Skip to content

Changelog

What's new in Vulcan. Most recent changes first.


May 2026

Device share passcode — warehouse TVs and other shared displays

A new way to sign many devices into a Vulcan app using one 6-digit code. Built for warehouse TVs, kiosks, and any browser-only device that can't enroll a passkey (no biometric sensor, no good keyboard).

  • Owner mints a 6-digit passcode from the Access page → Device share passcode section. The passcode + the app URL are shown once, then only the SHA-256 hash is persisted on the server.
  • On each device: operator visits the production (or preview) URL, gets redirected to a passcode-entry page on the gateway, types the 6 digits once, the device stays signed in for 30 days.
  • Per-device cookie is path-scoped to the one app it was minted for — a leaked URL can't reach other apps the warehouse display has no business seeing.
  • Rate-limited: 10 attempts per IP per hour. 1 million combinations × throttling ≈ 11 years to exhaust the space, brute-force-safe for floor-visible content.
  • Rotation invalidates the URL channel without kicking active TVs offline — already-paired devices keep working until their cookie expires. To force every device off: Revoke + Mint.
  • Same passcode works for both production and preview URLs — handy for verifying a fresh deploy on a TV before flipping prod, no extra mint required.
  • Login-CSRF guarded: the claim endpoint rejects cross-origin POSTs.

Companion primitive to the existing per-person passkey flow — passkeys for individuals on personal devices, passcode for many devices sharing one identity. → Partner Access guide

Production hardening — Waves 1 through 4

A four-wave hardening pass landed in May to take api and graphql-api apps from "works fine internally" to "ready for external consumers". Every wave shipped to the immutable platform layer (src/api/_platform.ts) so existing apps inherit the new behavior on their next deploy without touching handlers.ts.

Wave 1 — observability (Tier 2: per-key usage stats + rate-limit headers + audit log)

  • Per-key usage counters in KV (one row per kid per hour). The playground key table now shows last-24h and last-7d traffic per consumer so you can spot drift before a customer complains.
  • Every response carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset — clients can self-throttle instead of waiting for a 429.
  • Append-only audit log captures key mints / rotates / revokes (last 100 entries). Read it from the playground's Activity tab.

Wave 2 — scope enforcement + self-service docs (Tier 2: per-route scopes + auto-generated developer docs)

  • Mint keys with explicit scopes: ['items:read', 'admin:*'] and gate routes by declaring vulcanScopes on the createRoute definition. Routes without the field stay open. The admin:* prefix wildcard satisfies any required scope.
  • New platform routes GET /api/docs (Swagger UI from a pinned CDN), GET /api/postman.json (v2.1 collection), and GET /api/client.ts (TypeScript client). All three gated like /api/openapi.json so consumers can self-onboard by importing the URL.

Wave 3 — idempotency + webhook signing (VBE-109)

  • Idempotency-Key header support on every POST/PUT/PATCH/DELETE. The first request runs the handler and caches the response; retries within 24h replay it with X-Idempotency-Replay: true. Bucketed by kid + method + path + key so different consumers don't collide.
  • HMAC-SHA256 webhook helpers (signWebhook, verifyWebhook) usable from any handler — Stripe/Svix-compatible signed payload (${timestamp}.${body}), 5-min replay window, timing-safe signature compare, structured failure reasons.
  • → System prompt teaches the agent to wrap mutating routes with checkIdempotency and to use the canonical webhook helpers instead of hand-rolling HMAC.

Wave 4 — external-IdP JWT verification (VBE-110)

  • New jwt-bearer integration component for apps called by partners with their own IdP (Auth0, Cognito, Okta, custom OIDC). Validates RS256/ES256 signatures via the issuer's JWKS (cached per-isolate for 10 min), checks iss/aud/exp/nbf with 30s clock skew, exposes verified claims on c.var.jwt.
  • Scope claim is extracted from both scope (space-separated string, OAuth standard) and scp (array, Microsoft/Okta convention) — integrates with the same requireScopes gate used by API-key auth, so JWT-authenticated callers pass the same per-route scope check.
  • HS256 is intentionally rejected (alg-confusion CVE prevention). For self-issued HS256 tokens, use the existing jwt-auth component instead.

Source referencesvulcan-ide/src/templates/base-scaffold.ts (idempotency + webhook helpers, scope enforcement, audit log, usage counters, rate-limit headers, docs routes), vulcan-ide/src/templates/components/integration/jwt-bearer.ts (Wave 4 component), vulcan-ide/src/templates/app-templates/api.ts (canonical idempotency wiring on POST /api/items).

Operational debt — CI flake retry + explicit docs deploy + validator hardening

Background cleanup that doesn't change customer behavior but reduces friction for the team.

  • CI miniflare retry — the recurring SocketError: other side closed on the workers pool shutdown now triggers a single bash-level retry with a 10-minute per-attempt timeout, so a flake costs one rerun instead of a manual gh run rerun.
  • Explicit docs deploy job — the CF Pages deploy for vulcan-platform.pages.dev now runs from GitHub Actions on push to main when docs/** changes, replacing the dashboard's GitHub integration which had been observed to occasionally skip auto-builds.
  • Deploy validator now tolerates barrel filesexport * from './foo' no longer trips the import/export consistency check. Plus regression tests for named re-exports, default as re-exports, and multi-line export brace groups.
  • Dead-code cleanup — removed flags-middleware (built but never wired) and worker-analyzer (no production callers).

Docs — partner passkey sign-in (partner perspective)

The owner-side guide for Partner Access explains how to add partners to your app. The new Partner Passkey Sign-In page is written for the partner — the person clicking the invite link. Share it with anyone you invite from outside Veho.

  • End-to-end walkthrough — what the invite link does, what to expect from the biometric prompt, what the chooser page (/auth/select) looks like on return visits.
  • Cross-device behaviour — how passkeys sync (or don't) on iCloud Keychain, Google Password Manager, 1Password, Windows Hello.
  • Recovery — what to do when an invite link is expired, a device is lost, or a password-manager extension is intercepting the prompt.
  • Source referencesvulcan-ide/src/api/guest-routes.ts, vulcan-ide/src/auth/passkey.ts, vulcan-ide/src/auth/guest-invite.ts, vulcan-ide/src/auth/session.ts.
  • Partner Passkey Sign-In

Docs — building API-only apps

Vulcan has had first-class support for pure JSON APIs since the api and graphql-api templates shipped, but the workflow wasn't documented end-to-end. The new API-Only Apps guide ties it together.

  • Template intro — what use_template('api') (and graphql-api) generates, and when to skip the template and just describe the API in chat.
  • X-API-Key auth — how the key is generated, where it's shown (once, at deploy time), and how to rotate it via the rotate_api_key chat tool. Clarifies that INBOUND_API_KEY_HASH is Nox-managed and users should never set it directly.
  • OpenAPI 3.0 specGET /api/openapi.json is auto-served and gated behind a Vulcan session OR a valid X-API-Key. Includes guidance on editing buildSpec() in src/api/spec.ts when you add endpoints.
  • Calling the API — copy-pasteable curl examples for list, create, and spec-fetch.
  • GraphQL alternative + CORS — covers the graphql-api template and CORS_ALLOWED_ORIGINS configuration.
  • API-Only Apps

Partner Access — let non-Veho users into specific apps

Apps can now be opened to specific partner emails (DSP admins, vendors, contractors) on a per-app basis, without giving them access to Vulcan IDE or any other app on the platform.

  • Access button in the App Builder toolbar (next to Team) opens the per-app access manager.
  • Add partner emails to the allowlist — must be non-@shipveho.com.
  • Generate a single-use invite URL — Vulcan returns a signed URL valid for 24 hours. Send it via Slack/email; the partner clicks it and enrolls a passkey (Touch ID / Windows Hello / phone biometric).
  • Phishing-resistant by design — partners sign in with passkeys cryptographically bound to vulcan.shipveho.com. No passwords, no third-party identity providers, no @shipveho.com accounts to provision.
  • Per-app isolation — a partner allowlisted on App A can't reach App B, App C, the IDE, or anything else. The allowlist applies to both your preview and production deploys symmetrically.
  • Owner-managed — only the project owner can add/remove partners or revoke enrolled passkeys.
  • Partner Access guide

Frontend scripts load in global scope (no ES modules)

app.js and all other frontend files are now loaded as plain classic scripts rather than ES modules. This fixes a class of errors where inline event handlers (onclick=, oninput=, etc.) couldn't find their functions because ES module scope isolates declarations from the page.

  • What changed — every app template's index.html now uses <script src="app.js"> instead of <script type="module" src="app.js">.
  • What it means for your app — functions defined in app.js are global. You don't need window.myFn = ... assignments for inline handlers. For large apps with multiple JS files, the AI uses separate <script> tags in dependency order instead of import statements.
  • No import / export in frontend files — ES module syntax no longer works in frontend JS. If your app uses it and breaks after this change, ask the AI to rewrite the affected files using plain global functions.
  • Frontend files reference

First-class API support

Vulcan can now build and deploy public-facing REST and GraphQL APIs — callable by any external client without a Vulcan session.

  • api template — production-ready REST API with KV-backed CRUD, an interactive playground at GET /, and a self-describing API docs page. Ask Claude: "build me a REST API for managing inventory items".
  • graphql-api template — GraphQL API with KV-backed resolvers and a built-in GraphiQL explorer at GET /graphql. Ask Claude: "build me a GraphQL API for querying products".
  • Vulcan-managed API keys — a secure 64-character key is generated at deploy time and shown once in chat. Callers include it as X-API-Key. No secrets to manage — Vulcan handles provisioning and rotation.
  • Automatic CORS — public APIs get CORS headers injected at the gateway. Configure allowed origins per-app via a CORS_ALLOWED_ORIGINS environment variable.
  • New componentsapi-key-auth, jwt-auth, and cors-config are available as reusable components for any app that needs them, not just the API templates.
  • Template catalog — APIs
  • Integration components — Auth

April 2026

Google login replaces Cloudflare Access

Vulcan now uses its own Google OAuth login instead of Cloudflare Access.

  • Sign in with Google — visit vulcan.shipveho.com and click "Sign in with Google". Only @shipveho.com Workspace accounts are accepted.
  • Session persists across Vulcan and your apps — logging into Vulcan once also authenticates you to all your deployed apps on nyx.shipveho.com. No separate login needed.
  • Your apps are still Veho-internal only — the Nyx gateway enforces that all app traffic requires a valid Vulcan session before reaching your app.
  • No changes needed to your app code — the getUser() helper and Cf-Access-Jwt-Assertion header your apps already use continue to work exactly as before. The gateway now injects these on every authenticated request.

Google Calendar integration

  • google-calendar component is now fully functional — the OAuth relay previously only requested Sheets, Docs, and Drive scopes. Calendar access (https://www.googleapis.com/auth/calendar) has been added so Calendar API calls actually succeed.
  • renderCalendarPicker(containerId, onSelect) — renders a dropdown of the user's Google Calendars, similar to how renderSheetSelector works for Sheets.
  • renderEventList(containerId, events) — renders a styled list of calendar events as cards, handling both timed and all-day events automatically.
  • Reconnect notice — users who connected their Google account before this change will need to reconnect once to grant Calendar access. The "Connect Google Account" button in any Google-integrated app handles this.
  • Integration components reference

Veho Data Proxy — KV-backed source catalog

  • Sources are now managed without a code change or deploy — the Platform team can add, update, or point sources at different environments (dev, staging, prod) directly from /admin/veho-sources. Entries stored in KV take effect immediately and override the static catalog.
  • Multi-environment support — register separate named sources (e.g. supergraph, supergraph-staging) and Vulcan apps call the specific source they need. No deploy required when switching endpoints for IAM-role sources.
  • /admin/veho-sources page — new admin UI showing all registered sources with auth type, endpoint, and credential details. KV entries are fully editable and deletable; static catalog entries can be overridden by adding a KV entry with the same name.
  • Veho Internal APIs guide

Admin: research session management

  • /admin/research page — new admin page that lists all research sessions across all users, searchable by owner email, title, or session ID. Shows message count, findings count, document count, created/updated dates, and a delete action per session.
  • GET /api/admin/research — lists all sessions with counts. DELETE /api/admin/research/:sessionId — deletes a session and all its associated data (chat, findings, documents, member pointers).

Admin: stuck-lock management

  • /admin/locks page — new admin page that scans for all active chat locks across projects and research sessions. Shows a live table of stuck locks with a one-click Clear button per row. Also includes a manual-clear form for when you know the project or session ID from a user report.
  • Force-clear APIDELETE /api/admin/projects/:projectId/locks clears the project-scoped lock (the one that blocks new messages with "already in progress") plus every member's per-user rate-limit slot. DELETE /api/admin/research/:sessionId/locks does the same for research sessions. No deploy or code change needed.
  • Troubleshooting doc updated — added a "project is stuck" entry to Common Issues explaining the lock TTL, when to wait vs. when to call an admin.

Platform

  • Test isolation — vitest now runs two separate pools: a Node pool for pure-TypeScript tests (no miniflare overhead, full per-test isolation) and a CF workers pool for everything else. The workers pool uses a test-only wrangler config without Workflow bindings, which unlocks isolatedStorage: true — each test file gets its own fresh KV namespace instead of sharing state.

March 2026

Rock-solid deploy → preview → debug loop

Several fixes that together prevent the agent from re-running the same fix in a loop due to stale or misleading error signals:

  • Preview always refreshes after deploy — after "Deployed to preview" the preview iframe now reliably reloads with the new code. Previously, a synchronous src overwrite in deployCompleteCallback cancelled the cache-busted navigation that __setSandboxUrl had just set, causing the browser to ignore the reload and show stale content.
  • Stale errors cleared at deploy time — runtime JS errors captured from the old preview page are now cleared the moment the iframe starts navigating to the new URL, not just after it finishes loading. This closes the window where the chat input re-enables (on "Deployed to preview") before the new page has loaded, which previously caused pre-deploy errors to be appended to the user's next message.
  • Error deduplication — the same runtime error is now stored at most once in the preview error buffer. Previously, an error firing on every animation frame (e.g. a canvas loop) would fill all 20 slots with identical entries and flood the agent's context.
  • Auto-debug counter resets per turn — the 2-retry cap on __autoDebugDeploy now resets at the start of each new agent turn. Previously it was per-page-load, meaning two failed deploys in one session permanently silenced auto-debug for the rest of the session.
  • Auto-debug includes the actual error__autoDebugDeploy now passes the specific error message and a truncated build log to the chat turn it fires, replacing the generic "The preview deploy failed" string so the agent has the right context immediately.

Team activity feed

All members of a project can now see what everyone else has been building. Click Activity in the chat panel header to open a slide-in feed showing every member's turns with Vulcan — who asked what, what Vulcan responded, and when. Each entry shows the member's initials, username, and a summary of the exchange. Your own chat thread works exactly as before; the activity feed is a shared read-only view on top of it. Capped at the 100 most recent turns.

Version history in the chat panel

A History button in the chat panel header opens a slide-in version list directly in the chat — no need to navigate away. Each version shows its name, date, and file count. Click Restore to revert to that version; Vulcan auto-saves your current state first so you can always undo the rollback.

Retry button on AI responses

After every completed response, a small ↺ Retry button appears at the bottom of the message. Click it to re-send the same prompt and get an alternative take without retyping. The button clears when you start a new message.

Message timestamps

Every message now shows a time label next to the sender name — time of day for same-day messages, date and time for older ones. Makes it easier to correlate changes with when they happened.

File and document uploads in chat

You can now attach files to the project chat the same way you can in Research sessions. Click the paperclip icon in the chat input area and attach PDFs, plain text, HTML, Markdown, CSV, JPEG, PNG, WebP, or GIF files (max 10 MB each, up to 10 files per project). Attached documents appear as chips above the input and are injected into Claude's context on every turn — useful for specs, schemas, reference data, or design screenshots. Files persist across sessions until you remove them.

Research graduation carries documents

When you graduate a Research session to a project, any documents attached to the session are now included in the AI-generated project brief. PDFs, images, and text files from the research context all flow into the first-turn prompt so the App Builder has the full picture from day one.

Task visibility panel

The Tasks tab in the workspace now shows what the AI is working on in real time. For any multi-step request — anything touching more than two files or requiring more than one logical step — the AI posts its full work plan at the start of the turn with all tasks marked "pending", then updates each task to "in progress" and "done" as it goes. The panel auto-switches into view the first time the AI posts tasks so you can follow along without clicking anything. Clears when you send a new message.

Per-project standing instructions

Owners and editors can now set a persistent instruction block for each project in Settings → Standing instructions (up to 2000 characters). The instructions are injected as a system-level prompt on every chat turn — so the AI always applies your project's rules without you having to repeat them each session. Useful for enforcing color schemes, protecting specific parts of the codebase, defining output formats, or encoding any other project-specific conventions. Cleared by saving an empty field.

Unified share modal

  • Share and Team modals now use the same component — the invite link UI in the Research Workspace (Share modal) and the App Builder (Team panel) is now backed by a single shared component. Both surfaces show a member list, a role picker, a Generate Link button, and a URL text box — no more browser prompt() dialog for copying the link in the IDE. The invite link is auto-copied to the clipboard when generated, with a Copy button available as a fallback.
  • The Research modal remains read-only (member role changes and removal are owner-only, coming in a future update); the IDE Team panel retains full member management (role-change dropdown, remove button).

Research Workspace — viewer role

  • Viewer role is now live — Research session viewers see a fully read-only UI: chat input is disabled, the attach button and documents "+" button are hidden, the session title is non-editable, and the Share / Delete / Graduate controls are not shown (owner-only). The "coming soon" label has been removed from the Viewer option in the share modal.
  • GET /research/:id now returns userRole (owner | editor | viewer) so the frontend can apply access controls based on the actual role rather than re-deriving it from session metadata.
  • All write endpoints already enforced viewer restrictions server-side (chat, rename, upload, document delete); the UI now matches.

Research sessions — shared by default

  • Every research session is now shareable — sessions use a shared KV namespace (research:{id}:*) from the moment they're created. No migration or opt-in required for new sessions
  • Share button in Research chat — the session owner sees a Share button in the chat header. Click it to open the share modal, choose a role (Editor / Viewer), generate a single-use invite link (48h expiry), and copy it to the clipboard
  • RolesEditor can chat with the AI; Viewer is read-only. The owner retains full control (chat, graduate, delete, member management)
  • Shared chat thread — all session members see a single conversation thread; messages from any member are visible to everyone
  • Member list — the Share modal lists current members and their roles
  • Owner-only operations — delete and graduate are restricted to the session owner
  • One-time migration — existing sessions were migrated automatically via POST /api/research/migrate-to-shared; the chat, findings, and documents are preserved exactly

Team collaboration

  • Every project is now a shared project — all new projects support team collaboration out of the box. No separate "shared project" type; the Team button is always available to project owners
  • Invite teammates — owners can generate an invite link (48h expiry) from the Team panel in the IDE header and share it with any Veho employee. The link auto-accepts and drops the invitee directly into the project
  • Role-based access — three roles: Owner (full access + team management), Editor (can chat with AI, view files), Viewer (read-only)
  • Concurrent session guard — only one AI session can run at a time per project, preventing two members from clobbering each other's file writes simultaneously
  • Manage your team — change member roles or remove members from the Team panel at any time

Landing page redesign

  • Two clear starting paths — the Vulcan home page now presents two options side by side: Research first (opens the Research Workspace to clarify requirements before coding) and Start building (opens the Project Workspace to jump straight in)
  • Removed the prompt text box from the landing page — both options are one-click buttons

Research Workspace — always on

  • Research Workspace is now available to all users — removed the RESEARCH_ENABLED feature flag; /research is always accessible with a permanent link in the project hub nav bar
  • Previously required an admin to set RESEARCH_ENABLED=true in wrangler config

Plan mode removed

  • Removed plan-first mode — the "Plan first / Build directly" toggle has been removed from the landing page, project hub, and chat interface
  • The Research Workspace is the recommended way to clarify requirements before building — it's more structured, persistent, and produces a proper project brief
  • No action needed: any saved vulcan_plan_first preference in localStorage will simply be ignored

Bug fixes

  • Fixed: newly created projects not appearing in the project hub — project metadata and the member-list index were written in a background waitUntil task. If the subsequent GET /projects request was routed to a different Cloudflare edge node, KV eventual consistency meant the new keys weren't visible yet and the project list appeared empty. Metadata and member pointer are now written synchronously before the 201 response; only file writes and preview deployment remain in the background

Role enforcement hardening

  • Fixed: viewer role now blocked from starting AI chat sessions — viewers could previously trigger chat requests, consuming compute and potentially writing files they had no edit access to. The API now requires at least Editor role to initiate a chat session
  • Fixed: production deploys now restricted to project owners — the explicit /deploy endpoint previously allowed any Editor to promote a production release. Production deploys now require the Owner role; preview deploys remain available to Editors
  • Fixed: shared project files, versions, and cron registry writing to the wrong KV namespace — chat persistence, deploy snapshots, cron registry, and project metadata were being written to the personal (u:{userId}:*) namespace for shared projects. All writes now correctly route to the shared (shared:{projectId}:*) namespace via ScopedProjectRepository

Agent reliability

  • Fixed: false "Undeclared env bindings" error on all new projectsverify_build's env-binding check was running its regex against the full file content, including comments. The base scaffold's data.ts contains section header comments that mention env.DB, env.BUCKET, and env.KV (e.g. "access via env.BUCKET"). This caused a false positive on every new project that hadn't provisioned a database or file storage. The validator now strips single-line comments before checking
  • Fixed: false "Undeclared env bindings" error when creating a datasourceverify_build runs in Phase 1b (after file writes), but create_datasource runs in Phase 2. When both were called in the same AI turn, the env-binding check fired before the binding was added to wrangler.toml — always producing a false failure. The check is now skipped when create_datasource is in the same round
  • Fixed: preview showing "Deploying..." indefinitely on new projects — a race condition between the metadata fetch and the chat SSE stream could cause the seed deploy poll to cancel the chat deploy poll and lose its completion callbacks. A __chatDeployInProgress flag now guards the seed poll from firing while a chat deploy is active
  • Fixed: scaffold overwriting AI-generated app on new projects — for projects created with a prompt, the background seed deploy (scaffold files) could complete after the AI had already deployed the full template, overwriting the app with placeholder files. The seed deploy now checks whether the AI has already deployed before pushing to Nox
  • Fixed: "build has failed multiple times" on new project creation — the import path validator was incorrectly flagging src/index.ts (a platform-internal file that imports a build-time virtual module). The validator now skips immutable platform files
  • Fixed: misleading "Deployed to preview" after a build failure — the agentic loop now tracks why it stopped; if it exits due to repeated build failures, the deploy step is skipped so users no longer see a deploy success message for code that never built
  • Fixed: Tasks tab blank even though badge showed a count — the task panel's window.__updateTaskPanel function used escapeHtml() to render task descriptions, but escapeHtml was only defined inside the chat component's IIFE — not in scope when the task panel code ran. This caused a ReferenceError that was silently swallowed by the SSE parser's try/catch. The badge count was set before the error, so the badge showed the right number, but tasksList.innerHTML was never assigned. Fixed by adding a local escapeHtml helper in the task panel IIFE
  • Fixed: chat lock held indefinitely after an inactivity timeout — when the 120s inactivity timer fired, finishStream() nulled streamAbortController without calling .abort(). The in-flight fetch stayed open, the Worker never received a disconnect signal, and the 30s lock-refresh interval kept the chat lock held indefinitely. Clicking Retry immediately returned a 409. The fix calls streamAbortController.abort() in finishStream() before nulling it, propagating the signal to the Anthropic stream and causing the agentic loop to exit cleanly
  • Fixed: Research chat hanging indefinitely on a stalled connection — the Research Workspace SSE stream had no timeout. A stalled connection would hold the page open forever with no error and no way to retry without a full reload. The same 120s inactivity timer pattern from the App Builder is now applied: an AbortController is passed as the fetch signal; the timer resets on every received chunk and fires after 120s of silence, aborting the fetch and showing "Response timed out. Please try again."

Canary users & feature flags (admin)

  • Canary user list — admins can now designate specific users as canary testers at /admin/canary without a deploy. The list is stored in KV (canary:users) and takes effect immediately. Add or remove users from the new admin page.
  • Feature flag system — in-progress features can be gated by a named flag in src/utils/flags.ts. Each flag has a rule: 'canary' (canary users only), 'all' (full rollout, no deploy needed), or a hardcoded email list for closed betas. Check flags in any route with await isEnabled('flag_name', email, env.PROJECT_FILES).
  • Admin Canary page — new /admin/canary page shows all defined flags and their current rules (static), plus a live canary user list with add/remove controls. Linked from the admin nav.

Research Workspace

  • New: Research Workspace — a dedicated space for clarifying requirements before writing code. Chat with an AI analyst at vulcan.shipveho.com/research to define the problem, identify users, map data, and surface open questions — without touching the App Builder
  • Findings sidebar — the AI automatically saves structured findings (requirements, open questions, data-model entities, insights) to a persistent sidebar as you chat
  • URL fetching — paste any public URL in the chat and the AI reads the page content before responding
  • Document upload — attach PDFs, text files, CSVs, Markdown, and images as context; documents are injected into every subsequent turn so Claude has full access
  • Graduate to project — click Start Building to generate a project brief from your session and create a new App Builder project pre-seeded with everything the AI learned
  • Delete sessions — remove sessions (and all associated documents) from both the hub and the individual session page
  • Research Workspace guide

App copy

  • Copy any app to another user — hover a project card and click the copy icon to send a full copy of your app to any Veho email address
  • The recipient gets all files and metadata; secrets and database data are not copied (they can't be — secrets are stored encrypted and database content belongs to the original app)
  • When the recipient opens the copied app, the AI automatically prompts them to re-enter any required secrets before making other changes

App Catalog

  • Public app listing — list your app in the Vulcan App Catalog so other Veho employees can discover and copy it
  • Auto-generated tags — when you list an app, Vulcan automatically generates descriptive tags in the background using AI
  • Browse and copy catalog apps from the homepage

CSS design system

  • CSS variable design systemstyles.css now ships with a full set of CSS variables (--color-*, --spacing-*, --radius-*, etc.) that components share for visual consistency
  • Build-time CSS validationverify_build now checks that every var(--foo) reference in styles.css has a matching --foo: definition in :root, catching typos before deploy

Background jobs — queue-based dispatch

  • Automatic retries — Failed cron jobs are now retried automatically up to 3 times with a 60-second delay between attempts
  • 30-second wall-clock limit — Cloudflare's subrequest timeout for Worker-to-Worker calls; CPU time (excluding I/O await) has the same 30-second cap
  • Improved reliability — Cron dispatch now uses Cloudflare Queues internally, decoupling scheduling from execution so a slow or failing job never blocks the next tick
  • Better logging — Every cron tick, enqueue, dispatch attempt, and retry is now visible in the Cloudflare console with structured JSON logs

New integrations & templates

  • Twilio, Airtable, Databricks, Metabase integration components added — connect to these services just by describing what you want
  • BYOK (Bring Your Own API Key) — add your own Anthropic API key in Vulcan Settings to use your own quota
  • Developer Productivity Dashboard added as a homepage suggestion and template — GitHub PRs, Linear issue velocity, New Relic error rates, and PagerDuty incidents in one view

Improvements

  • Stop button — cancel an AI turn mid-response if it's going in the wrong direction
  • All 51 app templates updated — background job scheduling now works correctly in every template
  • Homepage suggestion chips updated with more Veho-specific starting points

Docs

  • New docs site launched at vulcan.shipveho.com/docs
  • Getting started guides, template catalog, component reference, and troubleshooting
  • FAQ, limitations, and prompt writing guides added

February 2026

New components

  • Google Sheets — connect via OAuth, view and append rows to any sheet
  • Receipt Scanner — upload a photo of a receipt and have AI extract vendor, date, total, and line items automatically
  • Document Intelligence — AI-powered document library with field extraction and semantic search
  • Delivery Hub — full-featured delivery operations dashboard with live route map, bulk actions, status stepper, and proof-of-delivery signature capture

Improvements

  • Console Logs tab added to workspace panel — captures frontend JavaScript logs as you interact with the preview
  • Server-Sent Events (SSE) support — stream live progress updates from backend to browser
  • Improved template matching — Vulcan more accurately selects the right template based on your description

February 2026

Platform MVP

  • Vulcan launched internally to Veho employees
  • AI-powered app builder with live preview and one-click deploy to production
  • 48 app templates across task management, business ops, logistics, AI-powered tools, and more
  • Key-value storage, SQL database, and file storage — provisioned automatically
  • Cloudflare Access integration — every app is automatically Veho-employee-only
  • Background jobs — schedule recurring tasks with plain English descriptions
  • Versions & rollback — save named snapshots and restore with one click
  • Integration components: AWS, New Relic, PagerDuty, Linear, GitHub, Google OAuth
  • UI components: charts, maps, tables, modals, file upload, signature capture, and more
  • AI components: text summarizer, image analyzer, embeddings, knowledge base Q&A

Built by the Veho Developer Platform team