Files
vibn-agent-runner/ai-new-thread.md

12 KiB

VibnCode / Master-AI Context Injector

This file serves as a high-density, comprehensive bootstrap guide for any AI Coding Agent starting a new thread in this workspace.


1. System Architecture at a Glance

VibnCode (formerly TalkCody) is a Cloud-Powered Agent Desktop IDE. It functions as a high-fidelity window into cloud-hosted project workspaces, routing file modifications, terminal tasks, and AI session runs to a sandboxed Docker/Coolify VM backend.

graph TD
    subgraph Client [Desktop client - vibn-code]
        UI[React 19 / Monaco Editor UI]
        State[Zustand Stores / SQLite Cache]
        Tauri[Tauri v2 App Wrapper]
    end

    subgraph CloudRunner [Cloud Workspace - vibn-agent-runner]
        Runner[Agent Session Runner Engine]
        Workspace[Sandboxed Project Dir: /workspaces]
    end

    subgraph Infrastructure [Vibnai Platform]
        DB[(PostgreSQL Database)]
        WebAPI[Next.js API Server: vibn-frontend]
        Gitea[(Gitea Git Server)]
        Coolify[Coolify Server Hosting]
    end

    UI <-->|Event Streams & Cloud FS| WebAPI
    WebAPI -->|Route Exec Request| Runner
    Runner <-->|Code Edits & Shell Runs| Workspace
    Runner <-->|Push/Pull/Clone Code| Gitea
    Runner -->|Manage & Deploy Apps| Coolify

2. Directory Structure & Individual Git Repositories

master-ai is a LOCAL development workspace on Mark's Mac. It does not exist in production and is never accessed by any running cloud service. Production runs entirely from the individual Gitea repositories → Coolify builds → running containers on 34.19.250.135. Once a change is pushed to the matching Gitea remote, master-ai is completely out of the picture.

The local master-ai directory houses folders that each map to an independent Gitea repository. The master-ai git repo itself is just a convenience — a single place to commit and track changes across all sub-projects before pushing each one to its own Gitea remote.

DO NOT treat master-ai as a single monorepo on Gitea — it is not deployed as one. You must push changes inside specific directories to their matching Gitea remote targets.

/Users/markhenderson/master-ai/           <-- Local Parent Directory
├── vibn-code/                            <-- Nested Git Repository (Submodule)
│                                             Remote 'origin' -> https://git.vibnai.com/mark/vibn-code.git (main)
├── vibn-agent-runner/                    <-- Subfolder of master-ai. Pushes via:
│                                             Remote 'coolify_agent_gitea' -> https://git.vibnai.com/mark/vibn-agent-runner.git
├── vibn-frontend/                        <-- Subfolder of master-ai. Pushes via:
│                                             Remote 'coolify_gitea' -> https://git.vibnai.com/mark/vibn-frontend.git
├── vibn-api/                             <-- Subfolder of master-ai. Pushes via:
│                                             Remote 'coolify_api_gitea' -> https://git.vibnai.com/mark/vibn-api.git
└── vibn-telemetry-service/               <-- Subfolder of master-ai (Training Data Microservice). Pushes via:
                                              Remote 'coolify_telemetry_gitea' -> https://git.vibnai.com/mark/vibn-telemetry-service.git

Git Remotes Reference (local Mac remotes — these exist only on Mark's machine):

These are git remotes configured in the local master-ai repo. They are the one-way bridge between local development and production. Production Coolify services pull directly from the Gitea URLs; they have no knowledge of master-ai.

Remote Gitea URL What it deploys
coolify_gitea https://git.vibnai.com/mark/vibn-frontend.git vibn-frontend (Next.js platform)
coolify_agent_gitea https://git.vibnai.com/mark/vibn-agent-runner.git vibn-agent-runner
coolify_api_gitea https://git.vibnai.com/mark/vibn-api.git vibn-api
coolify_telemetry_gitea https://git.vibnai.com/mark/vibn-telemetry-service.git vibn-telemetry-service
gitea https://git.vibnai.com/mark/master-ai.git (share-only — coworker local setup; builds do NOT use this)
origin https://github.com/MawkOne/master-ai.git (GitHub mirror only — not used by Coolify)

The full deploy lifecycle:

Local Mac (master-ai)  →  git push <remote> HEAD:main  →  Gitea repo  →  Coolify build  →  Production
         ↑                                                      ↑
  master-ai ends here                                  Production begins here
  1. Make changes in master-ai/vibn-frontend/ (or whichever subfolder).
  2. git commit in master-ai.
  3. git push coolify_gitea HEAD:main (or relevant remote) — this is the complete hand-off.
  4. Coolify detects the push, builds a Docker image from the Gitea repo, and deploys it.
  5. master-ai is no longer involved. Production runs entirely from the Gitea repo + Coolify.

vibn-code is a nested submodule with its own .git — commit & push it via its own origin. Secret .env* files at the repo root are gitignored — never commit them.

⚠️ NEVER use git subtree push for these remotes. Coolify is configured with vibn-frontend as its base directory, so it expects the full master-ai repo structure at the Gitea root and resolves the Dockerfile at vibn-frontend/Dockerfile. A subtree push flattens the repo to just the subfolder contents, making vibn-frontend/ disappear and breaking the build with open Dockerfile: no such file or directory. Always use:

git push <remote> HEAD:main          # normal
git push <remote> HEAD:main --force  # if remote has diverged

Deploying the Telemetry Service manually via Coolify UI:

Because Coolify's API strictly blocks the programmatic creation of GitHub/Gitea Apps, the Telemetry service must be linked manually once:

  1. Open Coolify Dashboard -> vibn-infrastructure -> production
  2. Click + Add -> Application -> Private Repository (with Gitea).
  3. Select vibn-telemetry-service and branch main.
  4. Set Build Pack to Dockerfile and Ports Exposes to 4000.
  5. Under Environment Variables, add DATABASE_URL=postgresql://<user>:<password>@<host>/<database>
  6. Deploy it, then add TELEMETRY_SERVICE_URL=http://<the-new-coolify-url>:4000 to the vibn-frontend environments.

3. Key Tech Stacks & Development Tools

Runtimes & Package Managers (Local Mac)

  • Bun: NOT installed on this local Mac's CLI path. Use pnpm (v10.33.2) or node (v24.1.0) instead.
  • Rust: Fully configured. Built/managed via cargo.

Sub-Project Configurations

A. vibn-code (The Desktop App)

  • Frontend: React 19 + TypeScript + Zustand + Tailwind CSS v4 + Shadcn UI + Monaco Editor.
  • Backend: Tauri v2 + Rust (split into core and desktop workspace members).
  • Startup Command:
    cd /Users/markhenderson/master-ai/vibn-code
    pnpm dev:tauri  # Compiles Rust backend, launches desktop shell, and starts Vite
    
    (To start React web preview only, run pnpm dev)

B. vibn-frontend (The Next.js Web Dashboard & API Bridge)

  • Frontend/Backend: Next.js + PostgreSQL + NextAuth.js.
  • Startup Command:
    cd /Users/markhenderson/master-ai/vibn-frontend
    docker compose -f docker-compose.local-db.yml up -d  # Start local Postgres
    pnpm dev                                             # Start Next.js
    

C. vibn-api

  • Stack: Bun/TypeScript + Drizzle ORM + sqlite/libsql + Wrangler/Cloudflare.

4. The Cloud-Powered Bridge Architecture

VibnCode overrides local OS actions to communicate with your cloud containers (on GCP VM 34.19.250.135 via Coolify/Traefik):

  1. Virtual Filesystem (src/services/cloud-fs-service.ts & repository-service.ts): Monaco & File Tree operations POST to Next.js /api/mcp with actions "fs_tree", "fs_read", and "fs_write".
    • fs_tree returns an ASCII tree parsed by parseAsciiTreeToNodes on the client into UI FileNode trees.
  2. Server-Delegated Run-Loop (src/services/execution-service.ts): Instead of launching local task compilers, the client calls POST /api/projects/:projectId/agent/sessions and initiates a real-time while (isRunning) polling loop against PostgreSQL to pull output lines and stream them to the Monaco chat panel.
  3. SSO Authentication Loop (vibncode:// Custom Scheme): OAuth logins redirect from Gitea back to vibncode://auth/callback?token=....
    • Important: This scheme is registered in macOS via vibn-code/src-tauri/Info.plist (updated and verified).
    • Relaunching/recompiling the app (pnpm dev:tauri) registers vibncode:// with Launch Services, enabling local SSO redirects.

5. Development Guidelines & Safety Nets

  1. Rust Clippy Warnings are treated as Errors: The pre-commit hooks will fail commits if cargo clippy warnings exist.
    • Unused structs: Annotate with #[allow(dead_code)].
    • Nested matches/ifs: Collapse nested if statements into outer match arms using pattern guards (e.g. ContentPart::Text { text } if !text.trim().is_empty() => { ... }).
  2. Commit Bypasses: If blocking cargo file locks (Blocking waiting for file lock on build directory) occur because the app is running, stage your changes and commit using --no-verify to bypass pre-commit compilation:
    git commit -m "commit message" --no-verify
    
  3. Push to Individual remotes (the ONLY way changes reach production): Commit in master-ai, then push the relevant subfolder's remote. Production never reads from master-ai directly — the push to Gitea is the complete hand-off.
    git push coolify_gitea HEAD:main           # deploy vibn-frontend
    git push coolify_agent_gitea HEAD:main     # deploy vibn-agent-runner
    git push coolify_api_gitea HEAD:main       # deploy vibn-api
    git push coolify_telemetry_gitea HEAD:main # deploy vibn-telemetry-service
    

6. Where We Left Off (As of May 31, 2026)

Read VIBNCODE_THIN_CLIENT_CHANGES.md first — it is the live, prioritized change list with exact files, steps, and acceptance criteria for the thin-client conversion, plus a STATUS section of what's done.

Chat works end-to-end. A desktop message → POST /api/projects/:id/agent/sessions → cloud runner executes the Coder agent (Gemini) → output polled back into the Monaco chat. Recent fixes that got it there:

  • Local SQLite was wiping chats (fixed): database-service.ts used INSERT OR REPLACE INTO projects, which (via ON DELETE CASCADE) deleted the active conversation mid-run. Switched to UPSERT; made task-service persistence non-blocking. The cloud is the source of truth; local SQLite is just a cache.
  • Empty appPath broke every run (fixed): the desktop sent appPath: ""; the runner's /agent/execute rejects falsy appPath with HTTP 400 and does nothing (no logs). Desktop now sends appPath: ".".
  • Agent tools fetch failed (fixed, pushed): the runner's buildContext() hardcoded vibnApiUrl: 'http://localhost:3000' and an empty mcpToken, so tool calls fetched a dead port. Now /agent/execute reads mcpToken from the body and sets ctx.vibnApiUrl (from VIBN_API_URL) + mcpToken. Pushed to coolify_agent_gitea/main — confirm the runner redeploy.
  • Single model: desktop model picker restricted to the VibnAI model, relabeled "Gemini 3.5 Flash". The runner's real model is set by GEMINI_MODEL env (currently gemini-3.1-pro-preview); the desktop label is cosmetic until model-passthrough is wired (CHANGE 4.1 in the change doc).

Known open items (in the change doc): the desktop still has a hardcoded vibn_sk_ API key to remove; /agent/sessions/:id/stop returns 401 to the desktop (uses browser-session auth, not the workspace key); runner early-failures are silently swallowed (failure PATCHes omit the x-agent-runner-secret header).

Earlier (still true): vibncode:// deep link scheme is registered in src-tauri/Info.plist; Rust clippy is treated as errors on commit.