From f670fee6919be92210da4b1a5ed43fc2b6ea61ec Mon Sep 17 00:00:00 2001 From: mawkone Date: Mon, 8 Jun 2026 14:46:21 -0700 Subject: [PATCH] chore: deploy final layout and routing polish to live --- docs_archive/AGENT_EXECUTION_ARCHITECTURE.md | 510 --------- docs_archive/Google_Cloud_Product_OS.md | 299 ------ docs_archive/TURBOREPO_MIGRATION_PLAN.md | 209 ---- docs_archive/VIBN_PRD.md | 501 --------- docs_archive/prd-agent-prompt.pdf | Bin 90462 -> 0 bytes docs_archive/product-idea-a.md | 409 -------- docs_archive/remixed-9edec9e9.tsx | 991 ------------------ docs_archive/vibn-coolify-schema.sql | 496 --------- new-site/Beta Signup.html | 167 --- new-site/Onboarding.bundle.html | 45 - new-site/Onboarding.html | 28 - new-site/app.jsx | 227 ---- new-site/audience.jsx | 177 ---- new-site/beta.jsx | 809 -------------- new-site/closing.jsx | 150 --- new-site/crossed.jsx | 134 --- new-site/hero.jsx | 370 ------- new-site/index.html | 219 ---- new-site/journey.jsx | 333 ------ new-site/onboarding-app.jsx | 181 ---- new-site/onboarding-build.jsx | 445 -------- new-site/onboarding-consultant.jsx | 294 ------ new-site/onboarding-entrepreneur.jsx | 274 ----- new-site/onboarding-fork.jsx | 134 --- new-site/onboarding-owner.jsx | 262 ----- new-site/onboarding-primitives.jsx | 333 ------ new-site/primitives.jsx | 108 -- new-site/tweaks-panel.jsx | 568 ---------- new-site/vibn-signin.html | 189 ---- new-site/wall.jsx | 251 ----- talkcody | 1 - temp-spec-kit | 1 - .../_onboarding/onboarding-primitives.tsx | 2 +- vibn-frontend/_onboarding/page.tsx | 7 + .../app/[workspace]/projects/layout.tsx | 29 +- 35 files changed, 9 insertions(+), 9144 deletions(-) delete mode 100644 docs_archive/AGENT_EXECUTION_ARCHITECTURE.md delete mode 100644 docs_archive/Google_Cloud_Product_OS.md delete mode 100644 docs_archive/TURBOREPO_MIGRATION_PLAN.md delete mode 100644 docs_archive/VIBN_PRD.md delete mode 100644 docs_archive/prd-agent-prompt.pdf delete mode 100644 docs_archive/product-idea-a.md delete mode 100644 docs_archive/remixed-9edec9e9.tsx delete mode 100644 docs_archive/vibn-coolify-schema.sql delete mode 100644 new-site/Beta Signup.html delete mode 100644 new-site/Onboarding.bundle.html delete mode 100644 new-site/Onboarding.html delete mode 100644 new-site/app.jsx delete mode 100644 new-site/audience.jsx delete mode 100644 new-site/beta.jsx delete mode 100644 new-site/closing.jsx delete mode 100644 new-site/crossed.jsx delete mode 100644 new-site/hero.jsx delete mode 100644 new-site/index.html delete mode 100644 new-site/journey.jsx delete mode 100644 new-site/onboarding-app.jsx delete mode 100644 new-site/onboarding-build.jsx delete mode 100644 new-site/onboarding-consultant.jsx delete mode 100644 new-site/onboarding-entrepreneur.jsx delete mode 100644 new-site/onboarding-fork.jsx delete mode 100644 new-site/onboarding-owner.jsx delete mode 100644 new-site/onboarding-primitives.jsx delete mode 100644 new-site/primitives.jsx delete mode 100644 new-site/tweaks-panel.jsx delete mode 100644 new-site/vibn-signin.html delete mode 100644 new-site/wall.jsx delete mode 160000 talkcody delete mode 160000 temp-spec-kit diff --git a/docs_archive/AGENT_EXECUTION_ARCHITECTURE.md b/docs_archive/AGENT_EXECUTION_ARCHITECTURE.md deleted file mode 100644 index 7f1dfe5e..00000000 --- a/docs_archive/AGENT_EXECUTION_ARCHITECTURE.md +++ /dev/null @@ -1,510 +0,0 @@ -# VIBN Agent Execution Architecture - -## Goal - -Give every product builder a personal AI that thinks like a COO — one that understands their product, monitors what's happening, and can direct specialists to get work done on their behalf. The user talks to one AI. That AI figures out what needs to happen and delegates accordingly. - ---- - -## The Mental Model - -**The user has one AI.** It happens to have specialists behind it. - -The user does not manage or navigate to Code agents, Growth agents, or Analytics agents. They talk to their Assist AI — their personal product COO — and that COO routes work to the right specialist internally. The module tabs (Code, Growth, Analytics) show the *output and status* of delegated work, not separate AI interfaces the user has to navigate between. - -This is the difference between a founder who has a COO (talks to one person who directs the team) vs. a founder who manages every department directly (exhausting, requires expertise they don't have). - ---- - -## Core AI Architecture - -``` -┌─────────────────────────────────────────────────────────────────────┐ -│ USER (non-technical founder) │ -│ │ -│ "I want more signups" │ -│ "Why did revenue drop last week?" │ -│ "Add a referral program" │ -│ "What should I build next?" │ -└───────────────────────────┬─────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────────┐ -│ ASSIST — Personal AI / COO (Tier B: Claude Sonnet) │ -│ │ -│ The user's only AI interface. Reasons across the entire │ -│ business. Surfaces insights proactively. Delegates all work │ -│ to the right specialist. Never asks the user to choose which │ -│ module or agent to use — it figures that out. │ -│ │ -│ Full context available: │ -│ - PRD + product vision │ -│ - Everything that's been built (Gitea) │ -│ - All past agent sessions and their outcomes │ -│ - Live analytics and deployment status │ -│ - Persistent memory: decisions made, patterns, preferences │ -│ - Web search: competitors, market trends, growth tactics │ -│ │ -│ Proactive behaviors: │ -│ - Surfaces anomalies before being asked │ -│ - Tracks open questions and follows up │ -│ - Monitors deploy outcomes and flags regressions │ -│ - Briefs the founder on what happened while they were away │ -└──────────────┬───────────────┬───────────────┬──────────────────────┘ - │ │ │ - delegates │ delegates │ delegates │ - ▼ ▼ ▼ - ┌────────────────┐ ┌──────────────────┐ ┌────────────────────┐ - │ CODE ADVISOR │ │ GROWTH ADVISOR │ │ ANALYTICS ADVISOR │ - │ (Tier B) │ │ (Tier B) │ │ (Tier B) │ - │ │ │ │ │ │ - │ Technical │ │ Acquisition, │ │ Data queries, │ - │ scoping. │ │ activation, │ │ anomaly detection, │ - │ Reads codebase │ │ retention. │ │ correlates data │ - │ before writing │ │ Researches what │ │ with deploys and │ - │ a single line. │ │ works for this │ │ events. │ - │ │ │ product type. │ │ │ - │ NOT user- │ │ NOT user- │ │ NOT user- │ - │ facing. │ │ facing. │ │ facing. │ - └───────┬────────┘ └────────┬─────────┘ └──────────┬─────────┘ - │ │ │ - └───────────────────┴───────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────────┐ -│ ORCHESTRATOR (Tier A: Gemini Flash) │ -│ │ -│ Receives a structured plan from whichever Advisor handled the │ -│ work. Breaks it into discrete tasks. Assigns tiers based on │ -│ complexity. Runs tasks in parallel where possible. │ -└──────────┬───────────────┬───────────────┬──────────────────────────┘ - ↓ ↓ ↓ - ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ - │ TIER A │ │ TIER B │ │ TIER C │ - │Gemini Flash │ │Claude Sonnet│ │Claude Sonnet│ - │ │ │ │ │ (→ Opus) │ - │Simple edits │ │Feature work │ │Complex arch │ - │Copy, rename │ │New components│ │Hard debugs │ - │Config tweaks│ │API routes │ │Refactors │ - └─────────────┘ └─────────────┘ └─────────────┘ - ↓ ↓ ↓ -┌─────────────────────────────────────────────────────────────────────┐ -│ EXECUTION RUNTIME (vibn-agent-runner) │ -│ │ -│ - Persistent dev environment: Node, Python, npm, git │ -│ - Agent executes commands, writes files, runs builds │ -│ - Self-corrects on errors (re-prompts with error context) │ -│ - Auto-commits to Gitea on completion │ -│ - Triggers Coolify redeploy automatically │ -│ - Session persists even if browser is closed │ -└─────────────────────────────────────────────────────────────────────┘ -``` - -**The confirmation moment is critical UX.** Before any work is delegated, Assist always surfaces a plain-language summary card: -> *"Here's my plan: I'm going to add a referral program. That means building a referral code system, an invite email, and a dashboard for your users. This will take ~8 minutes. Want me to start?"* - -The user never sees task tiers, agent assignments, or technical scope. They see what's happening and confirm. - ---- - -## Assist — Personal AI / COO - -The user's primary and only AI interface. All other specialists work behind it. - -### What it does - -**Reactive** — answers anything the user asks: -- "What should I build next?" -- "Why did signups drop?" -- "How does our product compare to [competitor]?" -- "Add a referral program" -- "Fix the checkout bug" - -**Proactive** — surfaces things without being asked: -- Detects when a deploy caused an error spike -- Flags when a key metric moves significantly -- Follows up on decisions made in past conversations ("You said you wanted to revisit the onboarding flow this week") -- Delivers a brief when the founder returns after time away - -### Full example - -``` -User: "I want more signups but I don't know what's blocking it" - ↓ -Assist COO - - Pulls current signup funnel from analytics - - Reads landing page + onboarding flow from Gitea - - Checks recent deploys for regressions - - Searches web for conversion benchmarks for this product category - - Cross-references PRD: what was the original promise to users? - - Asks: "Are people finding you organically or are you mostly getting - referrals? That changes what I'd recommend." - - User: "Mostly referrals from friends" - - COO: "Then your acquisition isn't the problem — your activation is. - People aren't converting after they land. Your onboarding skips the - 'aha moment'. Here's what I'd do..." - - Presents plan: "1. Rewrite the onboarding welcome email. - 2. Add an empty-state prompt on the dashboard. - 3. Test a 30-day trial instead of 14. - Shall I start?" - ↓ -On confirm → delegates to Growth Advisor (items 1–2) + Code Advisor (item 3) - ↓ -Orchestrator breaks into tasks → Execution agents build and deploy - ↓ -Assist follows up: "Done. The onboarding email and dashboard prompt are live. -The trial length change needs your input on pricing — want to talk through it?" -``` - -### What Assist does NOT do itself -- Write or execute code → delegates to Code Advisor -- Design and run growth experiments → delegates to Growth Advisor -- Run raw data queries → delegates to Analytics Advisor - -The user never has to know this routing is happening. - -### Persistent Memory - -Assist maintains a memory of the product that grows over time: - -``` -"User prefers simple, fast solutions over architecturally correct ones" -"Decided against social login in Jan 2026 — too complex for current stage" -"Trial length has been discussed 3x — founder is nervous about revenue impact" -"Mobile conversion has been an open problem since Nov 2025" -``` - -This is what makes it feel like a COO rather than a chatbot. It remembers context across sessions so the user never has to repeat themselves. - ---- - -## Specialist Advisors (Delegated, Not User-Facing) - -These three Advisors are invoked by Assist, not by the user directly. Their module tabs (Code, Growth, Analytics) in the sidebar show **status and output** — not chat interfaces. - -### Code Advisor - -Handles anything that requires changes to the codebase. Scopes work technically before a single line is written. - -``` -[Invoked by Assist with]: "Add Stripe checkout to the admin app" - ↓ -Code Advisor - - Reads package.json — Stripe not yet installed - - Reads existing payment-related files (none found) - - Searches: current Stripe Next.js best practices - - Scopes: "3 tasks: install SDK, create checkout API route, - add checkout button to pricing page" - - Returns structured plan to Orchestrator - ↓ -Orchestrator: - Task 1 (Tier A): npm install stripe - Task 2 (Tier B): POST /api/checkout route - Task 3 (Tier B): CheckoutButton component on pricing page - ↓ -Execution → commit → redeploy - ↓ -Assist reports back to user: "Stripe checkout is live." -``` - -**Context it uses:** -- Full codebase via Gitea -- Past agent sessions and what they changed -- Build logs and Coolify deploy history -- Web search: API docs, package versions, error solutions - -### Growth Advisor - -Handles acquisition, activation, and retention work. Researches what's proven to work before proposing anything. - -``` -[Invoked by Assist with]: "Build a referral program" - ↓ -Growth Advisor - - Checks current user count + retention from analytics - - Reviews existing onboarding flow from codebase - - Searches: referral mechanics that work for this product type + stage - - Proposes: "Double-sided reward — referrer gets 1 month free, - referee gets 14-day trial. This pattern converts at ~18% for - B2B SaaS at your stage." - - Returns scoped plan - ↓ -Orchestrator → 4 tasks → Execution -``` - -**Context it uses:** -- User base metrics from Analytics -- Current user flow from Gitea -- Past growth experiments and outcomes -- Web search: growth playbooks, conversion benchmarks, competitor tactics - -### Analytics Advisor - -Handles all data interpretation. Correlates numbers with events to find the actual story behind a metric. - -``` -[Invoked by Assist with]: "Why did signups drop last week?" - ↓ -Analytics Advisor - - Queries signup data: 30-day trend, last week specifically - - Checks Gitea: any deploys last week? Yes — Tuesday at 2pm - - Checks error logs: mobile error rate went from 0.2% to 8.4% post-deploy - - Finds: specific commit that changed signup form validation - - Returns: "Tuesday's deploy broke mobile signup. Here's the commit." - ↓ -Assist reports to user + asks: "Want me to fix it?" -If yes → delegates to Code Advisor -``` - -**Context it uses:** -- Product event data (signups, activations, churns, feature usage) -- Deployment history (Gitea commits + Coolify deploy timestamps) -- Error logs and performance metrics -- Web search: category benchmarks for comparison - ---- - -## Shared Execution Infrastructure - -``` -┌───────────────────────────────────────────────────────────────────┐ -│ vibn-agent-runner (Node.js/TypeScript) │ -│ │ -│ - Receives task + tier assignment from Orchestrator │ -│ - Instantiates the correct LLM client (Tier A/B/C) │ -│ - Executes tools: write_file, execute_command, read_file, etc. │ -│ - Self-corrects on errors (re-prompts with error output) │ -│ - Writes step-by-step output to Postgres after every step │ -│ - Auto-commits to Gitea on completion │ -│ - Triggers Coolify redeploy automatically │ -│ - Session persists even if browser tab is closed │ -└──────────────────────┬────────────────────────────────────────────┘ - │ git push (auto on completion) - ▼ -┌───────────────────────────────────────────────────────────────────┐ -│ Gitea (git.vibnai.com) │ -│ - Source of truth for all committed code │ -│ - Webhook → triggers Coolify auto-deploy │ -└──────────────────────┬────────────────────────────────────────────┘ - │ auto-deploy - ▼ -┌───────────────────────────────────────────────────────────────────┐ -│ Coolify (coolify.vibnai.com) │ -│ - Builds, deploys, manages domains + SSL │ -└───────────────────────────────────────────────────────────────────┘ -``` - ---- - -## Model Tier Reference - -| Tier | Model | Used For | Cost Profile | -|------|-------|----------|--------------| -| A | Gemini 2.5 Flash | Orchestration, simple tasks, routing, summaries | Very low | -| B | Claude Sonnet 4.6 | Assist COO, specialist advisors, feature-level tasks | Medium | -| C | Claude Sonnet 4.6 (→ Opus) | Hard debugging, architecture changes, complex reasoning | High | - -All tiers overridable via env vars: `TIER_A_MODEL`, `TIER_B_MODEL`, `TIER_C_MODEL`. - ---- - -## Data Model - -### `agent_sessions` table (Postgres) — exists - -```sql -CREATE TABLE agent_sessions ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - project_id TEXT NOT NULL, - module TEXT NOT NULL DEFAULT 'code', - -- code | growth | analytics (delegated modules) - app_name TEXT NOT NULL, - app_path TEXT NOT NULL, - task TEXT NOT NULL, - plan JSONB, - status TEXT NOT NULL DEFAULT 'pending', - -- pending | running | done | approved | failed | stopped - output JSONB NOT NULL DEFAULT '[]', - changed_files JSONB NOT NULL DEFAULT '[]', - error TEXT, - started_at TIMESTAMPTZ, - completed_at TIMESTAMPTZ, - created_at TIMESTAMPTZ NOT NULL DEFAULT now(), - updated_at TIMESTAMPTZ NOT NULL DEFAULT now() -); -``` - -### `advisor_conversations` table (Postgres) — to be built - -Stores every conversation the COO has had with the user. Each row is one session (may span many turns). - -```sql -CREATE TABLE advisor_conversations ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - project_id TEXT NOT NULL, - - -- 'assist' for user-facing COO conversations. - -- 'code' | 'growth' | 'analytics' for internal specialist invocations. - module TEXT NOT NULL DEFAULT 'assist', - - messages JSONB NOT NULL DEFAULT '[]', - -- Full message history: [{role, content, timestamp}] - - context_snapshot JSONB, - -- State of PRD, codebase summary, analytics at conversation start. - -- Used for debugging ("what did it know when it said that?") - - outcome TEXT, - -- null | 'tasked' | 'declined' | 'deferred' | 'monitoring' - - -- If this conversation resulted in execution, link to the session(s) - session_ids UUID[] DEFAULT '{}', - - created_at TIMESTAMPTZ NOT NULL DEFAULT now(), - updated_at TIMESTAMPTZ NOT NULL DEFAULT now() -); -``` - -### `advisor_memory` table (Postgres) — to be built - -Long-term memory for the COO. Persists facts, decisions, and patterns across conversations. This is what makes the AI feel like a real assistant rather than a stateless chatbot. - -```sql -CREATE TABLE advisor_memory ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - project_id TEXT NOT NULL, - - -- Category of memory - category TEXT NOT NULL, - -- 'decision' — "Decided not to add social login — too complex for now" - -- 'preference' — "Founder prefers speed over architectural correctness" - -- 'open' — "Mobile conversion problem still unresolved" - -- 'context' — "Target user is non-technical indie founders" - -- 'experiment' — "Tried 30-day trial in Feb — didn't impact conversion" - - key TEXT NOT NULL, -- short label for retrieval - value TEXT NOT NULL, -- full memory content - confidence REAL DEFAULT 1.0, -- 0–1, decays if contradicted - - -- Where this memory came from - source_conversation_id UUID REFERENCES advisor_conversations(id), - - created_at TIMESTAMPTZ NOT NULL DEFAULT now(), - updated_at TIMESTAMPTZ NOT NULL DEFAULT now() -); -``` - ---- - -## Current End-to-End Status (March 2026) - -### What works today - -| Step | Status | -|------|--------| -| User types task → session created in Postgres | ✅ | -| Agent runner receives task, calls Claude Sonnet 4.6 via Vertex AI | ✅ | -| Agent executes commands and writes files in runner workspace | ✅ | -| Step output streamed to Postgres in real time | ✅ | -| Frontend polls and shows live output log | ✅ | -| Auto-commit + push to Gitea on completion | ✅ | -| Gitea webhook triggers Coolify auto-deploy | ✅ | -| Browse tab shows latest committed files | ✅ | -| Project tabs (Atlas/PRD/Build/Growth/Assist/Analytics) in sidebar | ✅ | - -### In Progress - -| Step | Status | -|------|--------| -| Assist COO + specialist advisor architecture | 🔶 Designing | - -### Not Yet Started - -| Step | Status | -|------|--------| -| `advisor_conversations` + `advisor_memory` DB tables | ⬜ | -| Assist COO (user-facing personal AI) | ⬜ | -| Code Advisor (delegated specialist) | ⬜ | -| Growth Advisor (delegated specialist) | ⬜ | -| Analytics Advisor (delegated specialist) | ⬜ | -| Orchestrator (task decomposition + tier routing) | ⬜ | -| Proactive monitoring (anomaly detection, briefings) | ⬜ | -| Parallel task execution | ⬜ | -| WebSocket streaming (replace polling) | ⬜ | -| Terminal tab (xterm.js → live container PTY) | ⬜ | - ---- - -## Build Phases - -### Phase 1 — Execution Foundation ✅ -- [x] `agent_sessions` DB table + REST API routes -- [x] Agent runner with Claude Sonnet (Tier B) -- [x] Three-tier LLM clients (Gemini Flash, Claude via Vertex) -- [x] Session output streamed to Postgres per step -- [x] Auto-commit + Coolify deploy on completion -- [x] Frontend: Browse / Agent / Terminal tabs -- [x] Adaptive polling, auto-select active session -- [x] Context-aware task input (locked while running) -- [x] Project tabs moved to sidebar (Atlas/PRD/Build/Growth/Assist/Analytics) - -### Phase 2 — Per-project Sandboxed Workspaces -- [ ] Per-project ephemeral container (cold tier — wakes on demand) -- [ ] Agent `execute_command` routes through the project workspace container -- [ ] Persistent volume per project for caches / installed deps -- [ ] In-browser file viewer reflects live agent workspace - -### Phase 3 — Assist COO + Specialist Advisors -- [ ] `advisor_conversations` + `advisor_memory` DB tables + API -- [ ] Assist COO: stateful multi-turn conversation with full project context -- [ ] Assist COO: persistent memory across conversations (advisor_memory) -- [ ] Assist COO: web search tool (competitor research, growth tactics, docs) -- [ ] Code Advisor: reads codebase, scopes tasks before execution -- [ ] Growth Advisor: researches what works, proposes specific experiments -- [ ] Analytics Advisor: queries data, correlates with deploys, finds stories -- [ ] Assist delegates to specialists internally — user sees one AI -- [ ] Confirmation card UX: plain-language plan before any execution begins - -### Phase 4 — Orchestrator -- [ ] Orchestrator: decomposes advisor plans into tiered tasks -- [ ] Parallel task execution (multiple agents simultaneously) -- [ ] Task dependency graph (task B waits for task A's output) -- [ ] Cross-module task routing (one confirm → Code + Growth tasks in parallel) - -### Phase 5 — Streaming & Persistence -- [ ] WebSocket replaces polling for live output -- [ ] Browser reconnect: full log replay from Postgres + live tail -- [ ] Background notifications (in-app + email) on completion/failure -- [ ] Terminal tab: xterm.js connected to project workspace PTY - -### Phase 6 — Proactive Intelligence -- [ ] Assist monitors for anomalies and surfaces them without being asked -- [ ] Morning briefing: digest of what happened since last session -- [ ] Memory improves over time: learns founder preferences and product patterns -- [ ] Orchestrator estimates task time + complexity before confirming -- [ ] Agents validate their own output (tests, type-checks, linting) - ---- - -## Key Design Decisions - -**Why one AI interface (the COO), not four module AIs?** -Non-technical founders don't want to manage a team of AI tools. They want to talk to one AI that knows their business and gets things done. Routing work to specialists is the COO's job, not the founder's. Hiding that complexity is the product. - -**Why is Assist Tier B (Claude Sonnet) and not the fastest model?** -Assist is the only AI the user ever talks to. They'll judge the entire product by how well it understands them, how good its advice is, and how natural the conversation feels. This warrants the strongest reasoning model available. The savings come from using cheaper tiers for execution, not from cutting corners on the user-facing intelligence. - -**Why does Assist have persistent memory (advisor_memory)?** -Without memory, every conversation starts from zero. The COO has to re-learn that the founder doesn't want to use social login, that mobile conversion is an ongoing problem, that the trial length decision was deliberate. Memory is what transforms a chatbot into an assistant that actually knows you. - -**Why are the specialist advisors not user-facing?** -Users shouldn't have to decide "is this a Code question or a Growth question?" That's the COO's job. The module tabs exist to show what's been delegated and what the status is — not as separate AI chat interfaces. The user's relationship is with Assist, not with the individual specialists. - -**Why is the Orchestrator Tier A (cheap)?** -Once a specialist Advisor has produced a clear, structured plan, decomposing it into tasks is mechanical. It doesn't require deep reasoning — it requires fast, reliable routing. Gemini Flash is ideal: low latency, high quota, very low cost. - -**Why auto-commit by default?** -The target user is a non-technical founder. Requiring approval on every task creates friction and undermines the "describe it, it ships" value proposition. Gitea + Coolify already provide a rollback path if something goes wrong. - -**Why store everything in Postgres?** -Browser sessions end. Postgres is the source of truth. Every conversation turn, every memory item, every execution step, every outcome is written immediately. The WebSocket stream (Phase 5) is a convenience layer on top of the database, not a replacement. diff --git a/docs_archive/Google_Cloud_Product_OS.md b/docs_archive/Google_Cloud_Product_OS.md deleted file mode 100644 index 1886bc4b..00000000 --- a/docs_archive/Google_Cloud_Product_OS.md +++ /dev/null @@ -1,299 +0,0 @@ -Google Cloud Product OS -Product-Centric IDE + SaaS Autopilot Platform (Requirements & Architecture) -Vision - -Build a Product-Centric IDE and Automation Platform dedicated exclusively to: - -Launching, growing, and operating SaaS products on Google Cloud - -This is NOT a general-purpose IDE. -This is a Product Operating System (Product OS) designed to unify: - -Code - -Marketing - -Analytics - -Growth - -Support - -Experiments - -Infrastructure - -AI-driven automation - -into one coherent platform. - -It delivers: - -A Cursor-like experience - -Without Cursor cost - -Powered by Gemini (Vertex AI) - -Optimized specifically for Google Cloud - -Focused exclusively on building & automating products - -Core Product Principles -1. Product-Centric, Not Code-Centric - -This platform optimizes for: - -Shipping, launching, growing, and optimizing products, not just writing code. - -2. Opinionated for Google Cloud - -This system is: - -Cloud Run-first - -Firestore / Cloud SQL-native - -BigQuery-native - -Cloud Build-native - -Gemini-native - -No AWS, no Azure, no multi-cloud abstraction. - -3. Automation First - -Everything is: - -Automatable - -Observable - -Auditable - -Optimizable - -4. AI as a Product Operator - -The AI is not just a coding assistant. -It is a: - -Product Operator AI -capable of coordinating marketing, growth, support, analytics, and code. - -IDE Structure: Product-Centric Layout - -Instead of a traditional IDE layout, the system must expose: - -Product OS -├── Code -├── Marketing -├── Analytics -├── Growth -├── Support -├── Experiments -└── Infrastructure - - -Each section is first-class and AI-assisted. - -Section Requirements -1. Code Section - -Purpose: - -Build and deploy product services - -Must support: - -Cloud Run services - -Cloud SQL / Firestore integration - -Secrets management - -Logs & traces - -Rollbacks - -Service templates - -Not required: - -Arbitrary framework support - -Every programming language - -Optimized languages: - -TypeScript / Node - -Python - -2. Marketing Section - -Purpose: - -Automate go-to-market and content execution - -Must support: - -Campaign generation - -Social scheduling (Missinglettr) - -Blog generation & updates - -Landing page updates - -Brand voice control - -Product update → campaign pipeline - -AI must: - -Convert product changes into launch content - -Adapt content to brand style - -3. Analytics Section - -Purpose: - -Understand product performance and causality - -Must support: - -Funnels - -Retention - -Activation - -Cohorts - -LTV - -Causal drivers - -Experiment results - -NOT a SQL editor. -This is a Product Intelligence Interface. - -AI must answer: - -"Why did conversion change?" -"What caused activation to drop?" -"What should we test next?" - -4. Growth Section - -Purpose: - -Optimize onboarding and conversion - -Must support: - -Funnel definitions - -Onboarding flows - -Growth experiments - -A/B tests - -Nudge systems - -Conversion optimization - -AI must: - -Detect drop-offs - -Recommend experiments - -Evaluate uplift - -5. Support Section - -Purpose: - -Integrate customer feedback and product health - -Must support: - -Ticket ingestion - -AI-assisted replies - -Knowledge base generation - -Product issue detection - -Issue → fix pipeline - -AI must: - -Generate replies - -Detect recurring issues - -Recommend fixes - -6. Experiments Section - -Purpose: - -Coordinate A/B tests and product experiments - -Must support: - -Experiment definitions - -Targeting - -Metrics tracking - -Statistical significance - -Rollout controls - -AI must: - -Suggest experiments - -Analyze results - -Recommend actions - -7. Infrastructure Section - -Purpose: - -Manage and monitor production systems - -Must support: - -Cloud Run deployments - -Firestore / Cloud SQL management - -Secrets - -Logs - -Traces - -Alerts - -Cost monitoring - -AI must: - -Detect anomalies - -Recommend optimizations - -Automate fixes diff --git a/docs_archive/TURBOREPO_MIGRATION_PLAN.md b/docs_archive/TURBOREPO_MIGRATION_PLAN.md deleted file mode 100644 index e3bb0037..00000000 --- a/docs_archive/TURBOREPO_MIGRATION_PLAN.md +++ /dev/null @@ -1,209 +0,0 @@ -# Turborepo Monorepo Per-Project Migration Plan - -## Why We Are Making This Change - -The core thesis of this platform is that **one AI controls everything in one project**. For that to work, the AI needs a complete mental model of the project — all apps, all shared code, all dependencies — in a single coherent context. - -The current architecture creates a single Gitea repo per project with no enforced internal structure. The AI has no reliable way to know where apps live, what shares code with what, or how to trigger a targeted build for one part of the project. - -By adopting **Turborepo monorepo per project**, every project repo gets a standardised structure containing all of its apps (`product`, `website`, `admin`, `storybook`) and shared packages (`ui`, `tokens`, `types`, `config`). The AI operates across the entire project simultaneously. Build orchestration, deployment, and shared code all become coherent automatically. - -**The structure every user project repo will have:** - -``` -{project-slug}/ ← one Gitea repo per project - apps/ - product/ ← core user-facing app (Next.js) - website/ ← marketing / landing site (Next.js) - admin/ ← internal admin tool (Next.js) - storybook/ ← component browser and design system - packages/ - ui/ ← shared React component library - tokens/ ← design tokens (colors, spacing, typography) - types/ ← shared TypeScript types - config/ ← shared eslint, tsconfig - turbo.json - package.json ← pnpm workspace root - .gitignore - README.md -``` - -Turborepo is MIT-licensed, runs anywhere, and costs nothing. No Vercel dependency. - ---- - -## Infrastructure Context - -Everything runs on a single GCP VM (`34.19.250.135`, Montreal) via Docker + Traefik: - -| Service | URL | Repo | -|---|---|---| -| Platform frontend | `vibnai.com` | `git.vibnai.com/mark/vibn-frontend` | -| Gitea | `git.vibnai.com` | — | -| Coolify | `coolify.vibnai.com` | — | -| PostgreSQL | internal | — | - -**All platform logic lives in `vibn-frontend`** (Next.js). There is no separate control plane service. The backend is Next.js API routes in `app/api/`. Storage is PostgreSQL via raw SQL queries (no ORM layer in use for project data). - -**Integrations that already exist and should not be replaced:** -- `lib/gitea.ts` — full Gitea API client (create repo, webhooks, signature verification) -- `lib/coolify.ts` — full Coolify API client (projects, databases, applications, deployments) -- `app/api/projects/create/route.ts` — project creation flow (creates Gitea repo) -- `app/api/webhooks/gitea/route.ts` — receives Gitea push/PR events -- `app/api/webhooks/coolify/route.ts` — receives Coolify deployment events -- `app/api/ai/chat/route.ts` — AI chat with Gemini -- `lib/auth/authOptions.ts` — NextAuth v4 with Prisma adapter - ---- - -## Scope of Changes - -### 1. Scaffold Templates - -**What:** A set of template files written into the user's Gitea repo when a project is created, giving every project the standard Turborepo monorepo structure. - -**Where:** `vibn-frontend/lib/scaffold/turborepo/` - -**Files to create:** -- `turbo.json` — pipeline: `build`, `dev`, `lint`, `type-check`, `test` -- `package.json` — pnpm workspace root pointing to `apps/*` and `packages/*` -- `.gitignore` -- `README.md` — project-specific (name injected at scaffold time) -- `apps/product/` — Next.js 15, references shared `ui`, `tokens`, `types` -- `apps/website/` — Next.js 15 -- `apps/admin/` — Next.js 15 -- `apps/storybook/` — Storybook 8 -- `packages/ui/` — Button, Card, Input, Badge components using CSS token vars -- `packages/tokens/` — design tokens as TS + CSS custom properties -- `packages/types/` — shared `User`, `ApiResponse`, `PaginatedResponse` types -- `packages/config/` — `tsconfig.base.json` and `eslint.config.js` - -**Status:** Templates were written and are ready. Need to be moved to `vibn-frontend/lib/scaffold/turborepo/`. - ---- - -### 2. Project Creation Route — Add Scaffold Push - -**What:** The existing `app/api/projects/create/route.ts` already creates a Gitea repo. It needs one additional step: push the Turborepo scaffold as the initial commit. - -**File to update:** `vibn-frontend/app/api/projects/create/route.ts` - -**Current flow:** -1. Create Gitea repo (`auto_init: true` — creates empty repo with README) -2. Register webhook -3. Save project record to PostgreSQL - -**New step to add after repo creation:** -- Read scaffold template files from `lib/scaffold/turborepo/` -- Replace `{{project-slug}}` and `{{project-name}}` placeholders -- Push each file to the Gitea repo via the contents API -- This replaces the default empty `auto_init` commit - -**Note:** Change `auto_init: true` to `auto_init: false` since we are pushing the scaffold ourselves. - ---- - -### 3. Project Data Model — Add App Tracking - -**What:** The `fs_projects` table stores project data as a JSONB `data` column. The `data` object needs two new fields to track the monorepo apps and their Coolify services. - -**Fields to add to the project `data` JSONB:** - -```typescript -apps: Array<{ - name: string; // "product" | "website" | "admin" | "storybook" - path: string; // "apps/product" - coolifyServiceUuid?: string; - domain?: string; -}> -turboVersion: string; // e.g. "2.3.3" -``` - -No schema migration needed — it's JSONB, just include these fields when inserting/updating. - ---- - -### 4. Coolify — Per-App Service Provisioning - -**What:** When a project is created, each app in the monorepo gets its own Coolify service with the correct Turbo build filter. This extends the existing `lib/coolify.ts`. - -**File to update:** `vibn-frontend/lib/coolify.ts` - -**Add function:** - -```typescript -createMonorepoAppService(opts: { - projectUuid: string; - appName: string; // e.g. "product" - gitRepo: string; // the project's Gitea clone URL - domain: string; // e.g. "product-taskmaster.vibnai.com" -}): Promise -``` - -Build command: `pnpm install && turbo run build --filter={appName}` - -**Wire into project creation:** After Gitea repo is created and scaffold is pushed, create one Coolify service per app and store the `coolifyServiceUuid` in the project's `apps` array. - ---- - -### 5. Deploy API Route - -**What:** A new API route that triggers a Coolify deployment for a specific app within a project. - -**File to create:** `vibn-frontend/app/api/projects/[projectId]/deploy/route.ts` - -``` -POST /api/projects/{projectId}/deploy -Body: { app_name: "product" | "website" | "admin" | "storybook" } -``` - -Flow: -1. Load project from PostgreSQL -2. Find the app's `coolifyServiceUuid` -3. Call `deployApplication(uuid)` from `lib/coolify.ts` -4. Return deployment UUID - ---- - -### 6. AI Chat — Project Context Injection - -**What:** The existing `app/api/ai/chat/route.ts` handles Gemini chat. It needs to inject monorepo structure context when a `projectId` is present in the request. - -**File to update:** `vibn-frontend/app/api/ai/chat/route.ts` - -**Add to chat request handling:** -- Accept optional `projectId` -- When present, load the project from PostgreSQL -- Inject into the system prompt: - - Project name, slug, repo URL - - List of apps and their domains - - Shared packages available - - Turbo version and build command pattern -- Add two new Gemini tools: - - `deploy_app` — triggers `POST /api/projects/{projectId}/deploy` - - `scaffold_app` — adds a new app folder to the monorepo via Gitea contents API - ---- - -## Implementation Order - -| Step | Task | File | Depends On | -|------|------|------|-----------| -| 1 | Move scaffold templates into `vibn-frontend/lib/scaffold/` | `lib/scaffold/turborepo/**` | — | -| 2 | Update project creation to push scaffold | `app/api/projects/create/route.ts` | Step 1 | -| 3 | Add app tracking fields to project data | `app/api/projects/create/route.ts` | Step 2 | -| 4 | Add `createMonorepoAppService` to Coolify lib | `lib/coolify.ts` | — | -| 5 | Wire Coolify per-app provisioning into project creation | `app/api/projects/create/route.ts` | Steps 3, 4 | -| 6 | Add deploy route | `app/api/projects/[projectId]/deploy/route.ts` | Step 4 | -| 7 | Inject monorepo context into AI chat | `app/api/ai/chat/route.ts` | Step 3 | - ---- - -## What Does Not Change - -- Gitea as source control — same, one repo per project (already the case) -- Coolify as deployment host — same, extended with per-app services -- NextAuth for auth — unchanged -- PostgreSQL + JSONB for project storage — unchanged -- `lib/gitea.ts` and `lib/coolify.ts` — extended, not replaced -- No Vercel dependency anywhere diff --git a/docs_archive/VIBN_PRD.md b/docs_archive/VIBN_PRD.md deleted file mode 100644 index 970f95f5..00000000 --- a/docs_archive/VIBN_PRD.md +++ /dev/null @@ -1,501 +0,0 @@ -# vibn — Product Requirements Document - -**Version:** 1.0 -**Date:** March 2026 -**Author:** Mark Henderson / Atlas AI -**Status:** Draft - ---- - -## 1. Executive Summary - -vibn is a template-first SaaS product builder for non-technical founders. It turns a product idea into a fully deployed, live web application — without writing code. Users describe their idea through a guided 6-phase wizard (Discover → Architect → Design → Market → Build), and vibn's AI agents scaffold, build, and deploy the product onto the user's own self-hosted infrastructure (Gitea + Coolify). vibn is positioned as "Shopify for building software": opinionated, template-driven, and designed to dramatically reduce failure rates compared to blank-page AI coding tools. The target customer is a non-technical or low-technical founder who has a validated idea and wants to get to a live product and first paying user in under 72 hours. - ---- - -## 2. Problem Statement - -**The problem:** Non-technical founders cannot build software products without hiring developers or becoming one themselves. Existing AI coding tools (Cursor, Replit, v0) assume technical literacy. General-purpose AI (ChatGPT) produces code snippets that can't be deployed. Developer agencies cost $50–200k and take 6–12 months. The gap between "I have a great idea" and "I have a live product" remains enormous. - -**Who experiences it:** Solo founders, domain experts (lawyers, trainers, consultants, operators) who want to productize a service, career changers, and micro-agencies wanting to scale client delivery without headcount. - -**What they do today instead:** -- Hire a freelance developer (slow, expensive, dependency risk) -- Use no-code tools like Bubble or Webflow (limited, technical ceiling, hard to customize) -- Try to learn to code (fails 90%+ of the time for non-native coders) -- Sit on the idea indefinitely - -**Why current alternatives fall short:** -- Bubble/Webflow: Hit a wall as soon as real backend logic is needed; proprietary and not portable -- AI coding tools: Require knowing what to ask, how to debug, how to deploy — the hard parts remain -- Agencies: Take too long, cost too much, and the founder loses control -- Hiring: Creates single-point-of-failure dependency - ---- - -## 3. Vision & Success Metrics - -**Vision:** vibn is the fastest path from idea to live product for anyone who can describe what they want. It removes every technical barrier between a non-technical founder and a running SaaS — planning, building, deploying, and marketing — while keeping the user in control and the infrastructure on their own servers. - -**Success metrics (v1, 6-month targets):** - -| Metric | Target | -|---|---| -| Time from signup to deployed app | < 72 hours (median) | -| % of builds that deploy successfully on first attempt | > 85% | -| Monthly active builders | 500 | -| Projects reaching "live" status | 200 | -| Net Revenue Retention (NRR) | > 100% | -| Gross margin | > 65% | -| Paying customers at 6 months | 150 | - -**Key milestones:** -- Month 1: Private beta with 10 hand-selected founders -- Month 2: 50 projects initiated, first 20 live -- Month 3: Public waitlist open, payment enabled -- Month 6: Self-serve onboarding, 150 paying customers - ---- - -## 4. Target Users & Personas - -### Persona A — The Non-Technical Founder ("The Builder") -- **Who:** A domain expert (ex: fitness coach, lawyer, ops manager) who has identified a software problem in their industry. No coding background. Has validated the idea informally with peers. -- **Primary goal:** Go from idea to a working product they can show to real users and start charging for. -- **Pain points:** Doesn't know where to start technically; has been burned by developers before; doesn't trust no-code tools for "real" products; overwhelmed by choices. -- **Happy path:** Describes idea in the Discover phase → reviews and approves architecture → picks a visual style → sets brand voice → hits "Build" → shares a live URL within 48 hours. -- **What they value:** Speed, control, clarity. They want to see something real, not a mock. - -### Persona B — The Micro-Agency Operator ("The Producer") -- **Who:** A freelancer or small agency (1–5 people) that builds web products for clients. Currently using developers or outsourcing. Wants to deliver faster and at higher margin. -- **Primary goal:** Build client products in days, not months. Manage multiple projects from one dashboard. Bill clients for AI compute costs with markup. -- **Pain points:** Hiring developers is expensive and slow. Coordinating freelancers is painful. Margins are thin. Can't take on more work without more headcount. -- **Happy path:** Creates a new client project → walks through wizard on behalf of client → client reviews and approves → vibn builds and deploys → operator bills client with AI cost markup shown. -- **What they value:** Speed, multi-project management, billing visibility, client-presentable output. - -### Permissions Matrix - -| Capability | Builder (own project) | Producer (client project) | -|---|---|---| -| Create project | ✓ | ✓ | -| Run wizard phases | ✓ | ✓ | -| Trigger build | ✓ | ✓ | -| View live app URL | ✓ | ✓ | -| View cost breakdown | Own costs only | Full client cost breakdown | -| Bill client | — | ✓ | -| Manage custom domain | ✓ | ✓ | -| Access Gitea repo | ✓ | ✓ | -| Request changes post-launch | ✓ | ✓ | - ---- - -## 5. User Flows & Journeys - -### Primary Flow — New Builder (Non-Technical Founder) - -1. Lands on vibn marketing site (`vibn.app`) -2. Clicks "Get started free" → enters email -3. Completes **Welcome phase**: sees 5-step overview of what vibn does, clicks "Let's build it" -4. **Discover phase**: guided 6-question chat conversation — idea, problem, users, value, revenue, features. Sees live PRD panel filling in as they answer. Continues when all 6 answered. -5. **Architect phase**: Reviews AI-generated architecture (frontend, backend, auth, payments, email, hosting). Each block shows the chosen option and why. Can edit any block. Confirms with "Plan looks good — next: Design". -6. **Design phase**: Picks visual feel from 6 presets (Clean, Bold, Warm, Fresh, Electric, Luxury). Sees live mock of their app updating in real time. -7. **Market phase**: Sets brand voice (sliders for tone, style, personality). Reviews and edits 3 AI-generated content topics. Previews their marketing website style. -8. **Build phase**: Reviews full summary (auth, payments, email, style, website, topics, pages). Clicks "Build my MVP". Watches 12-step live build progress. Receives live URL + Gitea repo link. -9. Redirected to **Dashboard** — sees project as "Live" with URL, stats, and action buttons. - -### Secondary Flow — Returning User (Dashboard → Change Request) - -1. Logs in → lands on Dashboard (projects screen) -2. Selects an existing project → clicks "Build" or "Grow" -3. Enters the relevant phase of the wizard in edit mode -4. Makes changes → re-triggers partial build -5. Returns to Dashboard, sees updated deployment - -### Secondary Flow — Agency Producer (Client Project) - -1. Logs in → clicks "+ New project" -2. Tags project as "Client" and enters client name -3. Walks through wizard as normal (can be done with client present or on their behalf) -4. After build: sees project card with "Client" tag, cost breakdown, and "Bill →" button -5. Clicks "Bill →" → generates itemized invoice (LLM costs + compute + markup) -6. Views unbilled total across all clients in Billing screen - -### Onboarding Flow - -1. Email signup → verify email -2. Welcome wizard (Welcome phase of builder) -3. First project created automatically — user is never left on an empty dashboard -4. If user exits mid-wizard, project is saved as draft and resumed on next login - -### Error / Recovery Flows - -- **Build fails mid-way:** User sees which step failed, error plain-English explanation, and "Retry" button. Failed build does not charge full credits. -- **Payment setup missing:** If user chose Stripe billing in Architect but hasn't connected Stripe, they're prompted before Build is triggered. -- **Custom domain fails DNS:** In-app guide walks through DNS setup; app is still live on vibn subdomain in the meantime. -- **User exits mid-wizard:** Progress is auto-saved per phase. Resumable from Dashboard. - ---- - -## 6. Feature Requirements - -### 6.1 Must Have (v1 Launch) - -**Builder Wizard — 6-Phase Flow** -- *Description:* The core product experience. A sequential, guided wizard that takes a user from idea to deployed product. -- *User story:* As a non-technical founder, I want to answer plain-English questions and have AI figure out the architecture, code, and deployment — so I never have to think about technical choices. -- *Acceptance criteria:* All 6 phases completable end-to-end. Progress saved between sessions. Each phase produces a visible artifact (PRD, architecture plan, design preview, etc.). - -**Discover Phase — Conversational PRD Builder** -- *Description:* 6-question guided chat. Each answer populates a live PRD panel. AI synthesizes answers into a structured product plan. -- *Acceptance criteria:* All 6 questions answered before proceeding. PRD panel shows structured output per question. "Plan looks good" CTA advances to next phase. - -**Architect Phase — Architecture Selection** -- *Description:* AI proposes 6 architecture blocks (Frontend, Backend, Auth, Payments, Email, Hosting). Each block is explainable in plain English and editable. -- *Acceptance criteria:* All 6 blocks shown with default selection and rationale. User can change any block via dropdown/modal. Hosting block is locked to self-hosted (Coolify + Gitea). Pages list shown. - -**Design Phase — Visual Feel Picker** -- *Description:* 6 visual presets. Selecting a preset updates a live app mock in real time. -- *Acceptance criteria:* 6 presets rendered correctly. Live mock updates within 300ms of selection. Continue CTA available once selection made. - -**Market Phase — Voice + Topics + Website** -- *Description:* Brand voice sliders (tone, style, personality). AI-generated content topics (add/edit/remove). Website style picker with live preview. -- *Acceptance criteria:* Voice sliders affect AI content generation downstream. Topics editable with add/remove. Website preview updates with style selection. - -**Build Phase — Review + Deploy** -- *Description:* Full summary of all decisions. "Build my MVP" button triggers 12-step build pipeline. Live progress shown. On completion: app URL + Gitea link. -- *Acceptance criteria:* All decisions shown accurately from prior phases. Build progress shows step-by-step status. On success: live URL displayed and functional. On failure: clear error + retry option. - -**Dashboard — Projects View** -- *Description:* Home screen after login. Shows all projects with status, basic stats, and actions. -- *Acceptance criteria:* Projects shown as cards with status (Live/Building), URL, and key stats (visitors, signups, MRR). "Continue building" for in-progress builds. "+ New project" creates a new wizard session. - -**Dashboard — Billing View (Agency)** -- *Description:* Client billing tab showing unbilled costs by client, LLM/compute/other breakdown, invoice generation. -- *Acceptance criteria:* Unbilled totals accurate. "Bill →" generates invoice. Cost log shows itemized charges. - -**Authentication** -- *Description:* Email-based signup/login for the vibn platform itself. -- *Acceptance criteria:* Email + password signup. Email verification required. Forgot password flow. Session persists across browser restarts. - -**Deployment Integration (Coolify + Gitea)** -- *Description:* Every built project is pushed to user's Gitea repo and deployed via Coolify automatically. -- *Acceptance criteria:* Gitea repo created on build start. Code committed on completion. Coolify deploy triggered automatically. App live on `[project].vibn.app` subdomain. - -**Floating AI Chat (Assist)** -- *Description:* Phase-aware chat assistant available throughout the builder wizard. Persists across phase navigation. -- *Acceptance criteria:* Chat available from Discover through Build phases. Phase-specific starter suggestions. Chat history persists across phase changes. Does not reset on navigation. - ---- - -### 6.2 Should Have (Fast Follow — Months 2–3) - -**Custom Domain Support** -- Users can connect their own domain to a deployed project. -- In-app DNS setup guide. SSL auto-provisioned via Coolify. - -**Post-Build Change Requests** -- Users can request changes to their live product in plain English. -- AI interprets, diffs the codebase, applies change, redeploys. - -**Marketing Autopilot** -- AI generates and schedules blog posts, email newsletters, and social content based on topics defined in Market phase. -- Initial manual approval required; can be set to auto-publish. - -**Credit Usage Display** -- Show real-time credit consumption during builds. -- Warn before triggering tasks estimated to cost > X credits. -- User-configurable spending cap per project. - -**Template Marketplace Access** -- Starter templates browsable before creating a project. -- Template selection sets pre-configured architecture defaults. - ---- - -### 6.3 Could Have (Future — Months 4–6) - -**Client-Facing Project Portal** -- Agency clients can log in to review progress, approve phases, and view their live app — without accessing the vibn dashboard directly. - -**Stripe Connect for Invoice Payment** -- Agency operators can receive payment from clients directly via vibn. - -**Analytics Dashboard (per project)** -- Built-in lightweight analytics (page views, signups, MRR) sourced from the deployed app's database. - -**Invite Team Members** -- Multiple vibn users can collaborate on a single project. - -**Mobile App (iOS/Android)** -- Native app for monitoring live projects and approving content scheduled by marketing autopilot. - -**Template Marketplace (Sell/Buy)** -- Third-party developers can submit templates; users can purchase premium templates. - ---- - -### 6.4 Explicitly Out of Scope (v1) - -| Feature | Reason excluded | -|---|---| -| Mobile app (iOS/Android) builder output | All v1 builds are web apps; native app generation is a later capability | -| Real-time multi-user collaboration on wizard | Single-user flow only in v1; collaboration is v2 | -| Self-hosting vibn itself (white-label) | Not offered in v1; Enterprise tier future consideration | -| AI voice/video generation | Out of scope; vibn generates text and code only | -| Direct Stripe Connect marketplace | Invoice workflow is manual export only in v1 | -| Custom AI model selection by users | Model routing is automatic; users do not choose models | -| Offline/desktop app | Web-only | -| HIPAA / SOC2 compliance | Out of scope for v1; required before any healthcare customers | - ---- - -## 7. Screen-by-Screen Specification - -### 7.1 Marketing Website (`vibn.app`) -- **Purpose:** Acquire non-technical founders. Convert to "Get started free" or "Log in". -- **Key elements:** Hero headline ("You have the idea. We handle everything else."), 5-step how-it-works, pull quotes from 3 founders, stats bar (280+ launched, 72h avg, 4.9 rating), empathy section, final CTA. -- **Actions:** Get started free → Welcome wizard. Log in → Dashboard. -- **Notes:** Lora serif + Inter sans, ink/parchment palette. No color accents. - -### 7.2 Welcome Phase -- **Purpose:** Orient the user, set expectations, build confidence. -- **Key elements:** 5-step overview of the vibn process. "Let's build it →" CTA. Tagline: "From idea to live product. No code needed." -- **Actions:** "Let's build it" → Discover phase. - -### 7.3 Builder Sidebar (phases 2–6) -- **Purpose:** Persistent navigation and progress tracking during the wizard. -- **Key elements:** vibn logo. Progress checklist (Product plan, Architecture, Product design, Marketing). Phase nav (Discover, Architect, Design, Market, Build MVP). User avatar + name + plan at bottom. -- **Notes:** Sidebar is hidden on Welcome and Website screens. Always visible during builder phases. - -### 7.4 Discover Phase -- **Purpose:** Capture the product idea as structured data. Output: PRD. -- **Key elements (left panel):** Phase header, progress bar across 6 questions, AI message bubble per question, user input field. -- **Key elements (right panel):** "Your Product Plan" — live-updating sections: Idea, Problem, Users, Value, Revenue, Features. Each fills in as answered. -- **Actions:** User types answers. AI asks follow-up. After 6 questions: "Plan looks good — next: Architect →" CTA. - -### 7.5 Architect Phase -- **Purpose:** Let user review and confirm the technical architecture in plain English. -- **Key elements (center):** Phase header. 6 architecture blocks as horizontal-scrollable cards (Frontend, Backend, Auth, Payments, Email, Hosting). Each card shows: icon, chosen option, plain-English explanation, "Change →" button. "Why?" expandable for each block. Infra note (Coolify + Gitea). -- **Key elements (right panel):** "Pages to Build" — grouped by Public, Auth, App, Payments. -- **Actions:** "Change →" opens selection modal with 2–4 alternatives per block. "Confirm — next: Design →" CTA. - -### 7.6 Design Phase -- **Purpose:** Choose a visual style for the product. -- **Key elements (left):** 6 feel cards (Clean, Bold, Warm, Fresh, Electric, Luxury) — each with label, reference product, and color/style preview. -- **Key elements (right):** Live app mock that updates to reflect selected feel. Shows a plausible dashboard UI in that style. -- **Actions:** Click a feel card → mock updates. "Next: Market →" CTA. - -### 7.7 Market Phase — Voice Tab -- **Purpose:** Set the brand voice for AI-generated content. -- **Key elements:** 3 slider pairs: Tone (Friendly ↔ Professional), Style (Conversational ↔ Precise), Personality (Warm ↔ Direct). "Voice preview" section shows how the brand would introduce itself. -- **Actions:** Sliders adjust in real time. Tab switches to Topics or Website. - -### 7.8 Market Phase — Topics Tab -- **Purpose:** Define the content topics AI will generate and publish. -- **Key elements:** 3 pre-generated topic cards (title, angle, channels). Each editable. "Add topic" button. Remove button per card. -- **Actions:** Edit, add, remove topics. "Next: Website →" tab. - -### 7.9 Market Phase — Website Tab -- **Purpose:** Choose the marketing website visual style. -- **Key elements:** 4 website style options (Editorial, Startup Energy, Ultra Minimal, Warm & Human). Live website preview panel updates on selection. -- **Actions:** Click style → preview updates. "Plan looks good — next: Build →" CTA. - -### 7.10 Build Phase — Review Screen -- **Purpose:** Final review before triggering the build. -- **Key elements:** Summary grid (Auth, Payments, Email, Product Style, Website Style, Campaign Topics). Pages list (by group). Infra deployment note. "▲ Build my MVP" button. Disclaimer: ~15 minutes, refinable after launch. -- **Actions:** "Build my MVP" → transitions to Build Progress screen. - -### 7.11 Build Phase — Progress Screen -- **Purpose:** Show real-time build progress. -- **Key elements:** 12-step checklist with: completed steps (green checkmark), active step (animated indicator), pending steps (grey). Step label + detail line. Progress header showing step count. -- **On completion:** "Your MVP is live" screen — app URL ("Open my app ↗"), Gitea link ("View in Gitea ↗"), "Your next 3 actions" card. - -### 7.12 Dashboard — Projects Screen -- **Purpose:** Manage all projects from one place. -- **Key elements:** "Your projects" header with count. Unbilled total button (if agency projects exist). "+ New project" button. Project cards (2-column grid): status thumbnail, project identity (name, URL, client if applicable), status pill (Live/Building), cost strip (client projects), stats (visitors, signups, MRR), action buttons (Build, Grow, ↗). New project CTA card (dashed border, "+" icon). -- **Activity feed:** Recent events across all projects (content published, new signups, build events). - -### 7.13 Dashboard — Billing Screen (Client Billing tab) -- **Purpose:** Manage invoicing for agency operators. -- **Key elements:** Summary stats (total unbilled, LLM costs, compute, other). Billing table (by client, by month). Each row: project, LLM, compute, other, total, status pill. "Invoice" button per unbilled row. "Generate invoice" button (global). - -### 7.14 Dashboard — Billing Screen (Cost Tracker tab) -- **Purpose:** Understand AI and infrastructure cost breakdown. -- **Key elements:** LLM usage breakdown (code gen, content, chat assist) with bar charts. Infrastructure breakdown (hosting, database, email, domain). Recent charges log (time, description, project, cost). - -### 7.15 Floating AI Chat (Assist) -- **Purpose:** On-demand AI help throughout the wizard. -- **Key elements:** Dark header with "Assist · [phase]" + live green dot. Message thread (user + assistant bubbles). Phase-specific starter suggestions (3 clickable). Input field + send button. -- **Behavior:** Persists open/closed state and message history across phase changes. Accessible via 💬 bubble button at bottom right. - ---- - -## 8. Business Model & Pricing - -### Revenue Model -**Subscription + Credits** (not unlimited AI) - -The subscription covers fixed platform value (infrastructure orchestration, templates, UX, dashboard, Gitea/Coolify integration, team ops). Credits cover variable AI compute costs (LLM calls across Tier A/B/C, build pipelines, content generation). - -### Pricing Tiers - -| Tier | Price | Templates | Projects | Credits included | Target | -|---|---|---|---|---|---| -| **Free** | $0/mo | Starter only | 1 active | 50 credits/mo | Evaluators | -| **Builder** | $49/mo | Starter + Builder | 3 active | 500 credits/mo | Solo founders | -| **Pro** | $149/mo | All templates | Unlimited | 2,000 credits/mo | Active builders + agencies | -| **Enterprise** | Custom | Custom + private | Unlimited | Custom | Teams, compliance needs | - -**Credit top-ups:** Available at $0.10/credit (10 credits = $1). Minimum top-up: $10. - -### AI Cost Structure (Internal) - -Three-tier model routing: -- **Tier A (40% of calls):** Gemini Flash-class — orchestration, summaries, routing, log parsing. ~$0.0001/1k tokens. -- **Tier B (45% of calls):** Mid-tier coding model (GLM-5 or Qwen Coder via Vertex) — code gen, feature building, refactors. ~$0.002/1k tokens. -- **Tier C (15% of calls):** Premium escalation (Claude Sonnet or Gemini Pro) — architecture decisions, high-risk changes, repeated failures. ~$0.015/1k tokens. - -**Credit pricing:** Each credit = approximately $0.10 of platform value (AI + margin). Exact credit cost per action surfaced to user before triggering high-cost tasks. - -### Cost Estimate Per Build (v1 template-based app) -| Item | Estimated cost | -|---|---| -| Discover/Architect/Design/Market phases (Tier A/B) | ~$0.80 | -| Full code generation (Tier B, ~8,000 LOC) | ~$2.40 | -| Deployment orchestration | ~$0.20 | -| **Total per build** | **~$3.40** | -| **Charged at markup** | **~40 credits ($4.00)** | - -At $49/mo (500 credits), a Builder subscriber can complete ~12 full builds per month within plan. - ---- - -## 9. Integrations & External Dependencies - -| Integration | Purpose | Notes | -|---|---|---| -| **Gitea (self-hosted)** | Code storage and version control for every built project | Required. All repos pushed here on build completion. | -| **Coolify (self-hosted)** | Build pipeline, deployment, container orchestration | Required. Auto-deploys on Gitea push. | -| **Google Vertex AI** | Tier A/B/C model calls | Primary AI provider. Gemini Flash (A), mid-tier MaaS (B), Claude/Gemini Pro (C). | -| **Stripe** | Subscription billing for vibn platform fees | Customers pay vibn via Stripe. Stripe not required in built apps unless user selects it in Architect. | -| **Resend / Postmark** | Transactional emails (signup, password reset, notifications) | For vibn platform emails. Built apps may use same if email selected in Architect. | -| **PostgreSQL** | Platform database (conversations, project state, tasks, billing) | Self-hosted in hot tier. | -| **Redis** | Job queue, pubsub for build pipeline events | Optional but recommended for build reliability. | - -**No external data import requirements in v1.** Built apps start fresh; no migration tooling in scope. - ---- - -## 10. Non-Functional Requirements - -### Performance -- Wizard phase transitions: < 200ms -- Live design mock updates: < 300ms after style selection -- Build pipeline: Median < 15 minutes for a template-based app -- Dashboard load: < 1 second (projects list) -- AI chat response: First token within 1 second - -### Platform -- **Primary:** Web (desktop browser) — Chrome, Safari, Firefox, Edge -- **Secondary:** Responsive mobile web for dashboard viewing (not wizard) -- **Not in scope v1:** Native iOS/Android apps - -### Accessibility -- WCAG 2.1 AA compliance for all interactive elements -- Keyboard navigable wizard phases -- Sufficient color contrast across all design tokens (ink on paper palette passes AA) - -### Compliance & Regulatory -- **GDPR:** Data processing agreements available for EU users. User data deletable on request. -- **PCI DSS:** vibn does not store card data; handled entirely by Stripe. -- **HIPAA:** Out of scope for v1. No healthcare data processed. -- **SOC 2:** Target for Enterprise tier; not required at launch. - -### Data Privacy & Security -- All user project code stored in user's own Gitea instance (user owns their data) -- vibn platform database stores: conversation history, project metadata, billing records -- AI conversations not used for model training (Vertex API terms) -- Secrets (API keys, Stripe keys) stored encrypted, never logged -- Build logs retained for 30 days, then purged - -### Scalability Assumptions (v1) -- Designed for 500 MAU at launch -- Build pipeline: 20 concurrent builds supported -- Horizontal scaling of worker pool via Coolify - ---- - -## 11. Risks & Mitigations - -| Risk | Likelihood | Impact | Mitigation | -|---|---|---|---| -| Build success rate < 85% due to AI code quality | Medium | High | Template-first architecture dramatically reduces open-ended generation. Fallback retry mechanism. Tiered escalation to better model on repeated failure. | -| LLM costs exceed credit pricing margins | Medium | High | 3-tier routing keeps 85% of calls on cheap models. Per-step token limits. Aggressive context summarization. Max retries cap (3). | -| Users don't understand "credits" model | High | Medium | In-app cost estimation before every build. Plain-English explanations. "This build will use ~40 credits." Spending caps user-configurable. | -| Coolify/Gitea self-hosted infra reliability | Low | High | Hot tier always-on. Healthcheck monitoring. Auto-restart policies. Graceful failure messaging in build UI. | -| Non-technical users abandon wizard mid-way | High | Medium | Progress auto-saved per phase. Resume from dashboard. Floating AI chat for unblocking. Encourage "good enough" answers — no wrong answers in Discover. | -| Scope creep in wizard phases | Medium | Medium | Each phase has a strict set of decisions. No free-form architecture input. Locked hosting block prevents deviation. | -| Competition from Replit, Bolt, v0 | High | Medium | Differentiator is self-hosted infra (user owns everything), template-first (higher success rate), and the end-to-end wizard (no coding literacy required). | -| Agency use case underperforms | Low | Low | Agency (Producer persona) is v1 secondary target. Builder persona is primary. Billing screen can be iterated post-launch. | - ---- - -## 12. Open Questions & Assumptions - -### Open Questions - -1. **Template library scope at launch:** How many starter templates exist at v1 launch? What are they? (Minimum: SaaS CRUD + landing page. What else?) -2. **Subdomain structure:** Are projects deployed to `[project-name].vibn.app` or `[user-slug]-[project].vibn.app`? (Collision risk if single namespace.) -3. **Build pipeline timing:** Is 15-minute median build time achievable for first template? What's the P95? -4. **Gitea/Coolify provisioning:** Is each user getting their own Gitea org? How are Coolify environments namespaced per user? -5. **Free tier limits:** Should free tier require a credit card? (Conversion vs. abuse risk tradeoff.) -6. **Change requests post-launch:** How are iterative changes billed? Per-change credit cost, or separate workflow? -7. **Marketing autopilot publishing:** In v1, does AI content require manual approval before publishing, or is auto-publish available? -8. **Wizard re-entry:** Can a user go back and redo an earlier phase after completing Build? Does this trigger a rebuild? - -### Assumptions Made - -- vibn's Gitea and Coolify infrastructure are already operational and stable before v1 user onboarding begins. -- Template-based builds (vs. blank-page builds) keep success rates above 85%. -- Non-technical founders are willing to pay $49–$149/month for a solution that reliably delivers a live product. -- The 6-phase wizard is completable in one sitting (~20–30 minutes) for a user with a clear idea. -- Vertex AI API access and model availability (Gemini Flash, mid-tier MaaS) is stable and within budget. -- Users do not need to understand or manage their Gitea/Coolify infrastructure directly — vibn abstracts it entirely. -- The primary acquisition channel for v1 is content marketing and founder communities (not paid ads). - ---- - -## 13. Appendix - -### Glossary - -| Term | Definition | -|---|---| -| **Build** | The automated process of AI generating code, committing to Gitea, and deploying via Coolify | -| **Wizard** | The 6-phase guided flow: Discover → Architect → Design → Market → Build | -| **Phase** | A single stage of the wizard, each producing a specific artifact | -| **Template** | A pre-built starter codebase that vibn AI builds upon instead of generating from scratch | -| **Credits** | vibn's unit of AI compute consumption; consumed during builds, content generation, and chat | -| **Hot tier** | Always-running shared infrastructure (API gateway, orchestrator, Postgres, Redis, Gitea, Coolify) | -| **Cold tier** | Per-user on-demand containers (agent workspace instances, hibernated when inactive) | -| **Tier A/B/C** | Three levels of AI model quality/cost, automatically routed by the orchestrator based on task complexity | -| **Producer** | A vibn user building products for clients (agency use case) | -| **Builder** | A vibn user building a product for themselves (founder use case) | -| **PRD** | Product Requirements Document — the structured output of the Discover phase | -| **Gitea** | Self-hosted open-source Git service; stores all project codebases | -| **Coolify** | Self-hosted deployment platform; builds and runs all deployed apps | - -### Reference Materials -- Product strategy document: `product-idea-a.md` -- Builder wizard UI prototype: `preview-assist-ui/src/App.jsx` -- Marketing website prototype: `preview-assist-ui/src/Website.jsx` -- Dashboard prototype: `preview-assist-ui/src/Dashboard.jsx` -- PRD agent system prompt: `prd-agent-prompt.pdf` - -### Competitor Reference -- **Bolt.new / Lovable:** AI coding from scratch; no deployment, no templates, requires iteration by user -- **Replit:** Strong coding environment; technical literacy required; no guided wizard -- **Webflow:** No-code UI builder; no real backend; visual but limited -- **Bubble:** No-code with backend; steep learning curve; proprietary lock-in -- **v0 (Vercel):** UI generation only; no deployment, no product planning -- **Agencies:** Custom development; 6–12 month timelines; $50k–$200k budgets diff --git a/docs_archive/prd-agent-prompt.pdf b/docs_archive/prd-agent-prompt.pdf deleted file mode 100644 index e77842b449cf387e8ec15aaff587688e14fa852a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90462 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

5ie@D3?xX1TxI2uoiV@%XXH47NRf>QbdGL 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 conversation replay -Instead of resending entire conversation history, persist and inject: - -project summary - -architecture summary - -repo map summary - -deploy state - -open tasks - -known bugs - -This is a major cost reducer. - -3) AI Model Strategy: 3-Tier Routing (Cost-Efficient Orchestration) - -You’re building your own agents, but the principle applies: choose models per tool/task. - -Tier A / Tier B / Tier C (the blend) - -We landed on this operational blend: - -40% Tier A (cheap) - -45% Tier B (mid / workhorse coder) - -15% Tier C (premium escalation) - -This is not arbitrary—it aligns with tool/task reality: - -most actions are parsing, routing, search, summarizing (cheap) - -most code edits and implementations are workhorse coding (mid) - -only a small fraction require deep reasoning / high-stakes decisions (premium) - -Tier purpose -Tier A — Cheap “Utility / Router” - -Use for: - -routing decisions - -summarizing logs, errors, context - -file discovery + search interpretation - -command suggestion drafts - -task context updates - -chat summaries / naming - -monitoring analysis - -This tier should handle the majority of orchestration. - -Tier B — Workhorse Coding Model - -Use for: - -generating diffs - -writing/refactoring code - -tests - -standard bug fixes - -“agent mode” loops when tasks are scoped - -iterating on features inside templates - -This tier should handle most coding. - -Tier C — Premium Escalation Model - -Use only when: - -architecture decisions - -high-risk changes (deploy, infra, migrations) - -cross-service debugging - -persistent failures (2 failed iterations) - -very large diffs / multi-file refactors - -security-sensitive changes - -This tier should be rare by design. - -4) Vertex Models: What to Use in Each Tier - -You wanted to stay on Google infra and Vertex marketplace/API models. - -Recommended mapping (Vertex-first) -Tier A (cheap) - -Gemini Flash-class model (fast, low cost) -Use for orchestration, summaries, extraction, routing, log parsing. - -Tier B (mid / coding workhorse) - -Pick one: - -GLM-5 MaaS (Vertex) — strong reasoning + cost-effective - -Qwen coder MaaS (Vertex) — strong coding, predictable cost - -This model does the heavy lifting for code edits and feature building. - -Tier C (premium escalation) - -Pick one: - -Claude Sonnet 4.6 on Vertex (reliability + long-chain coding) - -or Gemini 3.1 Pro Preview (if it proves better for your workflows) - -This is your “expert brain” used sparingly. - -5) Routing Policy: How the System Chooses Models - -You’re not letting users pick models manually. The orchestrator routes based on task complexity and risk. - -Default rules - -All “read/search/list/summarize” → Tier A - -Most code edits/refactors/tests → Tier B - -High-risk or repeated failure → Tier C - -Escalation triggers (simple + effective) - -Escalate Tier B → Tier C when any of these happen: - -2 failed iterations (tests still failing, same error persists) - -Touching >5 files - -Diff size exceeds ~400 LOC changed - -Deployment / infra / secrets / migration steps involved - -Context pressure (approaching model limits) - -De-escalation rule - -Once the hard part is resolved (cause found / plan decided), drop back to Tier B for implementation. - -6) Business Model: Subscription + Credits (Not “Unlimited AI”) - -You clarified the intended split: - -Subscription covers your fixed costs - -Subscription pays for: - -your hosted infrastructure (hot tier + shared services) - -Agent workspace orchestration (cold tier) - -your people costs (support, ops, ongoing development) - -product value (templates, UX, dashboards, workflows) - -baseline included usage / small AI overhead - -Credits cover variable compute - -Credits pay for: - -model calls (Tier A/B/C) - -heavy tasks (builds, refactors, debugging loops) - -long chain tasks - -autonomous agent execution - -This protects you from heavy users and keeps margins predictable. - -7) Template Access as a Tiered Product (Shopify-style) -Templates are the moat - -Templates reduce: - -architecture planning cost - -retry loops - -token burn - -complexity and failure rates - -Templates also create: - -differentiation - -a marketplace opportunity later - -compounding margins - -Tiering via template access - -Instead of just “more AI,” higher tiers unlock better starter systems. - -Example approach: - -Starter tier - -landing page template - -simple SaaS CRUD template - -basic auth + Stripe - -limited integrations - -Builder tier - -multi-tenant SaaS template - -marketplace template - -analytics dashboard template - -stronger RBAC patterns - -more integrations - -Pro tier - -“OpsOS / analytics warehouse” template - -monitoring + alerting template - -ML-ready pipeline template - -advanced data model scaffolds - -Enterprise - -custom templates - -compliance add-ons - -private deployments - -dedicated support / SLAs - -8) Credit Pricing: Fixed Markup per Model - -You said you want: - -credits based on user actions, with fixed markup on every model - -This implies: - -Each model has an internal “true cost” - -You charge credits at a consistent markup multiplier - -Premium models may have a higher markup (optional), but you can keep it fixed if you prefer simplicity - -How it should feel to the user - -“This action will cost ~X credits” - -“Set a spending cap per day/project” - -“Require approval if a task is estimated > Y credits” - -This prevents runaway spending and builds trust. - -9) Key Risk Controls We Agreed Are Necessary - -To make this sellable and safe: - -Token and autonomy guardrails - -max tokens per step - -max retries per task - -auto-summarize context aggressively - -store structured memory, not chat replay - -only send diffs / minimal file slices - -caching where possible (especially for repeated prefixes) - -UX controls - -show credit burn in real time - -warn/approve for high-cost tasks - -allow user-set budgets - -explain why escalation happened (briefly) - -10) The End State - -VibnAI becomes: - -A template-first “product builder OS” - -powered by multi-model orchestration - -hosted on your infra - -with predictable economics via subscription + credits - -and a defensible moat via templates + routing intelligence \ No newline at end of file diff --git a/docs_archive/remixed-9edec9e9.tsx b/docs_archive/remixed-9edec9e9.tsx deleted file mode 100644 index 6428a5e9..00000000 --- a/docs_archive/remixed-9edec9e9.tsx +++ /dev/null @@ -1,991 +0,0 @@ -import { useState, useEffect, useRef } from "react"; - -const FontLoader = () => ( - -); - -/* ─── DATA ─── */ -const projects = [ - { id: 1, name: "Meridian", desc: "Client portal for boutique agencies", status: "building", progress: 68, features: 12, phase: "Frontend Gen", lastActive: "2h ago", color: "#3d5afe", domain: "meridian-app.stackless.dev", repo: "stackless/meridian-build", created: "Jan 12, 2026" }, - { id: 2, name: "Tidepool", desc: "Marine research data platform", status: "prd", progress: 45, features: 7, phase: "Features", lastActive: "20m ago", color: "#00897b", domain: null, repo: null, created: "Feb 3, 2026" }, - { id: 3, name: "Canopy", desc: "Internal team knowledge base", status: "live", progress: 100, features: 18, phase: "Deployed", lastActive: "1d ago", color: "#2e7d32", domain: "canopy.stackless.dev", customDomain: "kb.acmecorp.com", repo: "stackless/canopy-build", created: "Nov 28, 2025" }, - { id: 4, name: "Foxglove", desc: "Prescription mgmt for pharmacies", status: "prd", progress: 20, features: 3, phase: "Discovery", lastActive: "now", color: "#e65100", domain: null, repo: null, created: "Feb 27, 2026" }, -]; - -const activityFeed = [ - { time: "2 min ago", project: "Foxglove", action: "Atlas completed Users & Personas phase", type: "atlas" }, - { time: "18 min ago", project: "Foxglove", action: "You described the core prescription workflow", type: "user" }, - { time: "1h ago", project: "Meridian", action: "Build: Dashboard UI component generated", type: "build" }, - { time: "2h ago", project: "Meridian", action: "Build: Authentication system passed all tests", type: "build" }, - { time: "3h ago", project: "Tidepool", action: "Atlas captured 7 features in MoSCoW framework", type: "atlas" }, - { time: "5h ago", project: "Tidepool", action: "You approved Problem Statement section", type: "user" }, - { time: "8h ago", project: "Meridian", action: "Build: Database schema deployed", type: "build" }, - { time: "1d ago", project: "Canopy", action: "Custom domain kb.acmecorp.com verified and active", type: "deploy" }, - { time: "1d ago", project: "Canopy", action: "v1.2 deployed — added search filters", type: "deploy" }, - { time: "2d ago", project: "Meridian", action: "PRD approved — build pipeline started", type: "deploy" }, - { time: "2d ago", project: "Tidepool", action: "Project created", type: "user" }, - { time: "3d ago", project: "Foxglove", action: "Project created", type: "user" }, -]; - -const chatHistory = [ - { from: "atlas", text: "I see you're building Foxglove — prescription management for small pharmacies. We've locked in the problem statement and identified your primary user.\n\nNow let's map the core workflow. When a pharmacist opens Foxglove first thing in the morning, what do they need to see?" }, - { from: "user", text: "They need to see incoming prescriptions from doctors. The current systems are super clunky. They want to see new scripts, verify them, and mark them as filled." }, - { from: "atlas", text: "Clean workflow. Three stages:\n\n1. Receive — new scripts appear in a queue\n2. Verify — check dosage, interactions, patient history\n3. Fill — mark dispensed, update stock\n\nTwo things I want to nail down: does the pharmacist need to message the prescribing doctor back through Foxglove if there's a dosage flag? And are we building for single-location pharmacies or chains with 2–3 stores?" }, -]; - -const prdData = [ - { name: "Executive Summary", status: "done", pct: 100 }, - { name: "Problem Statement", status: "done", pct: 100 }, - { name: "Users & Personas", status: "done", pct: 100 }, - { name: "User Flows", status: "active", pct: 60 }, - { name: "Feature Requirements", status: "pending", pct: 20 }, - { name: "Screen Specs", status: "pending", pct: 0 }, - { name: "Business Model", status: "pending", pct: 0 }, - { name: "Non-Functional Reqs", status: "pending", pct: 0 }, - { name: "Risks", status: "pending", pct: 0 }, -]; - -const discoveryPhases = [ - { name: "Big Picture", done: true }, - { name: "Users", done: true }, - { name: "Features", active: true }, - { name: "Business Model" }, - { name: "Screens" }, - { name: "Risks" }, -]; - -/* ─── Micro Components ─── */ -const Tag = ({ children, color = "#1a1a1a", bg = "#1a1a1a10" }) => ( - {children} -); - -const StatusDot = ({ status }) => { - const c = status === "live" ? "#2e7d32" : status === "building" ? "#3d5afe" : "#d4a04a"; - return ; -}; - -const SectionLabel = ({ children }) => ( -

{children}
-); - -const Card = ({ children, style: s = {}, hover = true, ...rest }) => { - const [hovered, setHovered] = useState(false); - return ( -
setHovered(true)} onMouseLeave={() => setHovered(false)} - style={{ background: "#fff", border: `1px solid ${hovered && hover ? "#d0ccc4" : "#e8e4dc"}`, borderRadius: 10, boxShadow: hovered && hover ? "0 2px 8px #1a1a1a0a" : "0 1px 2px #1a1a1a05", transition: "all 0.15s", ...s }} - {...rest} - >{children}
- ); -}; - -const Btn = ({ children, variant = "primary", style: s = {}, ...rest }) => { - const styles = variant === "primary" - ? { background: "#1a1a1a", color: "#fff", border: "1px solid #1a1a1a" } - : variant === "secondary" - ? { background: "#fff", color: "#1a1a1a", border: "1px solid #e0dcd4" } - : { background: "transparent", color: "#a09a90", border: "1px solid transparent" }; - return ( - - ); -}; - -const InputField = ({ label, value, onChange, placeholder, type = "text", mono = false }) => ( -
-
{label}
- -
-); - -const Toggle = ({ on, onToggle, label }) => ( -
- {label} - -
-); - -/* ─── SIDEBAR ─── */ -const Sidebar = ({ activeProject, setActiveProject, view, setView }) => ( - -); - -/* ─── ACTIVITY PAGE ─── */ -const ActivityPage = ({ setActiveProject, setView }) => { - const [filter, setFilter] = useState("all"); - const filtered = filter === "all" ? activityFeed : activityFeed.filter(a => a.type === filter); - const typeIcon = (t) => t === "atlas" ? "A" : t === "build" ? "⚡" : t === "deploy" ? "▲" : "●"; - const typeColor = (t) => t === "atlas" ? "#1a1a1a" : t === "build" ? "#3d5afe" : t === "deploy" ? "#2e7d32" : "#8a8478"; - - return ( -
-

Activity

-

Everything happening across your projects

- - {/* Filters */} -
- {[ - { id: "all", label: "All" }, - { id: "atlas", label: "Atlas" }, - { id: "build", label: "Builds" }, - { id: "deploy", label: "Deploys" }, - { id: "user", label: "You" }, - ].map(f => ( - - ))} -
- - {/* Feed */} -
- {/* Timeline line */} -
- - {filtered.map((item, i) => ( -
e.currentTarget.style.background = "#fff"} - onMouseLeave={e => e.currentTarget.style.background = "transparent"} - > - {/* Dot on timeline */} -
- -
-
- - · - {item.time} -
-
{item.action}
-
-
- ))} -
-
- ); -}; - -/* ─── SETTINGS PAGE ─── */ -const SettingsPage = () => { - const [settingsTab, setSettingsTab] = useState("account"); - const [emailNotifs, setEmailNotifs] = useState(true); - const [buildNotifs, setBuildNotifs] = useState(true); - const [atlasDigest, setAtlasDigest] = useState(false); - const [darkMode, setDarkMode] = useState(false); - - return ( -
- {/* Settings nav */} -
-

Settings

- {[ - { id: "account", label: "Account" }, - { id: "notifications", label: "Notifications" }, - { id: "billing", label: "Plan & Billing" }, - { id: "team", label: "Team" }, - { id: "domains", label: "Domains" }, - { id: "api", label: "API Keys" }, - { id: "danger", label: "Danger Zone" }, - ].map(t => ( - - ))} -
- - {/* Settings content */} -
- {settingsTab === "account" && ( -
-

Account

-

Manage your profile and preferences

- - -
-
M
-
-
Michael
-
michael@example.com
-
- Change photo -
- {}} /> - {}} type="email" /> - {}} placeholder="Optional" /> -
- Save changes -
-
- - -

Preferences

-

Customize your workspace

- setDarkMode(!darkMode)} label="Dark mode" /> -
- Default project view - -
-
- Atlas personality - -
-
-
- )} - - {settingsTab === "notifications" && ( -
-

Notifications

-

Choose what you hear about and when

- - setEmailNotifs(!emailNotifs)} label="Email notifications" /> - setBuildNotifs(!buildNotifs)} label="Build completion alerts" /> - setAtlasDigest(!atlasDigest)} label="Daily Atlas digest" /> -
- Notification frequency - -
-
-
- )} - - {settingsTab === "billing" && ( -
-

Plan & Billing

-

Manage your subscription and usage

- - -
-
-
Current plan
-
Pro
-
- Active -
-
- {[ - { label: "Projects", value: "10", used: "4" }, - { label: "Builds/mo", value: "20", used: "3" }, - { label: "Deploys", value: "Unlimited", used: "—" }, - ].map((m, i) => ( -
-
{m.label}
-
- {m.used} - / {m.value} -
-
- ))} -
-
- - -
-
Payment method
-
•••• 4242 — expires 08/27
-
- Update -
-
- )} - - {settingsTab === "team" && ( -
-

Team

-

Manage collaborators and permissions

- - {[ - { name: "Michael", email: "michael@example.com", role: "Owner" }, - { name: "Craig F.", email: "craig@example.com", role: "Editor" }, - ].map((m, i) => ( -
-
{m.name[0]}
-
-
{m.name}
-
{m.email}
-
- {m.role} -
- ))} -
- + Invite team member -
-
-
- )} - - {settingsTab === "domains" && ( -
-

Domains

-

Custom domains for your deployed projects

- -
-
-
kb.acmecorp.com
-
→ Canopy
-
- Verified -
-
- + Add custom domain -
-
-
- )} - - {settingsTab === "api" && ( -
-

API Keys

-

Access your projects programmatically

- -
-
-
Production key
-
sk_live_••••••••••••3kF9
-
- Reveal -
-
-
-
Test key
-
sk_test_••••••••••••7mR2
-
- Reveal -
-
- + Generate new key -
-
-
- )} - - {settingsTab === "danger" && ( -
-

Danger Zone

-

Irreversible actions

- -
-
-
Delete account
-
Permanently remove your account and all projects
-
- Delete -
-
-
- )} -
-
- ); -}; - -/* ─── PROJECT DETAIL ─── */ -const ProjectDetail = ({ project }) => { - const [tab, setTab] = useState("chat"); - const [msgs, setMsgs] = useState(chatHistory); - const [input, setInput] = useState(""); - const [typing, setTyping] = useState(false); - const endRef = useRef(null); - - useEffect(() => { endRef.current?.scrollIntoView({ behavior: "smooth" }); }, [msgs, typing]); - - const send = () => { - if (!input.trim()) return; - setMsgs(p => [...p, { from: "user", text: input }]); - setInput(""); - setTyping(true); - setTimeout(() => { - setTyping(false); - setMsgs(p => [...p, { from: "atlas", text: "Good instinct. For multi-location, the core question is inventory: shared pool vs per-store tracking.\n\nOption A — Shared inventory. Simpler, but Store B can't trust the count if Store A just dispensed.\n\nOption B — Per-location with transfers. Accurate, adds a \"request stock\" workflow.\n\nMost independents start single-location and add multi-store as v2. Want to scope it that way?" }]); - }, 2000); - }; - - const prdPct = Math.round(prdData.reduce((a, s) => a + s.pct, 0) / prdData.length); - - return ( -
-
- {/* Header */} -
-
-
- {project.name[0]} -
-
-
-

{project.name}

- - {project.status === "live" ? "Live" : project.status === "building" ? "Building" : "Defining"} - -
-

{project.desc}

-
-
-
- {project.progress}% -
-
- - {/* Tabs */} -
- {[ - { id: "chat", label: "Atlas" }, - { id: "prd", label: "PRD" }, - { id: "build", label: "Build" }, - { id: "deploy", label: "Deploy" }, - { id: "projsettings", label: "Settings" }, - ].map(t => ( - - ))} -
- -
- - {/* CHAT */} - {tab === "chat" && ( -
-
- {msgs.map((m, i) => ( -
= chatHistory.length ? "enter 0.3s ease" : `enter 0.35s ease ${i * 0.08}s both` }}> -
- {m.from === "atlas" ? "A" : "M"} -
-
-
{m.from === "atlas" ? "Atlas" : "You"}
-
- {m.text.split(/(\*\*.*?\*\*)/).map((seg, j) => seg.startsWith("**") && seg.endsWith("**") ? {seg.slice(2, -2)} : seg)} -
-
-
- ))} - {typing && ( -
-
A
-
- {[0,1,2].map(d =>
)} -
-
- )} -
-
-
-
- setInput(e.target.value)} onKeyDown={e => e.key === "Enter" && send()} placeholder="Describe your thinking..." - style={{ flex: 1, border: "none", background: "none", fontSize: "0.86rem", fontFamily: "Outfit", color: "#1a1a1a", padding: "8px 0" }} /> - -
-
-
- )} - - {/* PRD */} - {tab === "prd" && ( -
-
-
{prdPct}%
-
-
-
-
-
- {prdData.filter(s => s.status === "done").length}/{prdData.length} approved -
- {prdData.map((s, i) => ( -
e.currentTarget.style.borderColor = "#d0ccc4"} - onMouseLeave={e => e.currentTarget.style.borderColor = "#e8e4dc"}> -
- {s.status === "done" ? "✓" : s.status === "active" ? "◐" : "○"} -
- {s.name} -
-
-
- {s.pct}% -
- ))} -
- )} - - {/* BUILD */} - {tab === "build" && ( -
- {project.status === "prd" ? ( -
-
🔒
-

Complete your PRD first

-

Approve all sections with Atlas, then the builder unlocks automatically.

-
- {prdPct}%complete -
-
- ) : ( -
-

Build progress

- {["Auth System", "Database", "Dashboard UI", "Rx Queue", "Inventory", "API"].map((f, i) => { - const pct = Math.max(0, Math.min(100, project.progress + (i * -12))); - return ( -
- = 100 ? "live" : pct > 0 ? "building" : "prd"} /> - {f} -
-
= 100 ? "#2e7d32" : "#3d5afe" }} /> -
- {pct}% -
- ); - })} -
- )} -
- )} - - {/* DEPLOY */} - {tab === "deploy" && ( -
-
-

Deployment

-

Links, environments, and hosting for {project.name}

- - {/* URLs card */} - - Project URLs - {project.domain ? ( - <> -
-
-
-
Staging
-
{project.domain}
-
- Open ↗ -
- {project.customDomain && ( -
-
-
-
Production
-
{project.customDomain}
-
- SSL Active - Open ↗ -
- )} -
-
-
-
Build repo
-
{project.repo}
-
- View ↗ -
- - ) : ( -
-

No deployment yet — complete your PRD and build to get a live URL.

-
- {project.progress}% to deployment -
-
- )} -
- - {/* Custom domain */} - {project.domain && !project.customDomain && ( - - Custom Domain -

- Point your own domain to this project. We'll handle SSL certificates automatically. -

-
- - Connect -
-
- )} - - {/* Environment vars */} - - Environment Variables - {project.domain ? ( - <> - {[ - { key: "DATABASE_URL", val: "••••••••••••" }, - { key: "API_SECRET", val: "••••••••••••" }, - { key: "SMTP_HOST", val: "mail.stackless.dev" }, - ].map((env, i) => ( -
- {env.key} - {env.val} - -
- ))} -
- + Add variable -
- - ) : ( -

Available after first build completes.

- )} -
- - {/* Deploy history */} - - Deploy History - {project.status === "live" ? ( - <> - {[ - { version: "v1.2", time: "1 day ago", status: "live", note: "Added search filters" }, - { version: "v1.1", time: "5 days ago", status: "previous", note: "Bug fix: auth timeout" }, - { version: "v1.0", time: "2 weeks ago", status: "previous", note: "Initial launch" }, - ].map((d, i) => ( -
- {d.version} - {d.note} - {d.time} - {d.status === "live" && Current} -
- ))} - - ) : project.domain ? ( -

First deploy will appear here once the build completes.

- ) : ( -

No deploys yet.

- )} -
-
-
- )} - - {/* PROJECT SETTINGS */} - {tab === "projsettings" && ( -
-
-

Project Settings

-

Configure {project.name}

- - - General - {}} /> -
-
Description
-