name: foundary description: "Foundary Studio: Bootstrap a React+API+DB project, design via architect conversation, build with natural language prompts, and verify the live site." version: 2 vars: project_name: "" steps: # ============================================================ # SECTION 1: INFRASTRUCTURE # Create project with React app, API service, and database # ============================================================ create-project: description: "Create project with bootstrap build" action: api method: POST endpoint: /project/create-and-build body: name: "{{ .vars.project_name }}" description: "Foundary Studio: Task management with Kanban board" template: "skeleton" prompt: "Set up the monorepo workspace. Ensure the root README describes a task management studio with Kanban board, REST API, and CockroachDB persistence." auto_commit: true auto_push: true outputs: - project_id: .data.project_id - domain: .data.domain - git_clone_http: .data.git.clone_http - bootstrap_task_id: .data.task_id wait-bootstrap: description: "Wait for bootstrap build to complete" depends_on: [create-project] action: wait_build build_id: "{{ .outputs.create-project.bootstrap_task_id }}" max_attempts: 720 poll_interval: 5 setup-hooks: description: "Configure git hooks in project workspace" depends_on: [wait-bootstrap] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: "Run ./scripts/setup-hooks.sh to configure git hooks. Then verify with: git config core.hooksPath" auto_commit: false auto_push: false git_clone_url: "{{ .outputs.create-project.git_clone_http }}" outputs: - build_id: .data.task_id wait-setup-hooks: description: "Wait for git hooks setup to complete" depends_on: [setup-hooks] action: wait_build build_id: "{{ .outputs.setup-hooks.build_id }}" max_attempts: 120 poll_interval: 5 add-components: description: "Add React frontend, API service, and CockroachDB database" depends_on: [wait-setup-hooks] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/components/batch" body: components: - type: app-react name: studio-ui - type: service name: studio-api - type: postgres name: studio-db wait-components: description: "Wait for component scaffolding pipeline" depends_on: [add-components] action: wait_pipeline project_id: "{{ .outputs.create-project.project_id }}" max_attempts: 720 on_error: continue verify-site: description: "Verify site is live (may 503 until first build pushes component images)" depends_on: [wait-components] action: wait_site domain: "{{ .outputs.create-project.domain }}" max_attempts: 120 on_error: continue # ============================================================ # SECTION 2: DESIGN & BUILD # Architect conversation flow, then 3 iterative builds with # natural language prompts (no slash commands). # ============================================================ architect-start: description: "Start architect conversation about product goals" depends_on: [verify-site] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/architect/start" body: prompt: "I want to build a task management studio. The product needs: 1) Core data models for Task, Project, Label, and Assignment entities with full CRUD stored in CockroachDB via studio-db, exposed as REST endpoints on studio-api. 2) A React frontend in studio-ui with a Kanban board (drag-and-drop columns: To Do, In Progress, Done), task creation/edit modals, and filtering by label and assignee. Propose the architecture and identify the two MVP features we should build." outputs: - conversation_id: .data.id architect-refine: description: "Refine architecture with component details" depends_on: [architect-start] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/architect/continue/{{ .outputs.architect-start.conversation_id }}" body: message: "Good. Let's define exactly two features for the MVP: Feature 1 covers the persistence layer (Task, Project, Label, Assignment entities, migrations, repository layer, service layer, handler tests). Feature 2 covers the React frontend (Kanban board, task CRUD modals, label/assignee filters). Feature 2 depends on Feature 1 being complete since it consumes the API. Please confirm this breakdown and note any architectural considerations." architect-generate-blueprint: description: "Generate structured blueprint from conversation" depends_on: [architect-refine] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/architect/generate-blueprint/{{ .outputs.architect-start.conversation_id }}" body: name: "foundary-studio-mvp" outputs: - blueprint_id: .data.blueprint.id # --- Build 1: Data models, migrations, repository, handlers on studio-api --- build-api: description: "Build studio-api: data models, migrations, repository, handlers" depends_on: [architect-generate-blueprint] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: | Build the studio-api service with these requirements: 1. Data models: Define Task, Project, Label, and Assignment entities. - Task: id, title, description, status (todo/in_progress/done), project_id, assignee_id, created_at, updated_at - Project: id, name, description, created_at - Label: id, name, color, project_id - Assignment: id, task_id, label_id (many-to-many join) 2. Database: Create SQL migrations for all tables with foreign keys and indexes. Use the studio-db CockroachDB connection (DATABASE_URL env var). 3. Repository layer: Implement CRUD operations for each entity using sqlx. 4. Service layer: Business logic for task lifecycle (create, update status, assign labels). 5. HTTP handlers: RESTful endpoints mounted at /api/: - GET/POST /api/projects, GET/PUT/DELETE /api/projects/:id - GET/POST /api/tasks, GET/PUT/DELETE /api/tasks/:id - GET/POST /api/labels, GET/PUT/DELETE /api/labels/:id - POST/DELETE /api/tasks/:id/labels/:label_id 6. Tests: Add handler tests for the task CRUD endpoints. Work in the components/studio-api/ directory. auto_commit: true auto_push: true git_clone_url: "{{ .outputs.create-project.git_clone_http }}" outputs: - build_id: .data.task_id wait-build-api: description: "Wait for API build to complete" depends_on: [build-api] action: wait_build build_id: "{{ .outputs.build-api.build_id }}" max_attempts: 720 poll_interval: 5 wait-deploy-api: description: "Wait for API deployment pipeline" depends_on: [wait-build-api] action: wait_pipeline project_id: "{{ .outputs.create-project.project_id }}" max_attempts: 720 # --- Build 2: React Kanban UI, API client, task CRUD modals on studio-ui --- build-ui: description: "Build studio-ui: Kanban board, API client, task modals" depends_on: [wait-deploy-api] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: | Build the studio-ui React frontend with these requirements: 1. API client: Create a typed fetch wrapper that calls the studio-api endpoints. Base URL should be configurable via VITE_API_URL env var, defaulting to /api. 2. Kanban board: Three columns (To Do, In Progress, Done). - Display tasks as cards with title, description preview, and labels. - Implement drag-and-drop between columns using @dnd-kit/core. - Moving a card between columns calls PUT /api/tasks/:id to update status. 3. Task modals: Create/Edit modal with fields for title, description, and label selection. - Create: POST /api/tasks - Edit: PUT /api/tasks/:id - Delete: confirmation dialog, then DELETE /api/tasks/:id 4. Project selector: Dropdown to switch between projects (GET /api/projects). 5. Label/assignee filters: Filter bar above the Kanban board. 6. Layout: Clean dashboard layout with header, project selector, filter bar, and board. Work in the components/studio-ui/ directory. Use Tailwind CSS for styling. auto_commit: true auto_push: true git_clone_url: "{{ .outputs.create-project.git_clone_http }}" outputs: - build_id: .data.task_id wait-build-ui: description: "Wait for UI build to complete" depends_on: [build-ui] action: wait_build build_id: "{{ .outputs.build-ui.build_id }}" max_attempts: 720 poll_interval: 5 wait-deploy-ui: description: "Wait for UI deployment pipeline" depends_on: [wait-build-ui] action: wait_pipeline project_id: "{{ .outputs.create-project.project_id }}" max_attempts: 720 # --- Build 3: Polish — CORS, error handling, health check, README --- build-polish: description: "Polish: CORS, error handling, health check, README" depends_on: [wait-deploy-ui] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: | Polish the Foundary Studio application: 1. CORS: Ensure studio-api allows requests from the studio-ui origin. Add CORS middleware that allows GET, POST, PUT, DELETE, OPTIONS with credentials. 2. Error handling: Add proper error responses (400, 404, 500) with JSON error bodies from studio-api handlers. Add error toast notifications in studio-ui. 3. Health check: Add GET /api/health endpoint on studio-api that checks database connectivity and returns {"status": "ok", "service": "studio-api"}. 4. README: Update the root README.md with: - Project description (task management studio) - Architecture overview (monorepo with studio-ui, studio-api, studio-db) - API endpoint reference - Local development instructions auto_commit: true auto_push: true git_clone_url: "{{ .outputs.create-project.git_clone_http }}" outputs: - build_id: .data.task_id wait-build-polish: description: "Wait for polish build to complete" depends_on: [build-polish] action: wait_build build_id: "{{ .outputs.build-polish.build_id }}" max_attempts: 720 poll_interval: 5 wait-deploy-polish: description: "Wait for polish deployment pipeline" depends_on: [wait-build-polish] action: wait_pipeline project_id: "{{ .outputs.create-project.project_id }}" max_attempts: 720 # --- Commit QA artifacts and validate pre-merge hooks --- commit-after-qa: description: "Commit any remaining changes after QA" depends_on: [wait-deploy-polish] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: '/commit-all "chore: commit QA artifacts and fixes"' auto_commit: false auto_push: false git_clone_url: "{{ .outputs.create-project.git_clone_http }}" outputs: - build_id: .data.task_id wait-commit-after-qa: description: "Wait for QA commit to complete" depends_on: [commit-after-qa] action: wait_build build_id: "{{ .outputs.commit-after-qa.build_id }}" max_attempts: 120 poll_interval: 5 pre-merge-validate: description: "Run pre-commit hooks and fix any failures" depends_on: [wait-commit-after-qa] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: | Run ./.githooks/pre-commit to check code quality. If it fails, run /fix-all to fix all issues, then re-run ./.githooks/pre-commit. Repeat until it passes. auto_commit: true auto_push: true git_clone_url: "{{ .outputs.create-project.git_clone_http }}" outputs: - build_id: .data.task_id wait-pre-merge-validate: description: "Wait for pre-merge validation to complete" depends_on: [pre-merge-validate] action: wait_build build_id: "{{ .outputs.pre-merge-validate.build_id }}" max_attempts: 720 poll_interval: 5 wait-deploy-final: description: "Wait for final deployment pipeline after validation fixes" depends_on: [wait-pre-merge-validate] action: wait_pipeline project_id: "{{ .outputs.create-project.project_id }}" max_attempts: 720 # ============================================================ # SECTION 3: VERIFY # Confirm site is live and API responds # ============================================================ verify-site-live: description: "Verify site is live after all builds" depends_on: [wait-deploy-final] action: wait_site domain: "{{ .outputs.create-project.domain }}" max_attempts: 120 verify-api-health: description: "Verify API health endpoint responds" depends_on: [verify-site-live] on_error: continue action: shell command: | DOMAIN="{{ .outputs.create-project.domain }}" # Check API health HEALTH=$(curl -sf "https://$DOMAIN/api/studio-api/health" 2>/dev/null || echo '{}') echo "API health response: $HEALTH" STATUS=$(echo "$HEALTH" | grep -o '"status":"ok"' || true) if [ -n "$STATUS" ]; then echo "API health check passed" exit 0 else echo "API health check failed (may not have health endpoint yet)" exit 1 fi verify-complete: description: "Print success summary" depends_on: [verify-api-health] action: shell command: | echo "" echo "============================================================" echo "SUCCESS: Foundary Studio build complete" echo "============================================================" echo "" echo "Domain: {{ .outputs.create-project.domain }}" echo "Project ID: {{ .outputs.create-project.project_id }}" echo "" echo "Architecture:" echo " studio-ui — React Kanban board frontend" echo " studio-api — REST API with Task/Project/Label CRUD" echo " studio-db — PostgreSQL persistence" echo "" echo "Builds completed:" echo " 1. API: data models, migrations, repository, handlers" echo " 2. UI: Kanban board, drag-and-drop, task modals" echo " 3. Polish: CORS, error handling, health check, README" echo "============================================================" exit 0 teardown: - action: api method: DELETE endpoint: "/project/{{ .outputs.create-project.project_id }}"