Commit Graph

19 Commits

Author SHA1 Message Date
c7bb0eea58 feat(project-creation): replace owner-style picker with audience picker
"Myself / A client" was about who *owns* the project (a billing
concern), but at creation time we want to know who *uses* it — that's
what determines which Infrastructure providers we should pre-stage.

  team       = internal users (your team / employees)
               → SSO-style auth, no payments by default, simple roles
  customers  = external users (the public)
               → public sign-up + payments + transactional email by
                 default, custom domain matters

Both choices are reversible from the Infrastructure tab later — the
selector copy makes that explicit so users don't feel locked in.

Changes: - setup-shared: ForWhomSelector ("Myself" / "A client") replaced by
    AudienceSelector ("My team" / "Customers"), with an "you can
    change this later" hint underneath. New Audience union type
    exported for the three setup screens to share.
  - BuildSetup / OssSetup / ImportSetup: swap state + import + payload.
    Defaults: BuildSetup → customers (most "vibe coder" projects are
    public products), ImportSetup → customers (existing repos usually
    are too), OssSetup → team (Twenty / n8n / Plausible style tools
    are most often deployed for internal use).
  - /api/projects/create: drop isForClient (we never read it
    anywhere), persist audience as a first-class field on the
    project record so the AI can branch on it during the first chat.
Made-with: Cursor
2026-04-29 16:24:54 -07:00
7a9cd68ea8 feat(project-creation): 3-path wizard — Build / OSS / Import
User feedback: the previous flow was a single-screen "name + audience"
dialog that gave AI no context about what the user actually wanted to
make. That worked for the demo but produced messy projects in practice
because everything was decided after the fact in chat.

The new flow asks the user one human question first ("How would you
like to begin?") and then captures the minimum context needed to seed
the AI's first conversation in the project.

Three paths, each is a 2-step setup screen with internal step dots:

  - Build your own idea  — Step 1: name + audience.  Step 2: free-text
    "what do you want to build". Becomes the project's vision and the
    AI's first-message context.

  - Run an open source tool  — Step 1: name + audience.  Step 2:
    segmented tabs to either (a) paste a GitHub link or (b) describe
    the kind of tool you want and have Vibn find one. Vision is set
    to either "Install and host this open-source project: <url>" or
    "Find and install an open-source tool that fits this need: <desc>"
    so the AI knows which mode to operate in on first chat.

  - Import existing code  — Step 1: name + audience + repo URL.
    Step 2: optional "what do you want to do with it" textarea.
    Public repos only for v1; private-repo OAuth lands later.

Backend:
  - /api/projects/create now accepts and persists `creationMode` and
    `sourceData` on the project record under a `kickoff` blob:
      { mode, sourceData, vision, createdAt }
    The chat endpoint will read this on first turn to seed the AI
    with the user's stated intent rather than asking them to re-type
    it in chat.

Cleanup:
  - Removed FreshIdeaSetup, CodeImportSetup, ChatImportSetup,
    MigrateSetup — replaced by BuildSetup, OssSetup, ImportSetup.
  - Removed the unused initialWorkspacePath prop from
    project-association-prompt (the new flow doesn't take it).
  - TypeSelector defaults are restored — the modal opens on the
    type-picker step now, not directly on a setup form.

UI building blocks added to setup-shared:
  - TextArea (multi-line input)
  - StepDots (page indicator)
  - SegmentedTabs (generic-typed tab selector, used in OSS Step 2)
  - SecondaryButton (used as ← Back inside Step 2)

Made-with: Cursor
2026-04-29 16:16:53 -07:00
b9c8457eb3 Stop auto-scaffolding 4 sub-apps + turborepo on project creation
Every new Vibn project was being seeded with:
  - a turborepo scaffold pushed to its Gitea repo
    (apps/product, apps/website, apps/admin, apps/storybook)
  - 4 corresponding Coolify services that nobody ever deployed

Both predate templates / GitHub imports / on-demand AI deploys and
created noise in every workspace's Coolify view (and confused the AI
about what was actually running).

Now project creation provisions just:
  - a Gitea repo (empty unless GitHub mirror is requested)
  - a dedicated Coolify project ready to receive deploys

Apps land in the project via apps_create on demand — what the user
actually wants, not a guess. The lib/scaffold/turborepo/ files remain
in source for future opt-in re-introduction.

Made-with: Cursor
2026-04-27 19:06:47 -07:00
1a686c2a23 Per-project Coolify project isolation (Stage 1)
Each Vibn project now gets its OWN Coolify project named
vibn-{workspace-slug}-{project-slug}. All apps/databases/services
deployed for the project land inside that Coolify project, giving
us clean grouping, cascading delete, and per-project domain
namespaces.

Changes:
- New lib/projects.ts: ensureProjectCoolifyProject (idempotent
  create/lookup), getProjectCoolifyUuid, getOwnedCoolifyProjectUuids
- /api/projects/create: pre-insert row, mint per-project Coolify
  project, then complete the row with productData (preserves the
  coolifyProjectUuid that was just set)
- apps.list (MCP): without projectId, aggregates across ALL
  workspace-owned Coolify projects; with projectId, scopes to
  that project's Coolify project. Returns coolifyProjectUuid
  on each result so the AI knows where things live.
- apps.create (MCP): accepts projectId; auto-mints the Vibn
  project's Coolify project on first deploy if missing
- apps_list/apps_create tool defs: projectId param surfaced
- System prompt: Project as first-class — planning + live as
  facets of ONE thing, never as separate worlds. AI told to
  always pass projectId on apps_create.

Stage 2 (next): set-aware ensureResourceInProject across all
single-resource MCP tools (apps.get/delete/exec/etc.) and
cascading delete via projects.delete.

Made-with: Cursor
2026-04-27 19:02:43 -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
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
528d6bb1e3 fix: remove colon from Coolify project description — fails Coolify validation
Made-with: Cursor
2026-03-09 18:20:33 -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
0e204ced89 feat: store coolifyProjectUuid on project creation for Infrastructure panel
Made-with: Cursor
2026-03-09 17:40:21 -07:00
9c277fd8e3 feat: add GitHub import flow, project delete fix, and analyze API
- Mirror GitHub repos to Gitea as-is on import (skip scaffold)
- Auto-trigger ImportAnalyzer agent after successful mirror
- Add POST/GET /api/projects/[projectId]/analyze route
- Fix project delete button visibility (was permanently opacity:0)
- Store isImport, importAnalysisStatus, importAnalysisJobId on projects

Made-with: Cursor
2026-03-09 11:30:51 -07:00
35675b7d86 fix: stop prisma from dropping custom tables on every deploy
entrypoint.sh: removed --accept-data-loss from prisma db push.
That flag was silently dropping fs_users, fs_projects etc. on every
container restart, wiping all user/project data. Made the push
non-fatal so a schema mismatch doesn't block startup.

create/route.ts: fixed same broken ON CONFLICT expression as
authOptions.ts — replaced with explicit SELECT + INSERT/UPDATE
to reliably upsert fs_users before inserting the project.

Made-with: Cursor
2026-02-27 19:15:55 -08:00
c9ef2379ec fix: upsert fs_users before inserting fs_projects to satisfy FK constraint
Made-with: Cursor
2026-02-27 13:36:25 -08:00
8587644a62 feat: turborepo monorepo scaffold and provisioning
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-21 16:44:37 -08:00
f4ab70822c fix: handle Gitea 409 on project create by linking to existing repo
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-19 17:16:24 -08:00
106d9c5ff1 feat: switch workspace provisioning from Coolify to Cloud Run
- lib/cloud-run-workspace.ts: provisions per-project Theia workspaces as
  Cloud Run services (theia-{slug}), scales to zero when idle, starts in
  ~5-15s from cached image
- create/route.ts: imports cloud-run-workspace instead of coolify-workspace
- Image: northamerica-northeast1-docker.pkg.dev/master-ai-484822/vibn-ide/theia:latest
- Includes prewarmWorkspace() for near-zero perceived load time on login

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-19 14:01:02 -08:00
a22d5a0f18 feat: provision dedicated per-project Theia workspaces
- lib/coolify-workspace.ts: creates a Coolify docker-image app at
  {slug}.ide.vibnai.com for each project, patches in vibn-auth Traefik
  labels, sets env vars, and starts deployment
- create/route.ts: provisions Theia workspace after Gitea repo creation;
  stores theiaWorkspaceUrl + theiaAppUuid on the project record
- theia-auth/route.ts: for *.ide.vibnai.com hosts, verifies the
  authenticated user is the project owner (slug → fs_projects lookup)
- overview/page.tsx: Open IDE always links (dedicated URL or shared fallback)
- project-creation-modal.tsx: shows dedicated workspace URL in success screen

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-19 13:14:21 -08:00
373bcee8c1 feat: Gitea auto-provisioning and webhook context sync
- Add lib/gitea.ts: Gitea API client (createRepo, createWebhook,
  deleteRepo, verifyWebhookSignature)
- Add lib/coolify.ts: Coolify API client (projects, databases,
  applications, deployments)
- Update api/projects/create: auto-creates a private Gitea repo and
  registers a webhook on every new project; stores giteaRepo,
  giteaRepoUrl, giteaCloneUrl, giteaSshUrl, giteaWebhookId in project
  data; Gitea errors are non-fatal so project creation still succeeds
- Add api/webhooks/gitea: handles push, pull_request, issues events;
  verifies HMAC signature; updates contextSnapshot on project record
- Add api/webhooks/coolify: handles deployment status events; updates
  contextSnapshot.lastDeployment on project record

Requires env vars: GITEA_API_URL, GITEA_API_TOKEN, GITEA_ADMIN_USER,
GITEA_WEBHOOK_SECRET, COOLIFY_URL, COOLIFY_API_TOKEN

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-18 14:48:46 -08:00
710a24a2fb feat: rewrite project create to use NextAuth session + Postgres 2026-02-18 01:24:47 +00:00
40bf8428cd VIBN Frontend for Coolify deployment 2026-02-15 19:25:52 -08:00