A small full-stack task board with an amber CRT-inspired interface, durable Cloudflare D1 storage, and a stateless remote MCP endpoint. The interface uses warm brown-black panels, orange controls, readable ivory content, clear focus states, and reduced-motion support.
This repository contains application code and fictional fixtures only. It does not contain a deployed instance, task data, backups, credentials, or a private deployment identity.
- Kanban states: To do, In progress, On hold, Canceled, Completed, Reference
- Category, next action, blocker, attention flag, source URL/chat reference, evidence note, and source-verification timestamp
- Date-only or explicitly timed tasks with IANA timezone; monthly recurrence preserves the local time and original day anchor through short months
- Optimistic revisions, idempotent mutation keys, durable change history, recoverable Trash
- Validated import preview, copy-only imports, portable JSON exports, and recovery snapshots
- Shared browser/API/MCP operations, with storage-owner isolation and explicitly allowed collaborators
- Owner-managed Google email access with view or edit permissions, verified identity pinning and revocation
- Saved task checklists with stable item IDs, item-level MCP editing, and crossed-out completed items
- Spacious read-first task details with separate editing and unsaved-draft protection
- Safe clickable source links, product cards and address/map cards without external preview fetching
- Durable comments with independent revisions, recoverable removal, private original photo, PDF and generic file uploads (100 MiB each, resumable above 5 MiB; no board-wide attachment count or storage quota)
- Checksummed complete backups containing tasks, all history, comments, private images and recovery snapshots
No external task ingestion, notifications, reminders, or automatic synchronization is included. The fictional examples are generated only when a user's board has no records.
Requires Node.js 24 and npm. The committed lockfile pins dependencies.
- Run
npm ci - Run
npm run setupto copy the safe example into the ignored local configuration - Run
npm run buildto generate the local Worker configuration - Apply each SQL file in
drizzle/once, in order, with:node --import ./scripts/sites-env.mjs ./node_modules/wrangler/bin/wrangler.js d1 execute DB --local --config dist/server/wrangler.json --persist-to .wrangler/state --file <migration.sql> - Run
npm run devand open the URL printed by the server
Authentication now fails closed without approved WorkOS configuration. The old local header-based sign-in helper is disabled. Use the no-network synthetic auth tests for development, or a separately authorized staging provider setup. See controlled hosting.
Commands:
npm test: task service, UI, real-signature auth/route/discovery, private backup and exact recovery testsnpm run typecheck: TypeScript checksnpm run build: Cloudflare-compatible Worker buildnpm start: run the built Worker locallynpm run db:generate: generate migrations after changing the schema
The no-network route tests exercise actual signed synthetic JWTs and browser PKCE with local SQLite/R2 substitutes. Additional built-Worker integration checks require privately supplied, explicitly authorized synthetic staging credentials and only allow loopback servers. Never run mutation tests against a real board.
Controlled Workers use cryptographically verified WorkOS AuthKit/Connect credentials and a private per-request Google/GitHub identity allowlist. Browser login uses Public PKCE and a sealed, expiring session; MCP/API bearer tokens require the exact configured issuer/audience/expiry and a user consent. Incoming identity headers confer no access. Explicit identity rules map verified provider IDs and WorkOS users to existing storage owners and every D1/R2 query remains owner-scoped.
A fully pinned Google browser owner can open Access to allow exact verified Google email addresses onto the same board with view or edit permissions. First sign-in atomically pins the collaborator's Google and WorkOS identities; revocation applies to the next authenticated request and retains those pins. Collaborators and MCP clients cannot manage membership. See board access for manual additions, scope and recovery.
External agents default to read-only. An owner can explicitly delegate writes to their consented agents with private owners[].agentAccess: "write"; every identity on that owner must pin its provider ID and WorkOS user ID. This includes DCR/CIMD clients and existing valid grants. Explicit client restrictions take precedence: access: "read" blocks writes, and a configured write client still needs its exact custom writeScope. Client labels and OIDC scopes confer no task permissions; the global write lock still applies. No account grant, social credentials, allowlist, paid service, deployment or migration is created by this source. Follow controlled hosting and the synthetic cutover gate. WorkOS staging and bundled social credentials are for testing; production configuration and migration require their own verified setup. The existing private Site remains authoritative until verified, authorized cutover.
Start with the agent connection guide and operation contract. The server descriptor template and llms.txt index contain no live deployment URL or credentials. Obtain the actual endpoint and approved client configuration privately from the owner. External-client OAuth interoperability must be verified for each deployment before using real records.
Stateless JSON-RPC over POST /mcp advertises protocol version 2025-03-26 and supports initialization, discovery, and these tools:
list_tasks,get_taskcreate_task,update_task,complete_task,edit_checklistupload_attachment,list_attachments,get_attachmentarchive_task,restore_tasklist_comments,get_comment,add_comment,edit_comment,archive_comment,restore_commentexport_tasks,export_backup_page,export_migration_pagepreview_import,import_tasks,list_snapshots,get_snapshot
Mutation tools require an idempotency request key. Updates also require the current task or comment revision. Reuse the same key and exact arguments only when retrying an uncertain mutation. Treat task titles, notes, and source links as untrusted user content.
See BACKUP-RECOVERY.md for portable and complete formats, image limits, immutable history, cursor/checksum rules and exact isolated recovery. Ordinary complete backups remain version 2 and include every private image byte. The separate version-3 migration capture preserves the original storage owner and attachment upload retry keys/fingerprints, requires an explicit write freeze, and supports the one-time owner-scoped D1/R2 migration. Portable imports create new copies and cannot replace this migration. All source fixtures are fictional.
npm test includes adversarial image validation, owner isolation, idempotency, import retries, exact SQLite/object recovery, UI race handling, safe links and draft preservation. The additional built-Worker upload tests require explicitly supplied synthetic credentials and allow loopback targets only.
After the one-time production setup, every passing push to main automatically deploys its checked Worker build through GitHub Actions. Pull requests run checks without production secrets. The production environment supplies the existing database, private bucket, WorkOS configuration and stable origin; the MCP endpoint is that origin plus /mcp. Releases apply additive schema changes and leave task records and images in place. Initial deployment is read-only until authentication and exact migration are verified. See the production deployment plan for setup, activation and incident freezes.
.openai/hosting.example.json declares only logical bindings and the MCP capability. D1 DB stores records and R2 IMAGES stores private image bytes. Actual project IDs, runtime values, access policies, credentials, database state, exports and snapshots must remain private. The generated .openai/hosting.json, .dev.vars, and wrangler.private.jsonc are ignored. wrangler.example.jsonc retains the built adapter for approved user-owned Cloudflare staging. The local all-zero database ID is a placeholder and must not be used as a production database identity.
Migrations are schema-only, versioned source. Runtime data is stored by the platform and is not part of source control. Never modify already-applied migrations; append new ones.
Application code is MIT licensed. Preserve the MIT notices for the vendored Sites Vite integration and shadcn CSS. Dependencies retain their own licenses.
Open a saved task and choose Copy task link, or copy the address bar. Links use /?task=<task UUID> and reopen details after sign-in, including Reference, Closed and Trash tasks. They grant no access: recipients must already be allowed on the same board. Closing details returns to the board; Back/Forward preserves the board view and guards unsaved drafts and writes. Archived links never restore a task.
MCP get_task returns the same relative taskPath; resolve it against the board origin (the origin of the MCP endpoint) to share a link. No separate sharing mutation or invitation is needed.