BeatDesign is a single-user creative application. It has no account boundary and no SaaS commerce layer.
Projects
+ Home
+ Studio
+ Canvas
+ Editor
+ Assets
+ Generation history
+ Provider configuration
+ Storage configuration
Studio, Canvas, Editor, and Assets are views over the same project, generation, asset, and history services. Switching modes never creates a second project or backend.
The shared product model is asset-first:
- A generation creates an
Asset; it does not own a single UI placement. - A Canvas node references an Asset, Generation, or Timeline.
- A Timeline clip pins a concrete Asset and never silently follows a Canvas generation's latest output.
- A Take is an alternate Asset for one clip; the original source remains recoverable.
- Canvas edges describe visual organization. Generation lineage describes real derivation and is stored separately.
The browser calls local /api routes. Server routes validate input and resolve a logical model through the active Generation Provider contract. BeatAPI is the built-in/default provider; forks can register another source-level provider without changing Canvas, Editor, MCP, or the asset-first request contract.
BeatDesign does not implement account concurrency policy. Projects may submit generations independently, and the active Generation Provider is the sole authority for account-level admission. The local submission lock protects SQLite intent/history consistency only; it does not reserve a long-running generation slot or reject a different Project because another task is active.
Provider and optional R2/S3 credentials are encrypted in the local config table. Browser components never receive raw credentials. Shared model metadata may read Provider bindings, but Provider adapter construction, configuration checks and input validation are wrapped in TanStack createServerOnlyFn; the browser dependency graph must not import local configuration or SQLite.
Upload storage is a separate adapter boundary. File selection remains browser-local. A successful generation precheck creates a short-lived, one-time SQLite intent that binds the project, model, exact upload count, uploaded URLs, and final generation submission. Required references are promoted only after that point and immediately before task submission; they become project assets only after the provider accepts the task. The default path uploads supported references to BeatAPI Files. Users may instead configure a public R2/S3-compatible bucket; those credentials remain local and are used only for confirmed generation inputs.
Production browser requests accept only localhost, IPv4 loopback and IPv6 loopback
authorities, independently of Origin. pnpm start and the WorkBuddy launcher pin
the listener to IPv4 loopback; ambient hosting variables cannot widen it. Packaged
DDL and migration receipts commit atomically and tolerate prior additive startup
upgrades without rewriting user records.
Project organization uses this same boundary. Canvas v4 stores canonical groups,
fixed reference bindings and frozen template instances alongside unchanged cards
and absolute frames. Display projections never replace raw references or historical
input snapshots. Per-project folders and Elements live in
project_organization_state; installation-wide definitions live in workflow_template.
New semantic writes require explicit revisions and stable IDs. An asynchronous
transaction context keeps service reads, CAS updates and request-fingerprinted
receipts on the same SQLite transaction, including legacy snapshot save paths.
Each transaction owns a dedicated client, commits or rolls back explicitly, then
closes it in finally; unrelated readers keep their separate connection. This
avoids detached native handles remaining open until garbage collection.
Canvas generation intents additionally pin the reviewed source card/configuration
digest. See Project organization.
UI actions and the local MCP server call the same Command Kernel. The kernel owns validation and pure document operations for Canvas and Editor. Persistence boundaries remain responsible for revision checks, durable writes, and returning the authoritative document.
UI / MCP
|
Command envelope + validation
|
Canvas / Editor / Generation commands
|
revision-checked project persistence
|
SQLite + project media files
MCP does not write SQLite directly or replace an entire Canvas or Timeline document. Its tools call persistBeatDesignCommand with a transport-controlled origin=mcp. The public UI route assigns origin=ui server-side and rejects an origin request field. UI-only timeline replacement exists for local autosave and undo/redo, remains revision-checked, and is rejected for MCP origins. Generation commands are asset-first and intentionally have no placement field; the server compiles provider media URLs from project-owned Asset IDs and the one-time generation intent before submission.
External incremental Canvas and Editor commands use a bounded conflict-recovery wrapper around the same persistence function. If the final CAS write loses a short race to UI autosave, the wrapper reloads the authoritative document and reapplies the same stable-ID operation at most twice. It never retries full-document replacement. Persistent conflicts return the latest revision and an explicit retry instruction.
Compound MCP helpers must preserve those same semantics across their local side effects. Tail-frame continuation derives stable Asset and Canvas IDs from its command ID, shares concurrent calls, uses bounded Canvas conflict recovery, and removes a newly created frame if the Canvas write ultimately fails.
The local MCP session may bind one active Project. View tools return clean workspace URLs plus host-neutral browser handoff metadata. The Codex Skill can open or reuse the exact Canvas or Editor review surface; Claude Code and WorkBuddy packages preserve the same URL for their available browser or user handoff. Every host package remains orchestration over the localhost product, not a second frontend or backend.
The public WorkBuddy Connector uses a WorkBuddy-managed Node.js runtime to
install a versioned BeatDesign package. That package starts the production
browser workspace and stdio MCP together, while storing SQLite, imported media,
and the per-install encryption key in the user's operating-system application
data directory through BEATDESIGN_DATA_DIR. This packaging changes startup
and installation only; it does not create a hosted workspace or another data
model.
Canvas UI persistence now derives incremental canvas.apply operations for cards, layout, camera, and workflow state. The layout snapshot endpoint remains a compatibility exception, not the active UI autosave path. CAS retries merge independent local and remote changes, while conflicting semantic edits fail visibly rather than silently overwriting either writer. External agents must use semantic operations rather than snapshot replacement.
Editor persistence selects editor.apply when applying supported operations reproduces the requested document exactly. Unsupported edits, imports, and undo may still use the revision-checked UI-only replacement command. The persistence hook owns autosave, conflict handling, and external revision refresh; external agents never receive replacement access.
Canvas and Editor poll the lightweight project revision endpoint before fetching documents and suspend document polling while hidden. Generation status endpoints read local task state; server-side synchronization throttles provider polling across callers using persisted sync timestamps. Local SQLite connections enable WAL and a five-second busy timeout. src/config/db/schema.ts is generated from schema.sqlite.ts by the database setup script, not a second hand-maintained schema.
The local SQLite schema contains twelve tables:
projectproject_canvas_stateproject_timeline_stateproject_command_receiptproject_workflow_stategeneration_historygeneration_upload_intentgeneration_intent_uploadassetgeneration_asset_linkproject_asset_membershipconfig
project_command_receipt stores bounded, short-lived command results for retry idempotency and powers the current MCP history tool. It is not a permanent audit log; long-term Agent Activity still needs a separate durable event contract.
No user, session, role, order, subscription, payment, credit, API-key, ticket, or CMS table belongs in this repository.
src/core/effects/effect-registry.ts is the canonical user-facing logical catalog. src/core/generation-providers/ maps those logical IDs to provider bindings and adapters. src/core/adapters/beatapi-adapter.ts contains BeatAPI request mapping. Do not leak upstream effect IDs or field names into MCP tools, and do not add a second database-backed model registry.
BeatDesign is a localhost application backed by one SQLite database and project-owned files under data/. Cloud database and hosted deployment adapters are intentionally outside this repository.