Commit Graph

95 Commits

Author SHA1 Message Date
afd76b394f fix(chat): preserve thread history across page reloads
Two bugs, one symptom (every reload silently spawned a blank thread,
the previous conversation was orphaned in the sidebar):

1. Race in the auto-thread effect.
   On mount: threads = [], activeThread = null, /api/chat/threads
   fetch in flight. The auto-create effect re-ran the moment the
   workspace + auth resolved, saw threads.length === 0, and called
   newThread() before the fetch ever returned. When the historical
   threads finally landed, activeThread was already pinned to the new
   empty one.

   Gate on a `threadsLoaded` flag that flips true after the first
   loadThreads() resolves. Auto-create can no longer fire before
   history is known.

2. activeThread wasn't persisted.
   Even with the race fixed, refreshing the page would reset the
   sidebar to the top thread (most recently updated). After a deploy
   that's usually the brand-new empty thread we just spawned, not the
   conversation the user was actually in.

   Persist activeThread to localStorage keyed by workspace. Reload
   restores the same thread; switching workspaces resets cleanly.

Made-with: Cursor
2026-04-28 14:26:34 -07:00
210fba4e08 Fix chat panel token fetch: use /api/workspaces not URL slug
URL param 'mark-account' != workspace slug 'mark'. Fetch default token
from /api/workspaces?include_default_token=true which resolves the real
slug server-side.

Made-with: Cursor
2026-04-27 16:26:55 -07:00
56e7c2fb5c Fix auto-token fetch: use keys?include_default_token=true instead of /keys/default
Avoids the Next.js dynamic route conflict with [keyId].
Chat panel now correctly bootstraps MCP token on mount with no user action.

Made-with: Cursor
2026-04-27 16:04:38 -07:00
1e138d69d6 Auto-mint default MCP token on workspace creation
- ensureWorkspaceForUser() now calls mintWorkspaceApiKey('default') on first workspace creation
- Legacy workspaces without a default key get one minted on first request
- GET /api/workspaces/[slug]/keys/default reveals (or mints) the default token for session users
- Chat panel fetches the token automatically on mount, caches it in localStorage
- No manual setup needed — tool calling works immediately on first sign-in

Made-with: Cursor
2026-04-27 15:43:27 -07:00
5e07bbf39d Add Vibn AI chat panel powered by Gemini 3.1 Pro
- Right-docked chat panel on all workspace pages ([workspace]/layout.tsx)
- Streaming SSE responses with Gemini 3.1 Pro preview via generativelanguage API
- Full tool-calling loop (up to 6 rounds): deploys apps, lists projects, registers
  domains, fetches logs — all via existing MCP dispatcher
- Persistent conversation history: fs_chat_threads + fs_chat_messages tables (Postgres)
- Thread management: create, list, rename (auto-title from first message), delete
- Panel collapses to a tab; open state persisted to localStorage
- Read-only mode hint when no MCP token is present
- Graceful content margin shift when panel is open

Made-with: Cursor
2026-04-27 15:40:32 -07:00
3192e0f7b9 fix(coolify): strip is_build_time from env writes; add reveal + GCS
Coolify v4's POST/PATCH /applications/{uuid}/envs only accepts key,
value, is_preview, is_literal, is_multiline, is_shown_once. Sending
is_build_time triggers a 422 "This field is not allowed." — it's now
a derived read-only flag (is_buildtime) computed from Dockerfile ARG
usage. Breaks agents trying to upsert env vars.

Three-layer fix so this can't regress:
  - lib/coolify.ts: COOLIFY_ENV_WRITE_FIELDS whitelist enforced at the
    network boundary, regardless of caller shape
  - app/api/workspaces/[slug]/apps/[uuid]/envs: stops forwarding the
    field; returns a deprecation warning when callers send it; GET
    reads both is_buildtime and is_build_time for version parity
  - app/api/mcp/route.ts: same treatment in the MCP dispatcher;
    AI_CAPABILITIES.md doc corrected

Also bundles (not related to the above):
  - Workspace API keys are now revealable from settings. New
    key_encrypted column stores AES-256-GCM(VIBN_SECRETS_KEY, token).
    POST /api/workspaces/[slug]/keys/[keyId]/reveal returns plaintext
    for session principals only; API-key principals cannot reveal
    siblings. Legacy keys stay valid for auth but can't reveal.
  - P5.3 Object storage: lib/gcp/storage.ts + lib/workspace-gcs.ts
    idempotently provision a per-workspace GCS bucket, service
    account, IAM binding and HMAC key. New POST /api/workspaces/
    [slug]/storage/buckets endpoint. Migration script + smoke test
    included. Proven end-to-end against prod master-ai-484822.

Made-with: Cursor
2026-04-23 11:46:50 -07:00
651ddf1e11 Rip out Theia, ship P5.1 attach E2E + Justine UI work-in-progress
Theia rip-out:
- Delete app/api/theia-auth/route.ts (Traefik ForwardAuth shim)
- Delete app/api/projects/[projectId]/workspace/route.ts and
  app/api/projects/prewarm/route.ts (Cloud Run Theia provisioning)
- Delete lib/cloud-run-workspace.ts and lib/coolify-workspace.ts
- Strip provisionTheiaWorkspace + theiaWorkspaceUrl/theiaAppUuid/
  theiaError from app/api/projects/create/route.ts response
- Remove Theia callbackUrl branch in app/auth/page.tsx
- Drop "Open in Theia" button + xterm/Theia PTY copy in build/page.tsx
- Drop theiaWorkspaceUrl from deployment/page.tsx Project type
- Strip Theia IDE line + theia-code-os from advisor + agent-chat
  context strings
- Scrub Theia mention from lib/auth/workspace-auth.ts comment

P5.1 (custom apex domains + DNS):
- lib/coolify.ts + lib/opensrs.ts: nameserver normalization, OpenSRS
  XML auth, Cloud DNS plumbing
- scripts/smoke-attach-e2e.ts: full prod GCP + sandbox OpenSRS +
  prod Coolify smoke covering register/zone/A/NS/PATCH/cleanup

In-progress (Justine onboarding/build, MVP setup, agent telemetry):
- New (justine)/stories, project (home) layouts, mvp-setup, run, tasks
  routes + supporting components
- Project shell + sidebar + nav refactor for the Stackless palette
- Agent session API hardening (sessions, events, stream, approve,
  retry, stop) + atlas-chat, advisor, design-surfaces refresh
- New scripts/sync-db-url-from-coolify.mjs +
  scripts/prisma-db-push.mjs + docker-compose.local-db.yml for
  local Prisma workflows
- lib/dev-bypass.ts, lib/chat-context-refs.ts, lib/prd-sections.ts
- Misc: stories CSS, debug/prisma route, modal-theme, BuildLivePlanPanel

Made-with: Cursor
2026-04-22 18:05:01 -07:00
14835e2e0a Revert "fix(gitea-bot): add write:organization scope so bot can create repos"
This reverts commit 6f79a88abd.

Made-with: Cursor
2026-04-21 11:12:20 -07:00
6f79a88abd fix(gitea-bot): add write:organization scope so bot can create repos
Without this the bot PAT 403s on POST /orgs/{org}/repos, which is
the single most important operation — creating new project repos
inside the workspace's Gitea org.

Made-with: Cursor
2026-04-21 11:05:55 -07:00
b9511601bc feat(ai-access): per-workspace Gitea bot + tenant-safe Coolify proxy + MCP
Ship Phases 1–3 of the multi-tenant AI access plan so an AI agent can
act on a Vibn workspace with one bearer token and zero admin reach.

Phase 1 — Gitea bot per workspace
- Add gitea_bot_username / gitea_bot_user_id / gitea_bot_token_encrypted
  columns to vibn_workspaces (migrate route).
- New lib/auth/secret-box.ts (AES-256-GCM, VIBN_SECRETS_KEY) for PAT at rest.
- Extend lib/gitea.ts with createUser, createAccessTokenFor (Sudo PAT),
  createOrgTeam, addOrgTeamMember, ensureOrgTeamMembership.
- ensureWorkspaceProvisioned now mints a vibn-bot-<slug> user, adds it to
  a Writers team (write perms only) on the workspace's org, and stores
  its PAT encrypted.
- GET /api/workspaces/[slug]/gitea-credentials returns a workspace-scoped
  bot PAT + clone URL template; session or vibn_sk_ bearer auth.

Phase 2 — Tenant-safe Coolify proxy + real MCP
- lib/coolify.ts: projectUuidOf, listApplicationsInProject,
  getApplicationInProject, TenantError, env CRUD, deployments list.
- Workspace-scoped REST endpoints (all filtered by coolify_project_uuid):
  GET/POST /api/workspaces/[slug]/apps/[uuid](/deploy|/envs|/deployments),
  GET /api/workspaces/[slug]/deployments/[deploymentUuid]/logs.
- Full rewrite of /api/mcp off legacy Firebase onto Postgres vibn_sk_
  keys, exposing workspace.describe, gitea.credentials, projects.*,
  apps.* (list/get/deploy/deployments, envs.list/upsert/delete).

Phase 3 — Settings UI AI bundle
- GET /api/workspaces/[slug]/bootstrap.sh: curl|sh installer that writes
  .cursor/rules, .cursor/mcp.json and appends VIBN_* to .env.local.
  Embeds the caller's vibn_sk_ token when invoked with bearer auth.
- WorkspaceKeysPanel: single AiAccessBundleCard with system-prompt block,
  one-line bootstrap, Reveal-bot-PAT button, collapsible manual-setup
  fallback. Minted-key modal also shows the bootstrap one-liner.

Ops prerequisites:
  - Set VIBN_SECRETS_KEY (>=16 chars) on the frontend.
  - Run /api/admin/migrate to add the three bot columns.
  - GITEA_API_TOKEN must be a site-admin token (needed for admin/users
    + Sudo PAT mint); otherwise provision_status lands on 'partial'.

Made-with: Cursor
2026-04-21 10:49:17 -07:00
0bdf598984 fix(workspace-panel): resolve workspace via /api/workspaces, not URL slug
The panel was fetching /api/workspaces/{urlSlug} where {urlSlug}
is whatever is in the `[workspace]` dynamic segment (e.g.
"mark-account"). That slug has nothing to do with vibn_workspaces.slug,
which is derived from the user's email — so the fetch 404'd, the
component showed "Loading workspace…" forever, and minting/revoking
would target a non-existent workspace.

Now:
- GET /api/workspaces lazy-creates a workspace row if the signed-in
  user has none (migration path for accounts created before the
  signIn hook was added).
- WorkspaceKeysPanel discovers the user's actual workspace from that
  list and uses *its* slug for all subsequent calls (details, keys,
  provisioning, revocation).
- Empty / error states render a proper card with a retry button
  instead of a bare "Workspace not found." line.

Made-with: Cursor
2026-04-20 20:43:46 -07:00
acb63a2a5a feat(workspaces): per-account tenancy + AI access keys + Cursor integration
Adds logical multi-tenancy on top of Coolify + Gitea so every Vibn
account gets its own isolated tenant boundary, and exposes that
boundary to AI agents (Cursor, Claude Code, scripts) through
per-workspace bearer tokens.

Schema (additive, idempotent — run /api/admin/migrate once after deploy)
  - vibn_workspaces: slug, name, owner, coolify_project_uuid,
    coolify_team_id (reserved for when Coolify ships POST /teams),
    gitea_org, provision_status
  - vibn_workspace_members: room for multi-user workspaces later
  - vibn_workspace_api_keys: sha256-hashed bearer tokens
  - fs_projects.vibn_workspace_id: nullable FK linking projects
    to their workspace

Provisioning
  - On first sign-in, ensureWorkspaceForUser() inserts the row
    (no network calls — keeps signin fast).
  - On first project create, ensureWorkspaceProvisioned() lazily
    creates a Coolify Project (vibn-ws-{slug}) and a Gitea org
    (vibn-{slug}). Failures are recorded on the row, not thrown,
    and POST /api/workspaces/{slug}/provision retries.

Auth surface
  - lib/auth/workspace-auth.ts: requireWorkspacePrincipal() accepts
    either a NextAuth session or "Authorization: Bearer vibn_sk_...".
    The bearer key is hard-pinned to one workspace — it cannot
    reach any other tenant.
  - mintWorkspaceApiKey / listWorkspaceApiKeys / revokeWorkspaceApiKey

Routes
  - GET    /api/workspaces                         list
  - GET    /api/workspaces/[slug]                  details
  - POST   /api/workspaces/[slug]/provision        retry provisioning
  - GET    /api/workspaces/[slug]/keys             list keys
  - POST   /api/workspaces/[slug]/keys             mint key (token shown once)
  - DELETE /api/workspaces/[slug]/keys/[keyId]     revoke

UI
  - components/workspace/WorkspaceKeysPanel.tsx: identity card,
    keys CRUD with one-time secret reveal, and a "Connect Cursor"
    block with copy/download for:
      .cursor/rules/vibn-workspace.mdc — rule telling the agent
        about the API + workspace IDs + house rules
      ~/.cursor/mcp.json — MCP server registration with key
        embedded (server URL is /api/mcp; HTTP MCP route lands next)
      .env.local — VIBN_API_KEY + smoke-test curl
  - Slotted into existing /[workspace]/settings between Workspace
    and Notifications cards (no other layout changes).

projects/create
  - Resolves the user's workspace (creating + provisioning lazily).
  - Repos go under workspace.gitea_org (falls back to GITEA_ADMIN_USER
    for backwards compat).
  - Coolify services are created inside workspace.coolify_project_uuid
    (renamed {slug}-{appName} to stay unique within the namespace) —
    no more per-Vibn-project Coolify Project sprawl.
  - Stamps vibn_workspace_id on fs_projects.

lib/gitea
  - createOrg, getOrg, addOrgOwner, getUser
  - createRepo now routes /orgs/{owner}/repos when owner != admin

Also includes prior-turn auth hardening that was already in
authOptions.ts (CredentialsProvider for dev-local, isLocalNextAuth
cookie config) bundled in to keep the auth layer in one consistent
state.

.env.example
  - Documents GITEA_API_URL / GITEA_API_TOKEN / GITEA_ADMIN_USER /
    GITEA_WEBHOOK_SECRET and COOLIFY_URL / COOLIFY_API_TOKEN /
    COOLIFY_SERVER_UUID, with the canonical hostnames
    (git.vibnai.com, coolify.vibnai.com).

Post-deploy
  - Run once: curl -X POST https://vibnai.com/api/admin/migrate \\
      -H "x-admin-secret: \$ADMIN_MIGRATE_SECRET"
  - Existing users get a workspace row on next sign-in.
  - Existing fs_projects keep working (legacy gitea owner + their
    own per-project Coolify Projects); new projects use the
    workspace-scoped path.

Not in this commit (follow-ups)
  - Wiring requireWorkspacePrincipal into the rest of /api/projects/*
    so API keys can drive existing routes
  - HTTP MCP server at /api/mcp (the mcp.json snippet already
    points at the right URL — no client re-setup when it lands)
  - Backfill script to assign legacy fs_projects to a workspace

Made-with: Cursor
2026-04-20 17:17:12 -07:00
74f8dc4282 fix(ui): make Justine palette visible on marketing + trim rainbow chrome
- Replace blue/purple gradients with ink gradient text and cream/parch CTA surface
- Step badges and transformation icons use primary (ink) fills
- /features page icons unified to text-primary; Lora section titles
- Tree view status colors use semantic tokens instead of blue/green

Made-with: Cursor
2026-04-01 21:09:18 -07:00
bada63452f feat(ui): apply Justine ink & parchment design system
- Map Justine tokens to shadcn CSS variables (--vibn-* aliases)
- Switch fonts to Inter + Lora via next/font (IBM Plex Mono for code)
- Base typography: body Inter, h1–h3 Lora; marketing hero + wordmark serif
- Project shell and global chrome use semantic colors
- Replace Outfit/Newsreader references across TSX inline styles

Made-with: Cursor
2026-04-01 21:03:40 -07:00
8eb6c149cb fix: map Non-Functional Reqs to features_scope phase, remove circular 'Generated when PRD finalized' hint
Made-with: Cursor
2026-03-17 17:15:26 -07:00
062e836ff9 fix: always show chat on Vibn tab — swap empty 'done' state for thin PRD-ready notice bar
Made-with: Cursor
2026-03-17 17:10:06 -07:00
d9bea73032 feat: add quick-action chips above chat input (suggestions, importance, move on)
Made-with: Cursor
2026-03-17 17:02:40 -07:00
532f851d1f ux: skip type selector — new project goes straight to name input
- CreateProjectFlow now defaults to setup/fresh mode; type selector never shown
- FreshIdeaSetup simplified to just project name + Start button
  (removed description field, 6-phase explanation copy, SetupHeader)

Made-with: Cursor
2026-03-17 16:58:35 -07:00
f1b4622043 fix: make content wrapper a flex column so child pages can scroll
Made-with: Cursor
2026-03-17 16:40:24 -07:00
f47205c473 rename: replace all user-facing 'Atlas' references with 'Vibn'
Updated UI text in: project-shell (tab label), AtlasChat (sender name),
FreshIdeaMain, TypeSelector, MigrateSetup, ChatImportSetup, FreshIdeaSetup,
CodeImportSetup, prd/page, build/page, projects/page, deployment/page,
activity/page, layout (page title/description), atlas-chat API route.
Code identifiers (AtlasChat component name, file names) unchanged.

Made-with: Cursor
2026-03-17 16:25:41 -07:00
f9f3156d49 fix: PRD tracker shows sections complete (0 of 12), not internal phases
Made-with: Cursor
2026-03-17 16:22:02 -07:00
2e3b405893 feat: restore PRD section tracker on the right side of Atlas chat
Two-column layout on the Atlas tab:
- Left: Atlas discovery chat (full height, flex 1)
- Right: 240px PRD section panel showing all 12 sections with
  live status dots (filled = phase saved, empty = pending)
  plus a progress bar showing phases complete out of 6
- Discovery banner (all 6 done) now lives inside the left column
- "Generate PRD" footer CTA appears in right panel when all done

Made-with: Cursor
2026-03-17 16:15:06 -07:00
9e20125938 revert: restore Atlas|PRD|Build|Growth|Assist|Analytics tab nav, remove COO sidebar
- SECTIONS back to 6 tabs: Atlas → /overview, PRD, Build, Growth, Assist, Analytics
- Remove persistent CooChat left panel and drag-resize handle
- Content area is now full-width again (no 320px sidebar eating space)
- Clean up unused imports (useSearchParams, useRouter, CooChat, Lucide icons, TOOLS constant)

Made-with: Cursor
2026-03-17 16:03:19 -07:00
c35e7dbe56 feat: draggable resize handle on the CooChat sidebar
Made-with: Cursor
2026-03-10 16:38:13 -07:00
99c1a83b9f feat: load Atlas discovery history into CooChat sidebar
Eliminates the two-chat experience on the overview page:

- CooChat now pre-loads Atlas conversation history on mount, showing
  the full discovery conversation in the left panel. Atlas messages
  render with a blue "A" avatar; COO messages use the dark "◈" icon.
  A "Discovery · COO" divider separates historical from new messages.
- FreshIdeaMain detects when a PRD already exists and replaces the
  duplicate AtlasChat with a clean completion view ("Discovery complete")
  that links to the PRD and Build pages. Atlas chat only shows when
  discovery is still in progress.

Made-with: Cursor
2026-03-10 16:28:44 -07:00
1af5595e35 feat(tasks): move Tasks first in toolbar, add Tasks+PRD left nav and content
Made-with: Cursor
2026-03-09 22:02:01 -07:00
e3c6b9a9b4 feat(create): show only Fresh Idea and Import Chats project types
Made-with: Cursor
2026-03-09 19:02:25 -07:00
6901a97db3 feat(migrate): wire GitHub PAT through to agent runner mirror call
MigrateSetup now sends the PAT field to the API; create route
forwards it as github_token so the agent runner can clone private repos.

Made-with: Cursor
2026-03-09 18:05:12 -07:00
70c94dc60c feat: tool icons drive left nav section, remove inner pills
Made-with: Cursor
2026-03-09 16:49:47 -07:00
57c0744b56 feat: move tool icons adjacent to section pills, add active toggle state
Made-with: Cursor
2026-03-09 16:31:38 -07:00
aa23a552c4 feat: replace unicode tool icons with Lucide icons (Globe, Cloud, Palette, Code2, BarChart2)
Made-with: Cursor
2026-03-09 16:28:19 -07:00
853e41705f feat: split top navbar to align with chat/content panels, fix Gemini API key
- Top bar left section (320px) = logo + project name, aligns with chat panel
- Top bar right section = Build|Market|Assist pills + tool icons (Preview, Tasks, Code, Design, Backend) + avatar
- Read GOOGLE_API_KEY inside POST handler (not top-level) to ensure env is resolved at request time

Made-with: Cursor
2026-03-09 16:17:31 -07:00
1ef3f9baa3 feat: top navbar (Build|Market|Assist) + persistent Assist chat in shell
- New top navbar in ProjectShell: logo + project name | Build | Market |
  Assist tabs | user avatar — replaces the left icon sidebar for project pages
- CooChat extracted to components/layout/coo-chat.tsx and moved into the
  shell so it persists across Build/Market/Assist route changes
- Build page inner layout simplified: inner nav (200px) + file viewer,
  no longer owns the chat column
- Layout: [top nav 48px] / [Assist chat 320px | content flex]

Made-with: Cursor
2026-03-09 15:51:48 -07:00
01dd9fda8e fix: wire MigrateSetup repoUrl to githubRepoUrl for mirror flow
Made-with: Cursor
2026-03-09 11:47:41 -07:00
231aeb4402 move project tabs to sidebar, remove top tab bar
Made-with: Cursor
2026-03-08 13:00:54 -07:00
93a2b4a0ac refactor: strip sidebar down to project name + status only
Removed all product layer sections (Build, Layouts, Infrastructure,
Growth, Monetize, Support, Analytics) from the left sidebar — these
are now handled by the in-page left nav inside each tab.

Sidebar now shows: logo, Projects/Activity/Settings global nav,
project name + colored status dot when inside a project, and the
user avatar/sign out at the bottom. Nothing else.

Cleaned up all dead code: SectionHeading, SectionRow, SectionDivider,
SURFACE_LABELS, SURFACE_ICONS, AppEntry interface, apps state,
apps fetch, surfaces/infraApps variables.

Made-with: Cursor
2026-03-06 17:36:31 -08:00
3cd477c295 feat: restructure project nav to Atlas | PRD | Build | Growth | Assist | Analytics
Tab bar:
- Removed: Design, Launch, Grow, Insights, Settings tabs
- Added: Growth, Assist, Analytics as top-level tabs
- Build remains, now a full hub

Build hub (/build):
- Left sub-nav groups: Code (apps), Layouts (surfaces), Infrastructure (6 items)
- Code section: scoped file browser per selected app
- Layouts section: surface overview cards with Edit link to /design
- Infrastructure section: summary panel linking to /infrastructure?tab=

Growth (/growth):
- Left nav: Marketing Site, Communications, Channels, Pages
- Each section: description + feature item grid + feedback CTA

Assist (/assist):
- Left nav: Emails, Chat Support, Support Site, Communications
- Each section: description + feature item grid + feedback CTA

Analytics (/analytics):
- Left nav: Customers, Usage, Events, Reports
- Each section: description + feature item grid + feedback CTA

Made-with: Cursor
2026-03-06 14:36:11 -08:00
3770ba1853 feat: Infrastructure section with 6 sub-sections (Builds, Databases, Services, Environment, Domains, Logs)
- Sidebar Infrastructure replaced with 6 named rows linking to /infrastructure?tab=
- New /infrastructure page with left sub-nav and per-tab content panels:
  Builds — lists deployed Coolify apps with live status
  Databases — coming soon placeholder
  Services — coming soon placeholder
  Environment — variable table with masked values (scaffold)
  Domains — lists configured domains with SSL status
  Logs — dark terminal panel, ready to stream
- Dim state on rows reflects whether data exists (e.g. no domains = dim)

Made-with: Cursor
2026-03-06 14:18:03 -08:00
39167dbe45 feat: deep-link sidebar Layouts to specific design surface
- Sidebar Layouts items now link to /design?surface=<surfaceId>
- Design page reads ?surface= param and opens that surface directly
- DesignPage split into DesignPageInner + Suspense wrapper so
  useSearchParams works in the Next.js static build

Made-with: Cursor
2026-03-06 14:12:29 -08:00
812645cae8 feat: scope Build file browser to selected app, rename Apps → Build
- Sidebar "Apps" section renamed to "Build"
- Each app now links to /build?app=<name>&root=<path> so the browser
  opens scoped to that app's subdirectory only
- Build page shows an empty-state prompt when no app is selected
- File tree header shows the selected app name, breadcrumb shows
  relative path within the app (strips the root prefix)
- Wraps useSearchParams in Suspense for Next.js static rendering

Made-with: Cursor
2026-03-06 13:51:01 -08:00
e08fcf674b feat: VIBN-branded file browser on Build tab + sidebar status dot
- Build page: full file tree (lazy-load dirs) + code preview panel
  with line numbers and token-level syntax colouring (VS Code dark theme)
- New API route /api/projects/[id]/file proxies Gitea contents API
  returning directory listings or decoded file content
- Sidebar Apps section now links to /build instead of raw Gitea URL
- Status indicator replaced with a proper coloured dot (amber/blue/green)
  alongside the status label text

Made-with: Cursor
2026-03-06 13:37:38 -08:00
bb021be088 refactor: rework project page layout - sidebar as product OS, full-width content
- VIBNSidebar: when inside a project, lower section now shows 7 product
  layer sections (Apps, Layouts, Infrastructure, Growth, Monetize, Support,
  Analytics) instead of the projects list. Sections self-fetch data from
  /api/projects/[id] and /api/projects/[id]/apps. On non-project pages,
  reverts to the projects list as before.
- ProjectShell: removed the project header strip (name/status/progress bar)
  and the persistent 230px right panel entirely. Tab bar now sits at the
  top of the content area with no header above it. Content is full-width.
  Each page manages its own internal layout.

Made-with: Cursor
2026-03-06 13:26:08 -08:00
ab100f2e76 feat: implement 4 project type flows with unique AI experiences
- New multi-step CreateProjectFlow replaces 2-step modal with TypeSelector
  and 4 setup components (Fresh Idea, Chat Import, Code Import, Migrate)
- overview/page.tsx routes to unique main component per creationMode
- FreshIdeaMain: wraps AtlasChat with post-discovery decision banner
  (Generate PRD vs Plan MVP Test)
- ChatImportMain: 3-stage flow (intake → extracting → review) with
  editable insight buckets (decisions, ideas, questions, architecture, users)
- CodeImportMain: 4-stage flow (input → cloning → mapping → surfaces)
  with architecture map and surface selection
- MigrateMain: 5-stage flow with audit, review, planning, and migration
  plan doc with checkbox-tracked tasks and non-destructive warning banner
- New API routes: analyze-chats, analyze-repo, analysis-status,
  generate-migration-plan (all using Gemini)
- ProjectShell: accepts creationMode prop, filters/renames tabs per type
  (code-import hides PRD, migration hides PRD/Grow/Insights, renames Atlas tab)
- Right panel adapts content based on creationMode

Made-with: Cursor
2026-03-06 12:48:28 -08:00
69eb3b989c Fix BgLayer SVG gradient reference causing dark rectangle in light mode
- beams: replaced SVG gradient <rect fill='url(#bm-glow)'> with a CSS
  radial-gradient div — browser SVG gradient reference fallback is solid
  black which produced the dark rectangle. Also adapt line colors and
  opacity for light mode.
- meteors: switch tail gradient from white-tip to dark-tip in light mode
  so meteors are visible on a light background.
- wavy: remove SVG linearGradient id references (same black-fill risk);
  use inline hex alpha on fill instead.

Made-with: Cursor
2026-03-06 11:17:13 -08:00
7eaf1ca4f1 Filter color palettes by dark/light mode
- Add themeMode?: 'dark'|'light' to ThemeColor (unset = any mode)
- Tag all DaisyUI themes: 11 dark (synthwave, aqua, luxury, night, etc.)
  and 6 light (light, cupcake, valentine, cyberpunk, retro, winter)
- Tag HeroUI Marketing themes: purple/blue/teal/modern=light, dark=dark
- Aceternity accent palettes stay untagged (work with either mode)
- Filter availableColorThemes in SurfaceSection by designConfig.mode
- Auto-reset active palette when mode switches makes previously
  selected palette incompatible

Made-with: Cursor
2026-03-06 11:03:22 -08:00
4eff014ae6 Fix Aceternity gradient background in light mode
BgLayer 'gradient' always rendered rgb(8,0,20) dark base regardless
of mode, covering the container's light bg and making the dark
gradient-text h1 invisible. Split into isDark branches: dark mode
keeps the hard-light blob effect, light mode renders soft pastel
blobs on rgb(248,247,255).

Made-with: Cursor
2026-03-06 10:53:23 -08:00
57a4f358d1 QA: fix dark/light mode rendering across all scaffolds
Aceternity (critical — light mode was completely broken):
- text/muted/card/border now respond to isDark instead of only forcedLight
- gradient-text h1 was white→transparent gradient (invisible on light bg);
  now switches to indigo gradient in light mode
- Minimal nav background was hardcoded dark; now adapts per isDark
- Floating nav background adapts per isDark
- "Browse components" button bg adapts per isDark
- 9x hardcoded color:"#fff" on content text replaced with color:text
  (lamp h1, typewriter word spans, feature titles, moving card names,
   bento MRR/Users/Uptime values, pricing prices, CTA heading, nav logo)

DaisyUI:
- noise background option now renders a visible SVG fractalNoise pattern

Made-with: Cursor
2026-03-06 10:47:45 -08:00
ef9f5a6ad3 UX: all sections on by default, palette at top, fix font loading
- All library defaultConfigs now enable every available section
- Color palette moved above Library picker in right panel (top of mind)
- Added fontImport() helper that injects Google Fonts @import into each
  scaffold's style tag so Plus Jakarta, DM Sans, Geist, Inter, Nunito
  actually load instead of falling back to system-ui

Made-with: Cursor
2026-03-06 10:31:37 -08:00
eff75a1ab5 Scale all marketing scaffolds to full website proportions
Remove compact/condensed sizing — all four scaffolds now render at real
website scale (72-80px headlines, 15-18px body, 80px section padding,
48-52px buttons, 64px navs, 340px DashMockup height) so the preview
scrolls naturally rather than squishing everything to fit the viewport.

Made-with: Cursor
2026-03-06 10:21:22 -08:00
0a237e1e8f Ground-up rewrite of all 4 marketing scaffolds to premium SaaS quality
Core problems fixed:
- Emoji icons (🔒📈) removed → replaced with clean inline SVG paths
- No product visualization → all heroes now include a real DashMockup component
- Generic flat sections → proper shadowed cards, feature lists, star testimonials
- Small unimpressive text → 42-56px display headlines with tight letter-spacing

New shared infrastructure:
- DashMockup: browser chrome + sidebar + 3 KPI cards + gradient line chart
  with accent colour theming; used in DaisyUI/HeroUI/Aceternity heroes
- Ico/ICO system: 12 SVG icons (bolt, shield, trend, globe, code, layers,
  clock, target, cpu, zap, users, sparkle) replace all emoji

DaisyUI improvements:
- 3 hero layouts: centered (CTA + full-width dashboard), split (left text +
  right dashboard), stats (big metrics row + dashboard)
- Feature section: 6 cards with SVG icons, proper copy, realistic shadows
- Steps section: numbered with editorial style
- Testimonials: 4 cards with star ratings and avatar initials
- Pricing: 3 tiers with full feature bullet lists and checkmarks
- FAQ: expand/collapse style

Aceternity improvements:
- Hero text increased to 48-52px
- Floating tilted card animations via CSS keyframes (ace-float, ace-float2)
- Feature cards with SVG icons instead of emoji
- Better moving-cards testimonials (wider, more realistic copy)
- Better bento grid with real chart

HeroUI improvements:
- All 3 header styles now include DashMockup (animated-badge, split, gradient)
- Feature section: 2-col with left-aligned icon + text (not centered emoji)
- Metrics bento with 4 KPIs
- Avatar trust stack with initials
- Pricing with popular tag

Tailwind improvements:
- Editorial header: huge 56px headline + real terminal mockup
  (git push → build 2.1s → deployed to prod) with syntax highlighting
- Split header: text + terminal side by side
- Feature grid: 6 cards with SVG icons
- Stats bar with 4 metrics
- Pricing: 3 tiers with checkmark feature lists
- Inverted CTA banner (bg=text, color=bg)

Made-with: Cursor
2026-03-05 21:34:57 -08:00