diff --git a/.gsd/DECISIONS.md b/.gsd/DECISIONS.md new file mode 100644 index 000000000..d256a0903 --- /dev/null +++ b/.gsd/DECISIONS.md @@ -0,0 +1,19 @@ +# Decisions Register + + + +| # | When | Scope | Decision | Choice | Rationale | Revisable? | +|---|------|-------|----------|--------|-----------|------------| +| D001 | M001-1ya5a3 | arch | Desktop shell framework | Electron + Vite | Chromium-based (required for Monaco, Shiki, potential future WebContainers), mature ecosystem, battle-tested for code editors (VS Code, Cursor). Electrobun considered but too young and needs CEF for Chromium. Tauri has system webview limitations. | Yes — if Electrobun matures | +| D002 | M001-1ya5a3 | arch | Web preview approach | Localhost iframe | gsd-2 already spawns local dev servers. iframe is simpler, zero overhead, real environment. WebContainers add complexity for a local app with full filesystem access. | Yes — if sandboxing needed | +| D003 | M001-1ya5a3 | library | Code editor | Monaco Editor (@monaco-editor/react) | Powers VS Code. Full language support, IntelliSense, diff views. Custom theming via defineTheme(). CodeMirror lighter but less out-of-box for a coding app. | No | +| D004 | M001-1ya5a3 | library | UI primitives | Radix + Tailwind (custom components) | Headless, accessible primitives with zero visual opinions. Total design control. shadcn/ui has recognizable aesthetic that conflicts with "no AI slop" requirement. | No | +| D005 | M001-1ya5a3 | convention | Icon set | Phosphor Icons | Minimal, geometric, consistent stroke weight. Used by Linear, Vercel. Anti-Lucide — explicitly chosen to avoid the generic AI app aesthetic. | No | +| D006 | M001-1ya5a3 | convention | Typography | Inter (UI) + JetBrains Mono (code) | Inter has great optical sizing and tabular figures. JetBrains Mono has ligatures and clear character distinction. Both high-quality and widely respected. | No | +| D007 | M001-1ya5a3 | convention | Color palette | Dark monochrome + warm amber/gold accent | Dark-first, terminal-inspired but refined. Single warm accent color. No purple. Monochrome grays for hierarchy. | Yes — accent color may evolve | +| D008 | M001-1ya5a3 | convention | Message layout | Continuous document flow, left-aligned | Not chat bubbles. Not turn-based blocks. A living document that grows — more like reading a premium terminal transcript than texting. | No | +| D009 | M001-1ya5a3 | library | Syntax highlighting (messages) | Shiki | TextMate grammar-based, accurate highlighting, theme customization. Used for code blocks in the markdown message stream. Monaco handles the editor separately. | No | +| D010 | M001-1ya5a3 | library | State management | Zustand | Lightweight, minimal boilerplate, works well with React. No Redux overhead for a desktop app. | Yes — if state complexity grows | +| D011 | M001-1ya5a3 | arch | Layout model | Three-column resizable | File tree (left), conversation (center), editor+preview (right). Draggable dividers. Center is primary focus. Panels collapsible. | No | diff --git a/.gsd/PROJECT.md b/.gsd/PROJECT.md new file mode 100644 index 000000000..50041af17 --- /dev/null +++ b/.gsd/PROJECT.md @@ -0,0 +1,39 @@ +# GSD Studio + +## What This Is + +A local desktop coding agent app — a premium GUI for gsd-2. Built with Electron + Vite + React, it replaces the terminal experience with a beautifully designed three-column interface where you can see the conversation stream, the code being written, the file tree, and a live preview of what's being built — all at once. + +The AI backend is gsd-2 communicating over its existing JSON-RPC protocol (stdin/stdout JSONL). The app spawns gsd-2 as a subprocess and renders its event stream as a continuous document flow with premium markdown rendering, bespoke tool cards with syntax highlighting and diffs, and wizard-style interactive prompts. + +## Core Value + + + +Tool cards that are art — beautiful, informative, syntax-highlighted cards for every tool call the agent makes. This is what you stare at 90% of the time while the agent works. If nothing else ships perfectly, the tool cards must be stunning. + +## Current State + +Greenfield project. No code exists yet. gsd-2 has a mature JSON-RPC protocol (`@gsd/pi-coding-agent` package) with TypeScript SDK, event streaming, and extension UI request/response handling. + +## Architecture / Key Patterns + +- **Desktop shell:** Electron + Vite + React (TypeScript) +- **UI primitives:** Radix (headless) + Tailwind CSS — custom component library, not shadcn +- **Design system:** Dark monochrome + warm amber accent, Inter + JetBrains Mono, Phosphor Icons +- **Code editor:** Monaco Editor with custom dark theme +- **Syntax highlighting (messages):** Shiki for code blocks in markdown +- **Diff rendering:** react-diff-viewer or custom diff component with Shiki highlighting +- **State management:** Zustand +- **AI backend:** gsd-2 spawned as subprocess via `RpcClient` from `@gsd/pi-coding-agent` +- **Preview pane:** Localhost iframe pointing at dev server the agent spawns +- **Electron IPC:** Main process manages gsd-2 subprocess, renderer communicates via contextBridge/preload + +## Capability Contract + +See `.gsd/REQUIREMENTS.md` for the explicit capability contract, requirement status, and coverage mapping. + +## Milestone Sequence + +- [ ] M001-1ya5a3: GSD Studio MVP — Full coding agent GUI with message stream, tool cards, editor, preview, and interactive prompts diff --git a/.gsd/REQUIREMENTS.md b/.gsd/REQUIREMENTS.md new file mode 100644 index 000000000..f912925ef --- /dev/null +++ b/.gsd/REQUIREMENTS.md @@ -0,0 +1,237 @@ +# Requirements + +This file is the explicit capability and coverage contract for the project. + +## Active + +### R001 — Desktop app shell with native window management +- Class: core-capability +- Status: active +- Description: Electron desktop app launches with native window, title bar, and proper macOS integration +- Why it matters: Foundation for everything else — no shell, no app +- Source: user +- Primary owning slice: M001-1ya5a3/S01 +- Supporting slices: none +- Validation: unmapped +- Notes: Electron + Vite + React. Must support HMR in dev. + +### R002 — gsd-2 RPC connection with full event streaming +- Class: core-capability +- Status: active +- Description: App spawns gsd-2 as a subprocess via JSON-RPC, streams all events (message_update, tool_execution_start/success/error, extension_ui_request), and handles the full bidirectional protocol +- Why it matters: This is the brain — without the RPC pipe, the app is an empty shell +- Source: user +- Primary owning slice: M001-1ya5a3/S02 +- Supporting slices: none +- Validation: unmapped +- Notes: Uses `RpcClient` from `@gsd/pi-coding-agent`. Must handle process lifecycle, crash recovery, and all event types. + +### R003 — Continuous document-flow message rendering with premium markdown +- Class: primary-user-loop +- Status: active +- Description: Agent text streams in real-time as a continuous left-aligned document flow — headings, code blocks with syntax highlighting (Shiki), tables, inline code, lists, blockquotes. Not chat bubbles. Premium typography with Inter, proper spacing, hierarchy, and weights. +- Why it matters: This is the primary reading experience. If the markdown rendering is mediocre, the whole app feels mediocre. +- Source: user +- Primary owning slice: M001-1ya5a3/S03 +- Supporting slices: none +- Validation: unmapped +- Notes: Must handle streaming deltas smoothly without jank. Tables must render properly. Code blocks need language-specific syntax highlighting. + +### R004 — Tool card system — bespoke cards per tool type +- Class: differentiator +- Status: active +- Description: Tool calls render as bespoke collapsed/expandable cards. Edit cards show syntax-highlighted inline diffs. Read cards show formatted code previews with line numbers. Bash cards show styled terminal output. Write cards show the created file with highlighting. Collapsed view shows just enough to be interesting — a code snippet, a diff summary, a command. Expanded view shows full detail. Each card type is a design piece with considered borders, spacing, hierarchy, and subtle expand animation. +- Why it matters: Tool cards are what you stare at 90% of the time. They are the product. They must be art. +- Source: user +- Primary owning slice: M001-1ya5a3/S04 +- Supporting slices: M001-1ya5a3/S03 +- Validation: unmapped +- Notes: Tool types to cover at minimum: Read, Write, Edit, Bash, lsp, search, browser tools. Each gets bespoke treatment. No generic "tool output" fallback that looks lazy. + +### R005 — Integrated Monaco code editor with custom dark theme +- Class: core-capability +- Status: active +- Description: Monaco Editor panel in the right column with JetBrains Mono font, custom dark theme matching the app's monochrome + amber aesthetic, minimap disabled, proper syntax highlighting for all major languages +- Why it matters: Users need to see and read the code the agent is writing +- Source: user +- Primary owning slice: M001-1ya5a3/S06 +- Supporting slices: none +- Validation: unmapped +- Notes: Theme must match the app aesthetic exactly — not stock VS Code dark. Use `monaco.editor.defineTheme()` with custom token colors. + +### R006 — File tree sidebar with project navigation +- Class: core-capability +- Status: active +- Description: Left sidebar shows the project's file tree with expandable directories, file type icons, and click-to-open behavior that loads files in the Monaco editor +- Why it matters: Spatial awareness of what the agent is building +- Source: user +- Primary owning slice: M001-1ya5a3/S06 +- Supporting slices: M001-1ya5a3/S02 +- Validation: unmapped +- Notes: Should auto-refresh when the agent creates/modifies files. File watching via Electron's Node.js fs.watch or chokidar. + +### R007 — Localhost iframe preview pane for live web app preview +- Class: core-capability +- Status: active +- Description: Right panel has a tab/toggle to switch between the Monaco editor and a localhost iframe preview. When the agent spins up a dev server, the preview pane loads it. +- Why it matters: See what the agent builds in real-time without leaving the app +- Source: user +- Primary owning slice: M001-1ya5a3/S07 +- Supporting slices: M001-1ya5a3/S02 +- Validation: unmapped +- Notes: Detect dev server URL from agent's tool output or Bash stdout. iframe should auto-reload on changes. + +### R008 — Dark monochrome + warm amber design system +- Class: quality-attribute +- Status: active +- Description: Comprehensive design system — dark backgrounds, light text, monochrome grays, warm amber/gold as the single accent color. Inter for UI text, JetBrains Mono for code. Phosphor Icons. Radix primitives + Tailwind for styling. No Lucide icons, no purple, no shadcn recognizable aesthetic. Custom component library that feels like Linear or Vercel. +- Why it matters: The "no AI slop" requirement. Every pixel must feel intentional, premium, and hand-crafted. +- Source: user +- Primary owning slice: M001-1ya5a3/S01 +- Supporting slices: all slices +- Validation: unmapped +- Notes: Design system is established in S01 and consumed by every subsequent slice. Tailwind config defines the full color palette, typography scale, and spacing system. + +### R009 — Beautiful interactive prompt UI — wizard-style extension UI +- Class: differentiator +- Status: active +- Description: Extension UI requests (select, confirm, input, editor) render as premium inline wizard components in the conversation flow. Single-select shows option cards with radio selection and a "None of the above" with free-form notes field. Multi-select shows checkboxes. Tab headers show question navigation. Recommended options are visually highlighted. The full ask_user_questions interaction surface — tab-to-add-notes, multi-page navigation, review screen — must be beautifully rendered. +- Why it matters: Interactive prompts are how the agent asks you questions during discussion, planning, and execution. If they feel like browser confirm() dialogs, the premium experience collapses. +- Source: user +- Primary owning slice: M001-1ya5a3/S05 +- Supporting slices: M001-1ya5a3/S02 +- Validation: unmapped +- Notes: Must handle all extension_ui_request methods: select (single + multi), confirm, input, editor. Also handle fire-and-forget: notify, setStatus, setWidget, setTitle. The secure_env_collect tool uses paged masked input — handle via the input method with masking. + +### R010 — Three-column resizable layout +- Class: core-capability +- Status: active +- Description: Three resizable columns — file tree (left), conversation stream (center), editor+preview (right). Draggable dividers. Center column is the primary focus. Panels can be collapsed. +- Why it matters: The spatial layout is the cockpit — seeing everything at once is the whole point +- Source: user +- Primary owning slice: M001-1ya5a3/S01 +- Supporting slices: none +- Validation: unmapped +- Notes: Use a panel library like react-resizable-panels or custom dividers. Remember panel sizes across sessions via localStorage. + +### R011 — No AI slop aesthetic +- Class: constraint +- Status: active +- Description: No Lucide icons, no purple accent, no generic component-kit look, no recognizable shadcn aesthetic, no default Monaco themes. Every visual element must feel intentionally designed, not assembled from a kit. +- Why it matters: This is a negative constraint that's sharper than any positive specification — it defines the taste bar +- Source: user +- Primary owning slice: M001-1ya5a3/S01 +- Supporting slices: all slices +- Validation: unmapped +- Notes: Enforce during every slice. UAT should include visual review. + +### R012 — Streaming performance — smooth high-frequency delta rendering +- Class: quality-attribute +- Status: active +- Description: The RPC protocol emits high-frequency message_update deltas. The renderer must accumulate and display them smoothly without jank, dropped frames, or visible flicker. Markdown parsing and syntax highlighting must not block the render loop. +- Why it matters: Stuttery streaming kills the premium feel instantly +- Source: inferred +- Primary owning slice: M001-1ya5a3/S03 +- Supporting slices: M001-1ya5a3/S04 +- Validation: unmapped +- Notes: Consider requestAnimationFrame batching, virtual scrolling for long conversations, and deferred/async Shiki highlighting. + +## Deferred + +### R013 — Multi-project/session management +- Class: continuity +- Status: deferred +- Description: Manage multiple projects, switch between sessions, session history +- Why it matters: Power user need once the core experience is solid +- Source: inferred +- Primary owning slice: none +- Supporting slices: none +- Validation: unmapped +- Notes: Deferred to a later milestone. M001 works with one project at a time. + +### R014 — Settings/preferences UI +- Class: admin/support +- Status: deferred +- Description: Settings panel for model selection, theme customization, keybindings, etc. +- Why it matters: Useful but not essential for the MVP experience +- Source: inferred +- Primary owning slice: none +- Supporting slices: none +- Validation: unmapped +- Notes: Deferred. Model and provider can be configured via gsd-2's existing mechanisms initially. + +### R015 — Onboarding flow for new users +- Class: launchability +- Status: deferred +- Description: First-run experience, project setup wizard, API key configuration +- Why it matters: Required for general audience but not for the current primary user +- Source: inferred +- Primary owning slice: none +- Supporting slices: none +- Validation: unmapped +- Notes: Building for Lex first. Onboarding comes when generalizing. + +### R016 — App packaging and distribution +- Class: operability +- Status: deferred +- Description: DMG/installer generation, code signing, auto-update mechanism +- Why it matters: Required for distribution but not for local development use +- Source: inferred +- Primary owning slice: none +- Supporting slices: none +- Validation: unmapped +- Notes: electron-builder handles this. Defer until the app is worth distributing. + +## Out of Scope + +### R017 — Cloud/remote agent execution +- Class: anti-feature +- Status: out-of-scope +- Description: Running gsd-2 on a remote server rather than locally +- Why it matters: Prevents scope creep — this is a local desktop app +- Source: user +- Primary owning slice: none +- Supporting slices: none +- Validation: n/a +- Notes: The agent runs locally as a subprocess. Period. + +### R018 — WebContainers in-browser runtime +- Class: anti-feature +- Status: out-of-scope +- Description: Running Node.js inside the browser via WebContainers instead of using local dev servers +- Why it matters: Adds complexity for zero benefit — the agent already has local filesystem access +- Source: user +- Primary owning slice: none +- Supporting slices: none +- Validation: n/a +- Notes: Preview pane uses localhost iframe instead. + +## Traceability + +| ID | Class | Status | Primary owner | Supporting | Proof | +|---|---|---|---|---|---| +| R001 | core-capability | active | M001-1ya5a3/S01 | none | unmapped | +| R002 | core-capability | active | M001-1ya5a3/S02 | none | unmapped | +| R003 | primary-user-loop | active | M001-1ya5a3/S03 | none | unmapped | +| R004 | differentiator | active | M001-1ya5a3/S04 | M001-1ya5a3/S03 | unmapped | +| R005 | core-capability | active | M001-1ya5a3/S06 | none | unmapped | +| R006 | core-capability | active | M001-1ya5a3/S06 | M001-1ya5a3/S02 | unmapped | +| R007 | core-capability | active | M001-1ya5a3/S07 | M001-1ya5a3/S02 | unmapped | +| R008 | quality-attribute | active | M001-1ya5a3/S01 | all | unmapped | +| R009 | differentiator | active | M001-1ya5a3/S05 | M001-1ya5a3/S02 | unmapped | +| R010 | core-capability | active | M001-1ya5a3/S01 | none | unmapped | +| R011 | constraint | active | M001-1ya5a3/S01 | all | unmapped | +| R012 | quality-attribute | active | M001-1ya5a3/S03 | M001-1ya5a3/S04 | unmapped | +| R013 | continuity | deferred | none | none | unmapped | +| R014 | admin/support | deferred | none | none | unmapped | +| R015 | launchability | deferred | none | none | unmapped | +| R016 | operability | deferred | none | none | unmapped | +| R017 | anti-feature | out-of-scope | none | none | n/a | +| R018 | anti-feature | out-of-scope | none | none | n/a | + +## Coverage Summary + +- Active requirements: 12 +- Mapped to slices: 12 +- Validated: 0 +- Unmapped active requirements: 0 diff --git a/.gsd/STATE.md b/.gsd/STATE.md new file mode 100644 index 000000000..50957b66d --- /dev/null +++ b/.gsd/STATE.md @@ -0,0 +1,17 @@ +# GSD State + +**Active Milestone:** M001-1ya5a3 — GSD Studio MVP +**Active Slice:** S01 — Electron Shell + Design System Foundation +**Active Task:** none (slice not yet planned) +**Phase:** Planning S01 + +## Recent Decisions +- D001-D011: Full architecture, library, and convention decisions captured during discussion +- Electron + Vite + React, Radix + Tailwind, Monaco, Shiki, Phosphor, Inter + JetBrains Mono +- Dark monochrome + warm amber accent, continuous document flow, three-column resizable layout + +## Blockers +- None + +## Next Action +Plan S01 — decompose into tasks, write S01-PLAN.md and task plans, then execute. diff --git a/.gsd/milestones/M001-1ya5a3/M001-1ya5a3-CONTEXT.md b/.gsd/milestones/M001-1ya5a3/M001-1ya5a3-CONTEXT.md new file mode 100644 index 000000000..1f6994a49 --- /dev/null +++ b/.gsd/milestones/M001-1ya5a3/M001-1ya5a3-CONTEXT.md @@ -0,0 +1,117 @@ +# M001-1ya5a3: GSD Studio MVP + +**Gathered:** 2026-03-18 +**Status:** Ready for planning + +## Project Description + +A premium local desktop coding agent GUI for gsd-2. Replaces the terminal experience with a beautifully designed Electron app featuring a continuous document-flow conversation stream, bespoke tool cards with syntax-highlighted diffs and code previews, wizard-style interactive prompts, a Monaco code editor, file tree navigation, and a live localhost preview pane. The design language is dark monochrome with warm amber accent, Inter + JetBrains Mono typography, Phosphor icons — inspired by Linear and Vercel's design sensibility. No AI slop. No generic component-kit aesthetic. Tool cards are art. + +## Why This Milestone + +gsd-2 is a powerful coding agent but lives in a terminal. This milestone delivers a visual, spatial interface where you see the conversation, the code, the files, and the preview all at once. It transforms the agent from text-scrolling-by into a cockpit. + +## User-Visible Outcome + +### When this milestone is complete, the user can: + +- Launch the desktop app, point it at a project directory, and start a conversation with gsd-2 through a premium GUI +- Watch tool calls stream as beautiful, bespoke cards — diffs for edits, syntax-highlighted code for reads, styled terminal output for bash commands +- Interact with agent prompts (select, confirm, input) through wizard-style inline components with tab-to-add-notes, option cards, and recommended option highlighting +- Browse the project file tree and open files in a custom-themed Monaco editor +- See a live preview of web apps the agent builds via a localhost iframe +- Experience the whole thing as a cohesive, premium, Linear/Vercel-quality design + +### Entry point / environment + +- Entry point: Electron app launch (dev: `npm run dev`, prod: app binary) +- Environment: local macOS desktop (primary), future: cross-platform +- Live dependencies involved: gsd-2 CLI (spawned as subprocess), local filesystem, local dev servers + +## Completion Class + +- Contract complete means: All UI components render correctly, RPC protocol handles all event types, tool cards display accurate data for each tool type +- Integration complete means: Full round-trip — user sends prompt, gsd-2 processes it, events stream back, tool cards render, files appear in tree, editor opens them, preview shows running app +- Operational complete means: App handles gsd-2 process crashes gracefully, reconnects, and maintains conversation state + +## Final Integrated Acceptance + +To call this milestone complete, we must prove: + +- Send a real prompt to gsd-2 via the GUI and watch the full execution — message streaming, tool cards, file changes — render beautifully in real-time +- Interact with an ask_user_questions prompt through the GUI's wizard-style UI, including adding notes and selecting from options +- Open a file the agent just created/modified in the Monaco editor and see it syntax-highlighted with the custom theme +- See a live web app preview in the iframe after the agent builds something with a dev server + +## Risks and Unknowns + +- **Monaco theming depth** — Custom dark theme needs to match the app aesthetic exactly. Monaco's theming API is powerful but the token color customization can be tedious. +- **Streaming performance** — High-frequency message_update deltas need smooth rendering. Markdown parsing + Shiki highlighting in the render loop could cause jank. +- **Tool card diversity** — Many tool types with different data shapes. Each needs bespoke rendering. The design surface is large. +- **Electron IPC architecture** — Main process manages gsd-2 subprocess, renderer needs the event stream. Need clean IPC bridge via preload/contextBridge. +- **Extension UI complexity** — The ask_user_questions interaction model is rich (tab headers, multi-select, notes, review screen). Recreating this in React with premium UX is substantial work. + +## Existing Codebase / Prior Art + +- `packages/pi-coding-agent/src/modes/rpc/rpc-client.ts` — TypeScript RPC client SDK. Use this to spawn and communicate with gsd-2. +- `packages/pi-coding-agent/src/modes/rpc/rpc-types.ts` — Full type definitions for all RPC commands, responses, and events. +- `packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts` — Server-side RPC mode implementation. Reference for understanding event shapes. +- `src/headless.ts` — Headless orchestrator. Reference for how to manage gsd-2 subprocess lifecycle. +- `src/headless-events.ts` — Event classification (terminal, blocked, milestone-ready). Reuse patterns. +- `src/resources/extensions/ask-user-questions.ts` — Ask user questions tool. Reference for the full interaction model: single/multi-select, "None of the above", notes field, recommended option highlighting. +- `src/resources/extensions/get-secrets-from-user.ts` — Secrets collection tool. Reference for paged masked input UI. +- `src/resources/extensions/shared/interview-ui.ts` — Interview round widget. Reference for the full multi-page wizard interaction: tab navigation, notes, review screen, exit confirmation. +- `~/.claude/skills/gsd-headless-rpc/` — Comprehensive RPC protocol documentation skill. + +> See `.gsd/DECISIONS.md` for all architectural and pattern decisions — it is an append-only register; read it during planning, append to it during execution. + +## Relevant Requirements + +- R001-R012 — All active requirements are owned by this milestone's slices +- R008 (design system) and R011 (no AI slop) apply to every slice +- R004 (tool cards) and R009 (interactive prompts) are the differentiators + +## Scope + +### In Scope + +- Electron + Vite + React desktop app shell +- gsd-2 JSON-RPC integration via TypeScript SDK +- Continuous document-flow message rendering with Shiki-highlighted code blocks +- Bespoke tool cards for Read, Write, Edit, Bash, lsp, search, and browser tools +- Wizard-style interactive prompt UI (select, confirm, input, editor) +- Monaco editor with custom dark theme +- File tree sidebar with auto-refresh +- Localhost iframe preview pane +- Dark monochrome + warm amber design system +- Zustand state management + +### Out of Scope / Non-Goals + +- Multi-project/session management (R013 — deferred) +- Settings/preferences UI (R014 — deferred) +- Onboarding flow (R015 — deferred) +- App packaging/distribution (R016 — deferred) +- Cloud/remote execution (R017 — out of scope) +- WebContainers (R018 — out of scope) +- Mobile or tablet support +- Collaborative/multi-user features + +## Technical Constraints + +- Must use Electron (Chromium-based) for the desktop shell — required for reliable rendering of Monaco, Shiki, and potential future WebContainers +- gsd-2 communication MUST use the existing JSON-RPC protocol — no custom protocols +- JSONL framing: LF-only splitting, NOT readline (breaks on Unicode separators) +- Extension UI requests MUST be responded to — agent blocks until response is sent +- Must work on macOS with Apple Silicon (primary dev environment) + +## Integration Points + +- **gsd-2 subprocess** — Spawned via `RpcClient`, communicates via stdin/stdout JSONL +- **Local filesystem** — File tree reads, file watching for auto-refresh +- **Local dev servers** — Preview iframe loads localhost URLs from agent-spawned servers + +## Open Questions + +- **Conversation persistence** — Should the GUI persist conversation history to disk, or rely on gsd-2's session files? Current thinking: lean on gsd-2's session management initially. +- **Multiple gsd-2 instances** — Deferred, but the IPC architecture should not preclude it. diff --git a/.gsd/milestones/M001-1ya5a3/M001-1ya5a3-ROADMAP.md b/.gsd/milestones/M001-1ya5a3/M001-1ya5a3-ROADMAP.md new file mode 100644 index 000000000..59c7fe90c --- /dev/null +++ b/.gsd/milestones/M001-1ya5a3/M001-1ya5a3-ROADMAP.md @@ -0,0 +1,171 @@ +# M001-1ya5a3: GSD Studio MVP + +**Vision:** A premium local desktop coding agent GUI for gsd-2 — dark monochrome + warm amber, Linear/Vercel design quality, continuous document-flow messages, bespoke tool cards that are art, wizard-style interactive prompts, Monaco editor, file tree, and localhost preview pane. + +## Success Criteria + +- User can launch the app, point it at a project, and converse with gsd-2 through a premium GUI +- Agent text streams in real-time with beautiful typography, syntax-highlighted code blocks, and proper markdown tables +- Tool calls render as bespoke collapsed/expandable cards with diffs, code previews, and terminal output +- Interactive prompts (ask_user_questions) render as inline wizard components with option cards, notes, and recommended highlighting +- File tree sidebar shows the project structure and opens files in the Monaco editor +- Localhost preview pane displays the running app the agent builds +- The entire experience feels like Linear or Vercel — not a hackathon prototype + +## Key Risks / Unknowns + +- **Streaming + highlighting performance** — High-frequency deltas + Shiki syntax highlighting in the render loop could cause jank +- **Tool card design surface** — Many tool types, each needs bespoke treatment. Large design effort. +- **Extension UI recreation** — The ask_user_questions interaction model is rich and needs faithful, beautiful recreation in React +- **Electron IPC bridge** — Clean separation between main process (gsd-2 management) and renderer (React app) + +## Proof Strategy + +- Streaming performance → retire in S03 by proving smooth delta rendering with Shiki highlighting on real agent output +- Tool card diversity → retire in S04 by proving bespoke cards for all major tool types on real agent sessions +- Extension UI complexity → retire in S05 by proving the full ask_user_questions interaction works through the GUI +- Electron IPC → retire in S02 by proving end-to-end event streaming from gsd-2 subprocess to React renderer + +## Verification Classes + +- Contract verification: Component renders match expected designs, RPC protocol handles all event types correctly +- Integration verification: Full round-trip — prompt → gsd-2 → events → UI rendering → file tree update → editor open +- Operational verification: gsd-2 process crash recovery, reconnection, conversation state preservation +- UAT / human verification: Visual design quality assessment — does it feel premium? Tool card review. Typography review. + +## Milestone Definition of Done + +This milestone is complete only when all are true: + +- All seven slice deliverables are complete and styled +- The design system is cohesive across all components — no visual inconsistencies +- Tool cards are beautiful in both collapsed and expanded states for all major tool types +- Interactive prompts work as premium wizard-style components with full interaction model +- File tree, editor, and preview pane are wired to real gsd-2 output +- A real end-to-end session works: prompt → agent executes → tool cards stream → files appear → editor shows them → preview loads the app +- Visual quality passes human UAT — it genuinely feels like Linear/Vercel, not a prototype + +## Requirement Coverage + +- Covers: R001, R002, R003, R004, R005, R006, R007, R008, R009, R010, R011, R012 +- Partially covers: none +- Leaves for later: R013, R014, R015, R016 +- Orphan risks: none + +## Slices + +- [ ] **S01: Electron Shell + Design System Foundation** `risk:high` `depends:[]` + > After this: App launches as a native desktop window with the three-column resizable layout, dark theme, amber accent, Inter + JetBrains Mono loaded, Phosphor icons rendering. Panels show placeholder content. + +- [ ] **S02: gsd-2 RPC Connection + Event Stream** `risk:high` `depends:[S01]` + > After this: App spawns gsd-2, connects via JSON-RPC. Raw events stream into the center panel as formatted output — proof the pipe works end-to-end. + +- [ ] **S03: Message Stream + Markdown Rendering** `risk:high` `depends:[S02]` + > After this: Agent text streams in real-time with beautiful typography — headings, code blocks with Shiki syntax highlighting, tables, inline code, lists. Continuous document flow. + +- [ ] **S04: Tool Cards — The Art** `risk:high` `depends:[S03]` + > After this: Tool calls render as bespoke collapsed/expandable cards. Edit cards show syntax-highlighted diffs. Read cards show formatted code previews. Bash cards show styled terminal output. Write cards show the created file. Each card is a design piece. + +- [ ] **S05: Interactive Prompt UI — Wizards** `risk:high` `depends:[S03]` + > After this: Extension UI requests (select, confirm, input, editor) render as premium inline wizard components. Full ask_user_questions interaction with option cards, tab-to-add-notes, recommended highlighting. + +- [ ] **S06: File Tree + Monaco Editor** `risk:medium` `depends:[S01,S02]` + > After this: Left sidebar shows the project file tree. Clicking a file opens it in a custom-themed Monaco editor. JetBrains Mono, dark theme matching the app. + +- [ ] **S07: Preview Pane + Final Integration** `risk:medium` `depends:[S06,S04,S05]` + > After this: Right panel has editor/preview tab toggle. Full end-to-end: send prompt, watch tool cards, see files in tree, open in editor, preview running app in iframe. Final polish pass. + +## Boundary Map + +### S01 → S02 +Produces: +- `electron/main.ts` — Electron main process with window creation and preload config +- `electron/preload.ts` — contextBridge API exposing IPC channels to renderer +- `src/App.tsx` — Root React component with three-column layout +- `src/components/layout/` — ResizablePanel, Sidebar, CenterPanel, RightPanel components +- `src/lib/theme/` — Tailwind config, CSS variables, design tokens (colors, typography scale, spacing) +- `src/components/ui/` — Core primitives: Button, Text, Icon wrapper for Phosphor + +Consumes: nothing (first slice) + +### S02 → S03 +Produces: +- `electron/gsd-service.ts` — gsd-2 subprocess manager in main process (spawn, restart, event forwarding) +- `src/lib/rpc/` — Renderer-side RPC bridge: event listener hooks, command sender, connection state +- `src/stores/session-store.ts` — Zustand store: connection status, raw events, message accumulator +- IPC channels: `gsd:event`, `gsd:send-command`, `gsd:spawn`, `gsd:status` + +Consumes from S01: +- Electron main/preload/contextBridge architecture +- Layout panels (center panel receives event stream) + +### S03 → S04 +Produces: +- `src/components/message-stream/` — MessageStream container, MessageBlock component +- `src/components/markdown/` — MarkdownRenderer with Shiki code blocks, tables, inline code +- `src/lib/streaming/` — Delta accumulator, RAF-batched render updates, markdown parse pipeline +- Shiki highlighter instance (shared, pre-loaded themes + languages) + +Consumes from S02: +- `session-store.ts` — message_update events, accumulated text +- RPC event stream + +### S04 → S05 +Produces: +- `src/components/tool-cards/` — ToolCard shell, collapsed/expanded states, expand animation +- `src/components/tool-cards/EditCard.tsx` — Diff viewer with syntax highlighting +- `src/components/tool-cards/ReadCard.tsx` — Code preview with line numbers +- `src/components/tool-cards/BashCard.tsx` — Terminal-styled output +- `src/components/tool-cards/WriteCard.tsx` — Created file preview +- `src/components/tool-cards/SearchCard.tsx` — Search results with match highlighting +- `src/components/tool-cards/GenericCard.tsx` — Fallback for uncovered tool types +- `src/lib/tool-parser.ts` — Tool event → card data transformer + +Consumes from S03: +- MessageStream (tool cards are rendered inline in the message flow) +- MarkdownRenderer (reused inside card content) +- Shiki highlighter instance + +### S05 → S07 +Produces: +- `src/components/prompts/` — SelectPrompt, ConfirmPrompt, InputPrompt, EditorPrompt +- `src/components/prompts/OptionCard.tsx` — Individual option with radio/checkbox, description, recommended badge +- `src/components/prompts/NotesField.tsx` — Tab-to-expand notes textarea +- `src/components/prompts/PromptWizard.tsx` — Multi-question wrapper with tab navigation +- `src/lib/extension-ui-handler.ts` — Routes extension_ui_request events to prompt components, sends responses back + +Consumes from S03: +- MessageStream (prompts are rendered inline in the conversation flow) +- Design system components + +Consumes from S02: +- RPC bridge (sends extension_ui_response back to gsd-2) + +### S06 → S07 +Produces: +- `src/components/file-tree/` — FileTree, FileTreeNode, directory expand/collapse +- `src/components/editor/` — MonacoEditor wrapper with custom theme, language detection +- `src/stores/file-store.ts` — Zustand store: file tree state, open files, active file +- `src/lib/file-watcher.ts` — Electron-side file watching, IPC to renderer for tree refresh + +Consumes from S01: +- Layout panels (left sidebar for tree, right panel for editor) + +Consumes from S02: +- IPC channels (file watching runs in main process) + +### S07 (final integration) +Produces: +- `src/components/preview/` — PreviewPane with iframe, URL bar, reload button +- `src/components/layout/RightPanel.tsx` — Updated with editor/preview tab toggle +- Final integration wiring: tool card file links → editor open, bash server detection → preview URL +- Polish pass: transitions, loading states, empty states, error states + +Consumes from S04: +- Tool cards (file links in cards trigger editor open) + +Consumes from S05: +- Interactive prompts (full wizard flow works end-to-end) + +Consumes from S06: +- File tree + Monaco editor (clicking files, opening modified files)