Changelog

Latest updates, features, and fixes in Trellis.

Changelog

Documentation

  • Projections and whiteboards: Calendar manual events and agent calendar CRUD tool, pin picker with rail × unpin, .whiteboard / Excalidraw files, fullscreen Whiteboards projection, agent whiteboard tool and corpus, Trellis system prompt + <whiteboard-tool> hints, auto-attached boards from Code tabs and Whiteboards projection, @opencode-ai/whiteboard/browser for Vite, and troubleshooting (unstyled Excalidraw, schema 500, agent denies tools). Studio introduction updated (graph entity sidebar frontmatter on Details).
  • CLI reference updated: seed, repair, expanded issue subcommands, refs, search, reindex, studio, and db quick start.
  • Documented -p / cwd repo-root resolution and issue create --description alias (shipped in 3.1.14).
  • Ecosystem desk guide: just trellis -r repo aliases, Studio vs desk indexing, VS Code search excludes.
  • Multi-agent desk hooks (Cursor, Windsurf, Codex, Copilot CLI, Gemini) and just docs-check / sync-docs workflow.
  • Ecosystem desk: local just publish-studio / publish-resume, desk .envNPM_TOKEN for non-interactive npm publishes.
  • Trellis Kernel API docs now cover concurrent local writers: lock-guarded ops.json appends, atomic temp-file rename writes, and lock-protected monotonic issue IDs (TRL-<n>).

Trellis Cloud

  • Sandbox CLI PATH: broker wraps E2B commands.run shells with npm global bin on PATH so trellis init and CLI upgrades work when the template already started Studio (wrapSandboxShell in cloud/src/studio-shell.ts). ensureStudioCli also verifies command -v trellis before skipping install. Fixes Provisioning failed / trellis: command not found (exit 127). See Cloud hosting.
  • Studio stack restart: when upgrading turtlecode, startStudioInSandbox now kills both the turtlecode shell (3333) and the OpenCode backend (4096) before relaunching. Fixes Method Not Allowed on POST /session/…/prompt_async when a new UI talked to a stale opencode serve. See Cloud hosting and Cloud AI proxy.
  • AI proxy (Vercel AI Gateway): broker routes /ai/chat, /ai/chat/stream, and /ai/v1/chat/completions through Vercel AI Gateway (default model: Gemini Flash Lite via GEMINI_DEFAULT_MODEL, for example google/gemini-2.5-flash-lite). Server-side AI_GATEWAY_API_KEY only; sandboxes authenticate with InstantDB bearer tokens. Per-user daily token budget (AI_DAILY_BUDGET), RPM/concurrency limits, and GET /ai/usage for the Studio status-bar gauge. BYOK (body.apiKey) bypasses the gateway and hits Google directly. See Cloud AI proxy.
  • AI proxy tests:cloud/src/ai-proxy.test.ts exercises model aliases, OpenAI-shaped responses, auth, rate limits, budget caps, and SSE streaming with a mocked AI SDK (no gateway key in CI). Runs under bun test src/ and passes broker bun run typecheck. Optional live checks: bun run test:ai-smoke in cloud/.
  • Projects grid: simplified project cards show the thumbnail, project name, last opened time, and an actions menu; large screens use a 3-column grid instead of four.
  • Publish (backend): broker endpoints POST /project/:id/publish/begin, POST /project/:id/publish/commit, and GET /publish/check for slug registry, R2 presigned uploads, and live pointer updates. InstantDB schema adds publishedSlugs, publishedVersions, and pendingPublishes. Edge router package at cloud/publish-router/ serves *.studio.trellis.computer from R2 (deploy is operator-driven; see the publishing guide).

Trellis Studio

  • Graph entity sidebar (markdown frontmatter): file Preview no longer squeezes YAML Properties into a side rail; frontmatter edits live on Details in a full-width block. Code view keeps the collapsible Properties column. See Trellis Studio introduction.
  • Whiteboard agent context: open .whiteboard files attach on composer send from Code tabs and from the Whiteboards projection fullscreen editor (recent tabs, no @ required). OpenCode Trellis system prompt documents the whiteboard tool; synthetic <whiteboard-tool> hints fire when boards are in context or the prompt mentions diagrams. See Projections and whiteboards.
  • Whiteboards projection (context fix): fixed a crash when opening a board fullscreen (ReferenceError: set is not defined) so projection context registration and composer auto-attach work. See Projections and whiteboards.
  • Projection rail unpin: pinned projection icons show the corner × only on hover or keyboard focus, keeping the rail uncluttered. See Projections and whiteboards.
  • Whiteboard package (browser entry): Studio UI imports @opencode-ai/whiteboard/browser so Vite does not bundle Node corpus loaders; fixes 500 on lib/whiteboard/schema.ts and broken Whiteboards projection. Agents still use the full @opencode-ai/whiteboard package and OpenCode whiteboard tool. See Projections and whiteboards.
  • Whiteboard agent corpus (@opencode-ai/whiteboard): versioned shapes, figures, layouts, and templates for .whiteboard files. OpenCode whiteboard tool: list_catalog, describe, apply_template, insert_figure. Elements can carry customData.trellis bindings (issue:…, entity:…) for graph cross-links. Shipped templates: sprint retro, flow diagram, system context; figures include mindmap node and API endpoint. See Projections and whiteboards.
  • Whiteboards projection (fullscreen): clicking a board in the Whiteboards lens opens Excalidraw fullscreen in the projection panel with a Back toolbar control to return to the card grid (no jump to Code view). New whiteboard opens the new file the same way. Code view and file tabs still open .whiteboard files in the editor pane. See Projections and whiteboards.
  • Session icon rail: reordered core views to Graph → Plan → Code → Database → Assets → Design → Review → Preview → Logs. Code, Assets, and Design use folder, boxes, and pencil-ruler icons. The preview panel tooltip is Preview (?view=browser; ?view=preview still works). Mobile bottom dock matches the same order. See Projections and whiteboards.
  • Whiteboards (Excalidraw CSS): fixed broken whiteboard UI (vertical toolbar, empty black canvas) by loading Excalidraw through a Vite-bundled React bridge (excalidraw-react-bridge.tsx) so index.css is injected; removed development CDN fallback. optimizeDeps includes Excalidraw and React. See Projections and whiteboards.
  • Calendar events: manual calendar_event entities in the Trellis store (title, schedule, all-day/timed, color, description). Studio Plan → Calendar and the Calendar projection: click a day to add/edit events, title chips on the grid, day panel editor. HTTP: GET /trellis/calendar/events, POST /trellis/calendar/save, POST /trellis/calendar/delete. Agent calendar tool: list, create, update, delete (optional year + month filter on list). See Projections and whiteboards.
  • Calendar projection: optional icon-rail lens (?view=projection&lens=calendar) shares calendar-view.tsx with Plan → Calendar (graph markers plus manual events). Pin from + or projections.pinned; not in workspace default pins.
  • Projection pin picker:+ opens On rail / Add to rail groups; hover a pinned icon for × to unpin (at least one projection required).
  • Whiteboards (.whiteboard + Excalidraw): open *.whiteboard files in Code view with an embedded Excalidraw editor (Excalidraw JSON on disk, debounced save). New Whiteboards projection on the icon rail (?view=projection&lens=whiteboards) lists boards and creates whiteboards/<slug>.whiteboard. Default pins for app and productivity workspaces include Whiteboards alongside Notes. Excalidraw mounts in a React 18 island inside the Solid app (excalidraw-react-bridge.tsx lazy chunk; Vite bundles @excalidraw/excalidraw/index.css). Requires bun install from the studio repo root and a dev-server restart. Studio strips ephemeral appState keys on save, supplies collaborators as a Map at runtime, repairs corrupt Excalidraw localStorage keys on open, and uses a per-file storage name. Unit tests in packages/app/src/lib/whiteboard/schema.test.ts. See Projections and whiteboards.
  • Cloud default agent (trellis-cloud): OpenCode registers a built-in trellis-cloud provider that points at the broker /ai/v1 OpenAI-compatible API. Studio defaults the composer to gemini-flash-lite-latest on cloud; CloudProviderSync writes the iframe auth token and broker base URL to OpenCode then disposes to reload providers. OpenCode Zen (Nemotron) remains a fallback. See Cloud AI proxy.
  • Cloud default agent (trellis-cloud): OpenCode registers a built-in trellis-cloud provider that points at the broker /ai/v1 OpenAI-compatible API. Studio temporarily defaults the composer to minimax-m2.5-free on OpenCode Zen while the metered broker → Vercel AI Gateway path is being stabilized; CloudProviderSync still wires the iframe auth token and broker base URL so trellis-cloud is ready to use. OpenCode Zen (Nemotron) remains a fallback. See Cloud AI proxy.
  • Cloud model constants tests:opencode-zen-model.test.ts locks hostedFreeModelKey() to opencode/minimax-m2.5-free and Zen/Nemotron as the fallback key.
  • Desktop graph (Tauri): fixed the live graph and other Trellis panels returning empty data in the desktop app. Several client helpers called /trellis/* with unauthenticated fetch; the embedded sidecar requires Basic auth, which produced 401 on /trellis/graph and similar routes. All Trellis HTTP helpers now use the authenticated SDK fetch (same path as stats and issues polling).
  • Code view layout: fixed the Explorer and editor stacking vertically in the Code rail view; the file tree and editor now share a horizontal row (tree left, editor right).
  • Publish (preview UI): cloud workspaces show a state-aware Publish / Live control in the preview and browser panels (packages/app/src/components/preview-publish-control.tsx). First publish opens publish-first-popover.tsx with slug validation (packages/app/src/lib/publish-slug.ts), debounced GET /publish/check, taken-slug suggestions, GET /publish/plan build overrides (command, output folder, SPA fallback), and public/unlisted visibility. Republish runs from the Live chevron menu. Session transcript sharing is labeled Share session so it is distinct from static publish. See Publish to the web.
  • Publish (backend): OpenCode module packages/opencode/src/publish/ orchestrates build (reusing preview inference), manifest hashing, broker begin/commit, and direct R2 upload. Routes: GET /publish/plan, GET /publish/check, POST /publish. Build logs go to the preview console. See Publish to the web.
  • Session status and streaming (cloud): assistant replies stream incrementally over SSE during a turn. The composer, timeline thinking indicator, and sidebar derive “working” from completed assistant messages as well as session_status, so UI recovers when the idle event is dropped in cloud iframes. While a turn is active, Studio polls session_status every few seconds; a full message reload runs only when busy status is stale, so streaming is not replaced by a single wall of text.
  • Default model on studio.trellis.computer: cloud workspaces temporarily default to MiniMax M2.5 Free via OpenCode Zen (default model id minimax-m2.5-free). When the metered trellis-cloud path is re-enabled as default, agent LLM calls route through the broker AI proxy and Vercel AI Gateway; no user API key is required for the default model. CloudProviderSync pushes the iframe InstantDB token to OpenCode on load so trellis-cloud is ready. Fallback remains Nemotron 3 Super Free (OpenCode Zen) when trellis-cloud is unavailable. Status bar shows daily token budget from GET /ai/usage. See Cloud AI proxy.
  • ChatGPT Pro/Plus (Codex) on studio.trellis.computer: remote workspaces now default to device code sign-in instead of browser OAuth (OpenAI only allows http://localhost:1455/auth/callback on the machine running Studio). Browser sign-in remains available for local Studio. After OAuth connect, Studio selects the best available Codex model (prefers GPT-5.3 Codex, then other Codex tiers; skips Codex Spark models that ChatGPT OAuth does not support) and shows a confirmation toast; new sessions prompt Connect ChatGPT until OpenAI is linked. The ChatGPT subscription catalog also exposes GPT-5.2, GPT-5.4, and GPT-5.4 Mini alongside Codex models; Studio detects subscription OAuth vs API-key catalogs so defaults stay on Codex after connect. MiniMax M2.5 Free remains the default when OpenAI is not connected.
  • ChatGPT Codex OAuth allowlist: OpenCode filters the OpenAI provider after ChatGPT sign-in to subscription Codex models only, so the first prompt no longer targets GPT-5.3 Codex Spark (Zen/API-only) and fails with "not supported when using Codex with a ChatGPT account".
  • Agent tool schemas (Big Pickle / DeepSeek): fixed first-turn failures when the default model rejected tool definitions with type: null (notably the asset tool). Tool parameters now use flat object schemas where needed, and OpenAI-compatible providers sanitize union schemas to root type: "object" before each request. Opencode regression tests cover the asset schema on the Big Pickle path plus link and image asset actions.
  • Backend resilience: Trellis graph and store polling pause while the local server is unhealthy (for example during a dev restart or [vite] server connection lost), then resume automatically when health returns. Avoids repeated ERR_CONNECTION_REFUSED noise in the browser console.
  • Session streaming: assistant tool accordions no longer trigger aria-hidden focus warnings during streaming; the turn container uses aria-busy instead. Auto-scroll coalesces layout updates to one frame while content grows.
  • Go to file:⌘P / Ctrl+P and the header search bar open a files-only quick open picker (VS Code-style), with fuzzy path search, space-separated segment matching, and up to 100 results. Search input is debounced (200ms) and in-flight /find/file requests are cancelled when you keep typing. The file index is warmed on workspace open. The command palette (⌘⇧P / Ctrl+Shift+P) remains a separate mixed picker for commands and sessions.
  • Open project by path: the Open project dialog accepts pasted absolute or tilde paths (for example /Users/you/project or ~/Projects/foo) in the search field; press Enter or choose the Paste path row to open that directory.
  • Composer focus: fixed inputs across the IDE (composer, file editor, search, sidebar prompts) sometimes becoming unclickable after an agent response. Modal UI layers could leave document.body with pointer-events: none; Studio restores pointer events when overlays close, on the next click when no modal is open, and defaults dropdown menus to non-modal. Errored assistant turns no longer keep the session in a “working” state when time.completed is missing. The todo dock no longer blocks the composer overlap (only its toggle and list accept clicks while open). Graph, Plan, Preview, and other rail views stay interactive without opening the review drawer; only Review requires the review panel. The composer uses pointerdown to focus the prompt when clicks land on the editor.
  • Theme preload:oc-theme-preload.js defaults to the Cursor palette and migrates legacy oc-1 installs to Cursor on first load (clears stale cached theme CSS).
  • Provider errors (invalid argument): OpenCode filters empty message content for Google/Gemini and OpenAI-compatible models (including Nemotron on Zen) before follow-up requests, reducing Request contains an invalid argument failures after tool rounds. Error text in the timeline includes a short hint to retry, switch models, or start a new session when this message appears.
  • File listing:GET /file lists the open project workspace when the SDK sends a project directory query param; the legacy ~/.turtlecode listing applies only under that home directory (fixes empty explorer on desk/symlink layouts).
  • Symlinks: symlinked folders in the file tree resolve to directory or file nodes based on their target.
  • Search indexing: git worktrees use ripgrep with symlink following where ignore rules allow. Desk-style roots (no git at the orchestration folder) use a shallow index that does not traverse symlink spokes; open a spoke path as the project to search inside that clone. .trellis/ is excluded from Studio file and text search.
  • Session navigation: removed the separate Home icon from the left rail. Graph is the default session view when you open a workspace (and when the view query param is omitted). Legacy links with ?view=home redirect to ?view=graph. The mobile bottom dock leads with Graph as well.
  • Workspace-scoped editor tabs: open files, rail selection, and review scroll state persist per project, not per agent session. Switching session tabs or creating a new session no longer resets the IDE layout; chat, composer, and model stay per session.
  • Default theme: Studio now defaults to the Cursor palette on first launch (local and cloud). Legacy oc-1 theme ids migrate to Cursor. Previously saved themes in localStorage are unchanged.

Debugging focus issues (development)

Studio logs when an input field gains or loses focus, and logs every pointerdown with hit, hitIsInput, inertAncestor, and bodyPointerEvents (useful when focus never fires). Filter DevTools for [input-focus]. When you click an input and focus still does not move, Studio retries focus() on the field under the cursor.

For deeper tracing (programmatic .focus() calls, focusout, mousedown hit targets), enable verbose logging and refresh:

localStorage.setItem("trellis_debug_focus", "true");

Filter the DevTools console for [focus]. Each log includes the click target, elementFromPoint at the cursor, and bodyPointerEvents when the body is stuck at "none". Disable with localStorage.removeItem("trellis_debug_focus") and refresh. Telemetry events no longer print to the console in dev; cloud tracking is unchanged.

3.1.14

  • CLI trellis --version now reports the real package version from package.json (was hardcoded 0.1.0).
  • CLI -p / cwd resolution walks up to the nearest .trellis repo root (monorepo subfolders work without passing the root path).
  • Clearer "not a repository" errors: show looked-from path, cwd, and -p hint.
  • issue create accepts --description as an alias for --desc.
  • bin/trellis.mjs launcher finds Homebrew Bun when Node's PATH is minimal (npx trellis / agent shells).

3.1.2

  • Fixed trellis/cms collection reads for inferred collections whose normalized key differs from the stored entity type casing, such as blogpost reading BlogPost entities.
  • Added graph-link awareness to CMS entries so reference links such as post --author--> author appear in fields and can be expanded.
  • Added status fact fallback when cms_status is absent, preserving content created by agents or lower-level store tools.
  • Added shared polling for CMS subscriptions so duplicate subscribers to the same collection or entry reuse one poll stream.
  • Added onError and custom equals subscription options.
  • Fixed CMS entity pagination to respect the opencode store route's 1000-entity page limit.
  • Added CMS client/scaffold tests and included them in the default test script.
  • Added directory support to CMS consumer scaffolds for multi-instance opencode routing.

3.1.1

  • Published the first trellis/cms SDK package update after adding scaffold helpers.

3.1.0

  • Added the trellis/cms subpath with createCmsClient, collection reads, entry reads, polling subscriptions, reference expansion, collection discovery, and consumer scaffold helpers for vanilla, React, Solid, and Vue.