Repository navigation
Self-hosting is now one command or one button on Docker, Cloudflare Workers or Vercel, and every target prepares its own database. See Self-hosting → Deployment topologies.
Breaking
PLANDESK_SESSION_SECRETis no longer read. Rename it toPLANDESK_BETTER_AUTH_SECRET(same value). A server that still has only the old name refuses to start and says so.- S3 storage needs
PLANDESK_STORAGE=s3. SettingPLANDESK_S3_*without it is now an error that says so, instead of a settingplandesk servesilently ignored. - Docker files are renamed.
Dockerfile.serveris nowDockerfileanddocker-compose.hosted.ymlis nowcompose.yaml, which reads.env(cp .env.example .env). The container listens on 7526, the same port asplandesk serve. plandesk deploy flyis gone; no Fly configuration ever shipped.plandesk deploy vercelis new, and thecloudflareanddockerguides describe what the repository actually deploys (Workers + Turso + R2, not D1 or Pages).- Removed package exports, none of which had a caller:
@plandesk/api:version,removeOrganizationMember,updateOrganizationMemberRole,parseActor,InvalidActorSerializationError,healthRouter.SyncServiceis nowTriageService.@plandesk/db:version,getArtifactByProjectAndId,getNoteByProjectAndId,viewConfig.upsertSubmission/UpsertSubmissionInput,revokeGuestSession,revokeRenderTokenandlistPrototypeLinksByFromArtifactmoved to@plandesk/db/testing.@plandesk/mcp-client:version.@plandesk/cliand@plandesk/runner: the"."entry. Both are command-line packages; run their binaries.
- Migration 0025 drops the unused
sync_statetable. @plandesk/serveris a new published package, and@plandesk/clinow depends on it:plandesk serve, the Docker image, the Worker and the Vercel function share its one composition. Publish it before the CLI that depends on it.@plandesk/mcp-clientand@plandesk/runnerare not part of this release. Their export changes above ship with their own next versions; the published1.0.0and0.1.0are unchanged.
Added
- The server prepares its own database.
plandesk serve, the Docker image, the Worker and the Vercel function all run migrations, the better-auth tables and the workspace backfills before serving, under a 60-second lease row (__plandesk_lease) so only one instance migrates at a time. While another instance holds it, requests answer503 {"error":"schema_behind","schema":…}and retry. A remote database no longer needs a manualplandesk migrate; the command stays for operators who prefer a CI step. - Deploy to Cloudflare and Deploy with Vercel from the repository root (
wrangler.jsoncwithpnpm run deploy;vercel.json). Both serve MCP at/mcp; the Vercel entry never did before. - Real S3-compatible storage (AWS S3, R2's S3 API, MinIO): signed PUT and GET, bytes proxied through the server. An unreachable bucket answers
502 storage_unavailable. - One environment reader for every target. Values are trimmed and blank means unset; GitHub and S3 settings are all-or-nothing and a half-set group names what is missing. Workers and Vercel answer
500 misconfigurednaming the variable.
Changed
- Storage kind
localis nowdb(bytes in the database).localis still accepted inPLANDESK_STORAGEandplandesk.server.json. - Notes and comments written over REST or the web app are stored as HTML, converted from Markdown in the service, the same as MCP writes.
- Uploaded files are served under a script-free sandbox CSP. An uploaded SVG carrying
<script>cannot run on the Plan Desk origin when opened directly; SVG still renders in<img>. [::1]is recognised as loopback for a server URL, like127.0.0.1andlocalhost.- The task lane shows and can be set on cards and the task drawer.
plandesk loginhas no default server. With no--serverit reuses the one saved in~/.plandesk/config.json, or tells you to pass--server <your Plan Desk URL>. It used to fall back to a host that serves only these docs.plandesk admin invite-ownerbuilds its claim link on your server's public URL:--base-url, thenPLANDESK_BASE_URLorbaseUrlinplandesk.server.json. It warns when it can only fall back to loopback.- Imported file URLs must be
https:(orhttp:to a loopback host), and their userinfo is dropped. An org export that carries any otherexternal_urlis now refused on import, all or nothing; edit that URL in the export and import again. File responses also sendReferrer-Policy: no-referrer.
Fixed
- Writes on a remote database are atomic again. Every multi-statement write (goals, tasks, projects, documents, folders, artifacts, prototypes, canvas) ran
BEGINandCOMMITon separate libSQL streams, so on Turso or sqld a successful write answered 500 and a failed one was not rolled back. Local file boards were never affected.
Install or upgrade: npm i -g @plandesk/cli@latest (published: @plandesk/db, api, mcp, server, cli at 5.0.0). Upgrading from 4.x: the 4.x → 5.0.0 guide. Full history: CHANGELOG.md.