Commit Graph

10 Commits

Author SHA1 Message Date
41fbed31f3 fix(prod): ESM transpile, healthcheck, hosting UX, settings, error msgs
- next.config.ts: add react-markdown + entire unified/remark/rehype
  ecosystem to transpilePackages — fixes TypeError 'z'/'j'/'aa' prod
  crashes caused by ESM-only packages not being bundled for webpack
- Dockerfile: bake HEALTHCHECK --start-period=60s on 127.0.0.1 so
  rolling deploys pass on first health probe (was failing on ::1 IPv6)
- Hosting tab: full rewrite — live URL chip, copy button, redeploy
  button, inline log viewer, domain list, empty state with prompt
  nudge. Single-card layout replaces master-detail for 1-3 endpoints.
- Settings page: new /project/:id/settings route with danger zone +
  typed "delete" confirmation for project deletion
- Status pill: "View logs" link appears on build failures
- URL chips: collapse extras into "+N more" pill when >2 visible
- Chat errors: structured "Tool error:" prefix; network errors
  distinguished from server errors

Made-with: Cursor
2026-04-30 17:12:48 -07:00
996b875983 feat(project-header): smart status pill + live/preview URL chips
- Status pill derives richer states (Empty / Deploying / Build failed /
  Down / Live) from anatomy with self-polling while deploying
- Tooltip explains what's happening (last build status, transient
  containers, Coolify build phase)
- New ProjectHeaderUrls component renders clickable chips for live
  domains and active dev-server preview URLs to the left of the pill
- useAnatomy gains pollMs option for client-driven refresh

Made-with: Cursor
2026-04-30 13:44:57 -07:00
5ecb0349d7 feat(plan): add Plan tab as the first project surface
A new home for everything that happens BEFORE building:
- Vision    — one-line elevator pitch (mirrors productVision)
- Ideas     — the "park-it" bin for raw thoughts
- Tasks     — what needs to happen next (open / done)
- Decisions — log of "we chose X over Y because Z"

Storage is appended under fs_projects.data.plan so no schema migration
is needed. CRUD lives at /api/projects/[projectId]/plan.

The bare project URL now redirects to /plan instead of /product, and
the AI chat receives decisions + open tasks in its active-project
context block — so it stops re-litigating settled questions and knows
what's queued up.

Made-with: Cursor
2026-04-29 18:02:02 -07:00
7b359e399e feat(infra): collapse to 7 categories + live Postgres table inspection
UX rework after iteration with the user:

  - Drop SMS, Analytics, Search, Monitoring categories from the rail.
    They were detection-only with no first-class UX behind them; surface
    is cleaner without them and they can return when each gets real
    flows (auth-style "edit configurables", payment-style "connect").
  - Storage no longer tries to detect S3/R2/GCS env vars. Instead it
    surfaces the workspace's bundled Vibn-provisioned GCS bucket
    (S3-compatible HMAC), with status, region, access id, and a
    one-shot env snippet for app config.
  - Email category no longer mixes in SMS providers.
  - LLM renamed to "Models"; empty state mentions BYOK as upcoming.
  - Payments empty state has a "Connect Stripe (coming soon)" CTA;
    Stripe detail surfaces the webhook URL guidance.
  - Secrets detail now lists actual env-var key names per resource,
    grouped by detected provider (Stripe block, OpenAI block, etc.)
    with an "Other (project-defined)" catch-all. Each row has Edit +
    Rotate icon buttons (currently disabled with tooltips — wire-up
    to apps.envs.upsert / services.envs.upsert lands in iter 2).

Live database inspection (Postgres only for now):

  - New /api/projects/[id]/databases/[uuid]/tables — auth-scoped, lists
    user-tables across non-system schemas via SSH-exec into the
    database container's psql. Hard caps: 50 tables, 8s timeout, no
    mutating queries possible (only SELECT row_to_json with LIMIT).
  - New /api/projects/[id]/databases/[uuid]/preview — returns first 50
    rows of a single table. Identifiers locked to /[A-Za-z0-9_]+/ so
    splicing them into the SELECT is safe.
  - DatabaseTableTree (lazy-fetch, schema-grouped, public-flat,
    approximate row counts from pg_class.reltuples) and TableViewer
    (sticky-header data grid, zebra rows, per-cell ellipsis at 360px).
  - Fix in lib/coolify.ts: listDatabasesInProject was flattening every
    db endpoint array (postgresqls, redises, mongodbs…) without
    tagging the output rows with the engine. Every consumer was
    seeing type=undefined which then bucketed as "unknown" and
    blocked the table inspector. Now we tag at the flatten step so
    every CoolifyDatabase has a stable type.
  - Infrastructure tab: database tile is now expandable inline like
    Codebases on Product. Auto-expands the first DB; click any table
    to preview rows on the right.

Made-with: Cursor
2026-04-29 15:22:58 -07:00
63f18d46a5 feat(project): wire Infrastructure tab to live Coolify data
Three sub-areas, all real, no static placeholders:

  Databases — listDatabasesInProject(coolifyProjectUuid). Type is
              normalised (postgresql / redis / mongodb / mysql / keydb
              / dragonfly / clickhouse) so the tile subtitle is stable
              regardless of how Coolify spells the engine.

  Providers — auto-detected from env-var keys across every app + service
              in the project. 35+ patterns covering Auth (Clerk, Auth0,
              Supabase, NextAuth, SuperTokens, WorkOS, Firebase Auth),
              Email (Resend, Mailgun, Postmark, SendGrid, SES, Loops),
              SMS (Twilio, Vonage), Payments (Stripe, LemonSqueezy,
              Paddle), Analytics (PostHog, Mixpanel, Amplitude, Plausible,
              Umami), LLM (OpenAI, Anthropic, Google AI, Mistral, Cohere,
              Groq, OpenRouter), Storage (S3, R2, GCS, Supabase),
              Search (Algolia, Meilisearch, Typesense), Monitoring
              (Sentry, Datadog, LogSnag). Each tile drills down to show
              which app/service the keys live in and which keys matched.

  Secrets   — env-var totals per app/service, sorted by count. Values
              are never read or returned from this surface — keys only.
              The detail pane explains how to read/edit (via AI chat
              with services.envs.* / apps.envs.* MCP tools).

Anatomy endpoint extended in the same single-fetch shape: env vars are
loaded once, then both detectProviders() and summariseSecrets() run
against that one source so we don't double-fetch.

The static What-lives-here grid is gone — every tile shown corresponds
to something that actually exists in the project.

Made-with: Cursor
2026-04-29 14:42:23 -07:00
307c3ca858 feat(project): unify Product+Hosting around code/images and live/previews
Anatomy + UI rewrite — locked the conceptual model after user feedback:

Product = "what makes up the thing you're shipping":
  - Codebases (Gitea repos)
  - Images (Coolify services backed by upstream Docker images: Twenty
    CRM, n8n, etc.)
  - Dev containers no longer surface here. The vibn-dev-* container is
    the AI's workshop, not a product surface; previews it serves still
    appear under Hosting → Previews.

Hosting = "where it lives + how it gets there", unified:
  - Live: every running endpoint as one list. Each item carries a
    source badge ("repo" | "image"), status dot, attached domain, and
    last-build summary inline. No separate Build, Domains or Services
    categories — those are properties on each Live item.
  - Previews: dev container preview URLs (unchanged).

Anatomy endpoint reshaped accordingly:
  - product.{codebases, images}
  - hosting.{live, previews}  (was production/services/previewUrls/domains)
  - lastBuild summary fetched per repo-app via listApplicationDeployments
    in parallel.

ProjectStagePill rewired to derive Live/Down/Building from hosting.live
+ hosting.previews. dev-container-detail.tsx removed.

services.* MCP tools added so AI agents can manage Coolify services
(Twenty CRM, n8n, …) the same way they manage apps:
  - services.list, services.get
  - services.start, services.stop
  - services.envs.list, services.envs.upsert
All tenant-scoped via getServiceInWorkspace + getOwnedCoolifyProjectUuids.
vibn-dev-* containers stay hidden from services.list.

Made-with: Cursor
2026-04-28 19:36:35 -07:00
3db7191146 feat(project): split dev containers into Product; convert Hosting to tile-rail
The vibn-dev-* services that the AI authors code in conceptually
belong to Product (build surface), not Hosting (runtime + reach).
Anatomy endpoint now splits Coolify services by name prefix:
  - vibn-dev-* → product.devContainers[]
  - everything else → hosting.services[]

Product tab gains a "Workspace" section above the codebases stack
with a single dev-container tile. Selecting it shows status +
active dev servers in the right pane. Codebase + file selection
behaves the same as before.

Hosting tab restructured from a stack of always-visible cards to
the same tile-rail pattern Product uses: left rail has 4 always-
present categories (Production / Services / Previews / Domains)
each with a count badge, items inside are clickable tiles, right
pane shows details for the selected item. Empty categories show a
one-liner explaining what would appear there — teaches the user
the model on a brand-new project without being preachy.

Made-with: Cursor
2026-04-28 18:54:19 -07:00
6fca78dca9 feat(project): unified anatomy endpoint + live Hosting tab + truthful Live pill
Adds GET /api/projects/[id]/anatomy returning the full project shape
in one shot — codebases (Gitea), production apps (Coolify
applications matched by repo URL), dev services (Coolify services in
the project's coolifyProjectUuid), preview URLs (active fs_dev_servers
rows), and aggregated domains. Each tab reads its own slice via the
new useAnatomy() hook so the page never fans out 3+ requests.

Hosting tab is now real: surfaces production / dev services / preview
URLs / domains with empty-state CTAs explaining what each means and
why it's empty when applicable. Includes a banner when nothing at all
is deployed for the project.

Project header pill (previously hard-coded from data.status, which
historically lied) now derives stage from hosting reality:
  - any production app running → Live (green)
  - any failed app             → Down (red)
  - any service / preview      → Building (blue)
  - else                       → fallback to data.status

Product tab refactored onto the same useAnatomy hook so we no longer
maintain two near-identical fetchers.

Made-with: Cursor
2026-04-28 17:38:57 -07:00
56d4cc36c7 feat(project): IDE-style Product tab — codebase tile expands inline, files preview right
Each codebase becomes its own panel with a header and an expandable
Gitea file tree inside. Clicking any file selects it and renders its
content in the right-hand preview panel (monospaced; no syntax
highlight yet). Single-codebase projects auto-expand the only
codebase on load so the tree is visible immediately.

Tree leaves are now interactive when an onSelectFile callback is
provided; selected rows highlight subtly so the user can tell where
the right pane's content came from.

Made-with: Cursor
2026-04-28 17:08:27 -07:00
69c3a1258c feat(project): Product/Infrastructure/Hosting tab shell with live Gitea preview
Replaces the old two-tile project landing with a tabbed shell anchored
on three sections: Product (codebases), Infrastructure (swappable
services), Hosting (runtime + reachability). Bare project URL
redirects to /product so the founder always lands on the most
actionable surface.

Product tab is the only one wired with real data so far: each
codebase tile is selectable and renders a lazy-loading Gitea file
tree for apps/<codebase>/ in the right column. Both columns share
height + a heading slot so panels stay visually aligned even when
the right side is sparse.

Infrastructure and Hosting are stubs ready for Phase 2 wiring (no
behavioural change vs today). The old (workspace)/infrastructure
route is removed in favour of the new tab; the other 15 sidebar
routes are untouched and still reachable for the migration window.

Made-with: Cursor
2026-04-28 16:37:38 -07:00