Cheldrop Docs

Cheldrop Build Plan — v3, 12 August 2026

Supersedes v2 (2 August). Two changes: (1) status — Phases 0–3 are built, committed, and verified against the code (see per-phase DONE markers); (2) a new Phase 3.5 inserted: decide and, if confirmed, execute the free-tier backend switch from Pages Direct Upload to Workers static assets, before the folder architecture is built on top of the publish path. Background: Cloudflare develops new features for Workers only and de-emphasizes Pages; no sunset date exists and existing sites are safe, but Cheldrop's acquisition funnel (free tier) currently rides the path Cloudflare steers people away from, while the paid R2+Worker path already sits right. Pre-launch is the cheapest moment to switch.

v2 preamble follows; per-phase status markers are inline.

Supersedes v1 (1 August). The change: site folders moved from "a feature" to the product's architecture, live sync ships before beta, and the app becomes a background agent. Core reframe, in Chris's words: each subfolder of ~/Documents/Cheldrops/ is a site, with its own config, settings, and theme carried in files inside the folder — and the app runs all the time, watching.

This is the feature-by-feature plan from verified Mac build to launch. Work through it phase by phase with Claude Code. Each feature is a mini-brief: why, what, where, what not to break, done-when.

How to use this plan with Claude Code

Start each feature in a fresh Claude Code session in ~/Developer/Cheldrop/app. Reference docs/cheldrop-functional-spec.md and the relevant section of this plan; have Claude Code read the spec's "What must not break" section before writing code. After each feature: test manually, run npm run build:mac + npm run verify:mac when main-process code changed, commit. One feature per session.

The architecture shift (read once, applies everywhere)

A site is a folder. The managed root is ~/Documents/Cheldrops/ (decided 2 August). One subfolder per site, named by site ID (preview.myclient.com/). The folder carries its own configuration in cheldrop.yaml and optional theme in cheldrop.css, both living in the folder root, both excluded from publish by exact name.

cheldrop.yaml is the source of truth for site configuration. lowdb demotes to a registry: which folders Cheldrop knows about, plus runtime data and secrets that must never live in a folder (folders end up in iCloud/Dropbox sync — treat their contents as semi-public). Split:

Draft schema (finalize in Phase 4.1):

# cheldrop.yaml — managed by Cheldrop; editable by humans and Claude
schema_version: 1
site: preview.myclient.com
backend: r2              # workers | r2
live: true               # auto-publish on change
password_protected: true # the hash lives in the Worker, never in this file
toc: index               # index | sidebar (docs site) | none
show_toc: true           # written in step with `toc:` so older versions still read it
show_toolbar: true
toolbar: { date: true, raw_file: true, download: true, copy_link: false }
theme: cheldrop.css      # optional; injected into generated pages
theme_user_html: false   # opt-in: also inject theme into user-supplied HTML
header: Acme Docs        # optional site chrome (title/logo/link)
footer: © 2026 Acme AS   # optional (text/links); both absent by default
ignore: ["*.tmp"]        # optional extra publish excludes

Conflict rules: UI edits write the yaml. External edits (human or Claude) are picked up by the watcher and applied; a config change can trigger a republish. Invalid yaml → macOS notification + keep last-good config, never crash, never publish a broken guess. A folder with a valid cheldrop.yaml can be adopted by any Cheldrop install (point the app at it, or drop it into the Cheldrops root) — settings travel with the folder; only secrets need re-establishing. This is site portability and disaster recovery in one move.

cheldrop.css is a rendering input, not a passthrough file. It gets injected (link tag) into everything Cheldrop generates — markdown wrappers, TOC, gallery, auth page. Injection into the user's own HTML files is opt-in via theme_user_html, because silently rewriting user HTML is how you break sites. This file is also the seed of the brandable-output story: a Claude SKILL that edits cheldrop.css + cheldrop.yaml is how "Claude reconfigures your site" works with zero API surface.

Spec collision to fix explicitly: the current renderer passes hidden files through to published output. cheldrop.yaml and cheldrop.css must be excluded by exact name at publish, and the ignore globs honored, in renderer.js — mode detection AND output.


Phase 0 — Housekeeping + smoke test (no code, ~1 hour + ongoing) — MOSTLY DONE 2026-08-12

  1. Copy mcp-plan.md and this plan from Dropbox …/Prosjekter/Cheldrop/docs/ into ~/Developer/Cheldrop/app/docs/, fix the stale ~/Documents/Prosjekter/… paths in mcp-plan.md's embedded prompt, commit.
  2. Delete the retired Dropbox app/ folder and ~/Developer/Cheldrop/_to_delete/.
  3. Install the verified DMG into /Applications.
  4. Smoke test, not beta: give the current build to 2–3 friendly users now — purpose is onboarding only (token creation, permission warnings, first publish on unfamiliar Cloudflare accounts). That surface doesn't change with the folder work, and strangers' accounts break things yours can't. The real beta moves to Phase 5, after the flagship exists — beta feedback on the pre-folder product would validate the wrong product.
  5. Lemon Squeezy paperwork (tax form, store approval) runs in parallel throughout — it's the long pole.

Status 12 Aug: docs copied into repo ✓, _to_delete/ removed ✓, DMG installed in /Applications ✓. Still open: the 2–3 person onboarding smoke test, and Lemon Squeezy paperwork (tax form + store approval — still the long pole, still blocking payouts).


Phase 1 — Small fixes (2–3 days) — DONE 2026-08-02

All four shipped: 1.1 password toggle (fc73e8e), 1.2 settings autosave (84b2756), 1.3 safeStorage token encryption with idempotent plaintext migration + fallback warning (e5a91a2, 1443caa), 1.4 token onboarding deep-link with pre-filled permissions (c487395 + follow-ups). The deep-link's Pages permission was removed in Phase 3.5 (b42aa63); the floor is now Zone:Read, DNS:Read, Workers:Edit, R2:Edit.

1.1 Password toggle bug

For a password-protected site re-selected in Publish: restore the toggle to on, leave the password field empty and required, never store the password (decision 1 Aug). Where: Publish.jsx, the same restore block as showToc/showToolbar (~lines 76–78). Don't break the 66ec00a per-site restore. Done when publishing unprotected-by-accident is impossible. (Note: Phase 3 changes password handling for R2; this fix still applies to the interim and to the publish-time UX.)

1.2 Settings autosave

Autosave on token validate, license activate/deactivate, defaultBackend/defaultSession change; "Settings updated" toast; remove the Save button. Where: Settings.jsx via existing save-settings IPC. Don't fire a save mid-way through the validate → zones → permissions chain.

1.3 Encrypt the API token with safeStorage

Encrypt cfToken via Electron safeStorage in the get-settings/save-settings handlers; idempotent migration from plaintext on first run; fallback with warning if encryption unavailable. Renderer sees no change. Matters more in v2: a background agent holds this token 24/7.

1.4 Token onboarding deep-link

Quick Start button opening Cloudflare's dashboard token page pre-filled (name + exact permission set) via the undocumented URL format (parameter encoding per cfdata.lol's generator); guided manual flow remains as visible fallback; cf-check-permissions verifies after paste. Floor permissions: Pages edit, Workers edit, R2 edit, DNS edit (the Pages CNAME upsert is mandatory), zone-scoped. (Superseded by Phase 3.5: Workers edit, R2 edit, DNS read, zone read.)


Phase 2 — Auto-update (1–2 days + testing) — DONE 2026-08-02

Shipped (4e37008); full update loop verified end to end with the 1.0.1 release (0ea1e64). main/updater.js exists; electron-updater in dependencies.

electron-updater + GitHub Releases. Check on launch (non-blocking) + menu item; quiet download; install on quit. Add the mac zip target (electron-updater requires it) to the existing sign/notarize pipeline; latest-mac.yml in the release. If the repo stays private, publish releases from a public releases-only repo or generic HTTPS feed — the updater needs unauthenticated access.

Elevated in v2: this app becomes a permanently-running background agent on other people's machines (Phase 4.3). An always-on process with no update channel is not shippable. Test the full loop with a dummy 1.0.1 before trusting it — auto-update is the one feature you can't fix remotely if it ships broken.

Don't break: validateStoredLicense() non-blocking at launch; updater must never block window creation.


Phase 3 — R2: real password protection + purge fix (3–4 days) — DONE 2026-08-03

Shipped (2d6a040). Verified in code: main/r2-worker.js implements PBKDF2-HMAC-SHA256 password hash + HMAC-signed session cookie (server-side auth, no request reaches an object without a valid session); main/cloudflare.js purgeR2Bucket() purges via the R2 API instead of the live domain (DNS race fixed) in both re-publish and delete paths. Remaining from "done when": the curl test matrix belongs to the Phase 9 test pass.


Phase 3.5 — Free-tier backend: Pages → Workers static assets — DONE 2026-08-13

Decision confirmed by Chris and shipped the same day (b42aa63). Cloudflare builds new features for Workers only; Pages is de-emphasized with no sunset date. The free tier — the acquisition funnel — was the last thing publishing via the Pages Direct Upload API; the paid path (R2+Worker) already sat on Workers. Done before Phase 4 deliberately: folders and live sync build straight on the publish path, so this was the last cheap moment.

What landed:

Verified: end to end on a throwaway site — TOC index at /, markdown wrapper, raw .md served as text/markdown, branding footer present; re-publish took the unchanged-files path; delete removed Worker, domain and DNS record. npm run build:mac + npm run verify:mac all green.

3.1 Server-side auth in the R2 Worker — now a hard prerequisite for live vaults

Why (v2 reason): live sync publishes unattended. The never-store-the-password decision means nobody is present to re-enter it at sync time — so on the client-side-guard model, a protected live site is impossible. Server-side auth dissolves the contradiction: the Worker keeps a salted hash (PBKDF2 via Web Crypto) and HMAC session secret as Worker secrets; content republishes never touch auth. Plus the original reason: current client-side protection leaves every file publicly fetchable by direct URL, which is not a thing you can sell as "password protection."

What: Worker checks every request for a valid HMAC-signed HttpOnly session cookie; otherwise serves the login page; login POST verifies against the hash and sets the cookie with the configured session length. Password set/changed in the app (or at protect-time) provisions the Worker secret — an allowed exception to the re-publish-skips-Worker-deploy rule; keep the skip for all other republishes. Stop injecting the client-side guard on R2 sites. /__cheldrop_admin__/purge stays exempt (adminSecret header).

DECISION — resolved 2 August: password protection is R2-only. UI copy: "Password protection requires the R2 backend." Remove the client-side guard path entirely (Pages sites are simply public); selecting password protection switches/requires backend r2, which is Business Class — the license gate does the upsell work.

Done when: curl of any file URL on a protected R2 site returns login/401, never content; sessions expire per config; purge/delete flows work; a Live protected site republishes with no password prompt.

3.2 R2 purge via API

Replace the live-domain purge with R2 API list + delete (paginated, batched) in the re-publish path. Fixes the DNS-propagation race — which live sync would otherwise hit constantly on fresh sites. Keep the Worker purge endpoint for delete-site (or migrate it too).


Phase 4 — The flagship: folder architecture, live sync, background agent (6–9 days)

Build in this order — each step is testable alone.

4.1 Site folders + cheldrop.yaml (the data-model inversion) — DONE 2026-08-13

What landed:

Deliberate call, worth knowing: the plan says the theme is injected as a link tag but not what URL it points at. Publishing it under the source name cheldrop.css would contradict "excluded by exact name", so it publishes as theme.css (Chris's call, 13 Aug) and is linked absolutely (/theme.css), which also works at any subdirectory depth. A user file already named theme.css pushes the generated one to theme-1.css.

Fixed in the same session (found while wiring the render options, fixed on Chris's go-ahead): licenseStatus was never passed into renderFiles, and seven wrapper/TOC call sites dropped isBusinessClass — so Business Class sites carried the free-tier "Published with Cheldrop" footer on every page.

Still open from this section: live is read, preserved and cached on the site entry, but nothing watches yet — that is 4.2 by design.

What: Create ~/Documents/Cheldrops/ lazily. New folder-mode sites are created here by default; a drag-drop (Files mode) publish offers one-click "Save as site folder" that materializes the published set into Cheldrops/<site-id>/, writes a cheldrop.yaml from current settings, and converts the site to folder mode. On every publish of a folder site, read cheldrop.yaml as the config source (lowdb entry becomes cache + secrets). UI settings changes write back to the yaml. "Adopt folder" flow: point Cheldrop at any folder containing a valid cheldrop.yaml (or drop it into Cheldrops root) → site appears in the app; prompt to (re)provision anything requiring secrets. Add "Reveal in Finder" per site; missing-folder → clear relink dialog. Deleting a site asks keep-or-trash the folder (default keep).

Renderer changes: exclude cheldrop.yaml/cheldrop.css by exact name from mode detection AND output; honor ignore globs; inject cheldrop.css into generated pages (and into user HTML only when theme_user_html: true).

Where: main/ipc.js (folder create/materialize/adopt, yaml read/write — add js-yaml), main/renderer.js (exclusions + theme injection), Publish.jsx/Sites.jsx (UI). Site entry keeps linkedFolder/publishMode — no schema break.

Don't break: existing sites with linkedFolder elsewhere keep working, no forced migration; read-linked-folder recursion; publishedAt preservation; the resource-naming derivation.

Done when: a site folder moved to a second machine and adopted publishes identically (minus secrets re-link); editing cheldrop.yaml by hand changes app-visible settings; yaml/css never appear on the published site.

4.2 Live sync — DONE 2026-08-13

What landed:

Deliberate calls, worth knowing: (1) Live requires the site to have been published once — the watcher republishes, it does not provision, and an adopted folder has no Cloudflare resources yet. The toggle says so. (Amended 16 August, plan C2: the toggle is no longer disabled before that first publish — Live is a setting of the site, so it is set with the others at creation and written to the yaml; it simply starts working when the site publishes.) (2) .tmp-style files are ignored as triggers but are still published if they sit in the folder, because a manual publish would publish them too; the folder's ignore globs are the way to exclude them from both. (3) Watchers run while the app runs — closing the window still ends them until the menu bar agent lands in 4.3.

Verified: headless Electron smoke test over a real folder — debounce holds, the rate cap holds, two saves inside the cap collapse into one publish carrying the latest state, cheldrop.yaml never enters the publish set, invalid yaml errors without publishing, and live: false stops the watcher. npm run build:mac + npm run verify:mac green.

Still open: the several-day soak with sleep/wake and real network drops, and the "window closed, agent keeps syncing" half of the done-when — that is 4.3.

What: Per-site live: true (folder sites only). Default on, superseding the "default off" this brief was written with — decided 15 August 2026, shipped with polish plan C1 + C2 on 16 August. A new site folder is created with live: true, so the normal case is folder + Live with no configuration; a folder whose path is inside a cloud-synced tree (iCloud, Dropbox, Google Drive, OneDrive) is created with live: false, because that is where the two-machines-publishing-over-each-other risk lives. The rule is one function, sitefolder.defaultLiveFor(), and it decides the default only — it never overrides what a cheldrop.yaml already says. Live still starts working only after the site's first publish: the watcher republishes, it does not provision. Main process watches live folders (chokidar): debounce ~5 s after last change, hard rate cap ~1 publish/60 s/site, queue latest state. Reuse the existing publish path end-to-end so rendering, TOC, auth, theme all apply identically. Watcher also watches cheldrop.yaml itself — config edits apply live (this is what makes the Claude SKILL work end-to-end). Pause watcher during any manual publish. Status in Sites list (Live / syncing / error).

Watch out: publish is full-replacement — debounce and rate cap are mandatory, and check current Cloudflare limits (Workers static assets: 25 MB/file, 20,000 files). Unchanged files are not re-uploaded (Phase 3.5), which makes frequent small edits cheap, but each publish still deploys a new Worker version. Folders inside iCloud/Dropbox: ignore dotfiles/.tmp/partial-download patterns; treat dataless iCloud placeholders as changed-when-materialized; document "enable Live on one machine per site" (two machines + shared folder + Live on both = publish ping-pong).

DECISION — resolved 2 August: Live is available on the free tier's single site. The gates stay: site count (1 free), R2/vaults (Business Class), branding footer (free). Live is the wow that sells the upgrade.

Done when: save a file in any editor → change is live on the domain in ~10 s with the app window closed (see 4.3); network loss mid-sync recovers with backoff; toggling Live off stops the watcher instantly.

4.3 Background agent (menu bar) — DONE 2026-08-14

What landed:

Verified: headless Electron test — 15 checks covering icon loading, tray creation with no window, menu building against the real registry, the worst-state glyph rule, one-notification-per-episode with silent recovery and a fresh episode after it, pause/resume, the ask-once login prompt, and the relative-time strings. npm run build:mac + npm run verify:mac green, tray resources present in the bundle.

Still open: the login/logout and multi-day soak runs belong to the Phase 9 test pass, and the Windows differences (tray behaviour, login items, window-all-closed) stay a Phase 9 item — on Windows the app still quits with its last window.

Why: "An app that runs all the time, watching folders" is a different app posture. Live sync while the window happens to be open is a demo; live sync as an ambient guarantee is the product.

What: Menu bar (tray) presence: status glyph (idle / syncing / error), menu with per-site status + last publish time, pause-all, open dashboard, quit. Closing the main window keeps the agent running (standard Mac behavior; Dock icon optional setting). "Launch at login" toggle (app.setLoginItemSettings), prompted once when the user enables their first Live site. macOS notifications for unattended failures — an agent that fails silently is worse than no agent; batch/throttle them (one per site per error episode, not one per retry). Real quit from the tray menu stops all watchers cleanly.

Where: main/index.js (window lifecycle, tray, login item), new tray module; notifications via Electron Notification.

Don't break: theme init and license validation on window re-open; single-instance lock (second launch focuses the running instance instead of spawning a twin — add if absent).

Done when: log in → agent is in the menu bar with no window; edit a file in a Live folder → published, notification-silent on success; unplug network → one clear failure notification, auto-recovery on reconnect; quit actually quits.


Phase 5 — Beta (the real one)

Now the beta tests the actual product: Cheldrops folder, Live sites, background agent, R2 vaults. 5–10 real freelancers, free tier + a comped Business Class each (you want R2/vault feedback more than $49). Structured ask: set up one real client-facing site, run it Live for a week, report every moment of confusion. Auto-update is in place, so shipping them fixes is cheap. Triage: ship-blockers fixed now, everything else to backlog.


Phase 6 — Cloudflare sync — DONE 2026-08-14 (built out of order, before Phase 5)

What landed:

Verified: 25 pure-logic checks (name→site-ID splitting including dashed domains and longest-match zones, ok/partial/missing/unpublished/unknown, orphan grouping and importability, legacy Pages sites) plus a live read-only run against a real Cloudflare account: 5 Workers listed, R2 and Pages correctly reported as unreadable rather than empty, 2 orphaned chel- Workers found — which is exactly the drift this phase exists to surface. npm run build:mac + npm run verify:mac green.

Out of scope, deliberately: nothing here deletes a remote resource. Cleaning up an orphan is import-then-delete through the normal delete flow, where the confirmation and the consequences are already spelled out.

Original brief follows.

Phase 6 — Cloudflare sync (1–2 days, scope reduced in v2)

Folder adoption (4.1) now covers local recovery and portability, so this shrinks to remote reconciliation: list chel--named Workers (and any leftover Pages projects from before Phase 3.5), flag local sites whose remote resources vanished (broken badge + repair/remove), list remote chel- resources with no local site (offer import as registry-only entries). Read-only against Cloudflare; never deletes remote resources. Join key is the naming derivation — do not vary it. Matters before MCP so list_sites tells the truth.


Phase 7 — MCP server + the Cheldrop SKILL — DONE 2026-08-14

What landed:

Verified: 81 offline checks against the real modules with Electron stubbed — tool surface and schemas, JSON-RPC (initialize/version negotiation/notifications/unknown method and tool/malformed request), the origin guard, every token-needing tool before setup, domain and subdomain validation, the free-tier gates and their nudges, files-mode and moved-folder refusals, the empty-folder and invalid-yaml stops, password refusals on free/Workers/files-mode with the password never echoed, the delete confirmation gate leaving both registry and folder untouched, adoption, and the HTTP surface (no/wrong/short secret, Bearer, foreign origin, notification 202, parse error, GET 405, unknown path 404, revocation, enable/disable). npm run build:mac + npm run verify:mac green.

Still open: the clean-Claude-Desktop end-to-end (create a real vault, curl it without a cookie for the 401) is a live run against a real domain — it belongs to the Phase 9 test pass, alongside the landing-page "Works with Claude" section, which is the one thing mcp-plan.md defers until after the feature works.

Original brief follows.

Phase 7 — MCP server + the Cheldrop SKILL (4–5 days)

Two integration surfaces now, and they split cleanly:

Files are the content/config interface. With Live folders, Claude updates a site by writing files into it and reconfigures it by editing cheldrop.yaml/cheldrop.css — no API needed. Ship a Cheldrop SKILL (SKILL.md, distributed from cheldrop.com/docs and bundled where useful) that teaches Claude: the Cheldrops folder convention, the yaml schema, the css injection model, and the rules (never write secrets to yaml, respect ignore, one Live machine per site). This is a docs artifact, not app code — cheap to build, huge leverage.

The MCP is the provisioning/action interface — the things files can't do because they need the token: get_settings, list_sites (now folder-aware: path, live status), create_site (provision subdomain/backend + create the folder + write starter yaml — the end-to-end "set up a vault for client X" move), adopt_folder, publish_now (force immediate publish, bypass debounce), delete_site (double-confirm, per mcp-plan.md), set_password (provisions the Worker hash per 3.1; never stored, never echoed). Build on docs/mcp-plan.md's transport/auth/guardrails (localhost:3847, shared secret, confirm-overwrite, upgrade nudges) — the tool list above supersedes its original tool list where they differ. get_settings gains app_version.

Done when: from Claude Desktop: "set up a password-protected vault at vault.client.com for the files I'm about to give you" → MCP creates folder + provisions site + sets password → Claude writes files into the folder → Live publishes them → link works, curl without cookie gets 401. Docs page + landing section ship with the feature (per mcp-plan.md's "when this ships" rules).


Phase 8 — Reskin (2–3 days, floats — start the design exploration now)

Claude Design brief: keep the layout; replace the espresso/terracotta palette ("too brown") with something easier to like on first contact but still with personality; dark + light; WCAG AA body text. Implementation is a CSS-custom-property token swap plus component polish. Propagate in one pass: app tokens → landing → DMG background → icon accent → brand skill doc — a half-reskinned brand reads as abandoned. New in v2: the tray icon needs designing (template image, dark/light menu bar, idle/syncing/error states) — partly done 2026-08-14, out of order, at Chris's request: the hexagon was replaced by the brand mark (disc + four-point flare, knocked out) with the state language unchanged, generated by build/tray/make-tray-icons.py from the app icon's geometry. It is committed source, so the reskin re-runs it with new proportions rather than redrawing by hand. The palette swap itself landed 14 August as Stillwater+ (218509a) across app tokens, the published output (wrapper, TOC, 404, gallery), the app icon and the tray glyph; default cheldrop.css starter themes are part of the design language now — their mechanism shipped 16 August with polish plan C3: three themes live as files in templates/themes/ (Pond, Ember, Ultraviolet, plus "Cheldrop default" = no file), picked in the publish form and copied into the folder as cheldrop.css. Adding or replacing a theme is editing a file in that folder; this phase revisits the CSS, not the plumbing. Can land any time after Phase 1; before Phase 5 beta is ideal so screenshots show the final face.

Propagation status (17 August). The install window is done: build/brand/dmg-background.svg is the source, bash build/make-dmg-background.sh renders build/dmg-background.png + @2x (electron-builder pairs them into a retina tiff with tiffutil at package time), and package.json's dmg block pins the layout the artwork is drawn for — app at (140,180), Applications at (400,180), 128px icons in a 540×380 window. The drop lands on the app icon and the wave carries it right; the ripple is --accent on --bg, the app's own tokens. It carries no text on purpose: Finder draws both icon labels anyway, and text would bind the file to a font that is not installed on a clean machine — the woff2 in node_modules cannot be rendered by rsvg-convert, so a lettered version could not be regenerated without a new build dependency. Still open in the propagation pass: the cheldrop.com landing page and the brand skill doc. Both live outside this repo; until they follow, the brand is half-reskinned in exactly the way the paragraph above warns about.


Phase 9 — Pre-release tests, launch, Windows

  1. Test pass: the original three (R2 re-publish via API purge, R2 per-file links, permission warnings) plus: auto-update loop; Worker auth curl-tests on every file type; live sync soak (a Live site with real edits over several days, sleep/wake, network drops); background agent across login/logout; yaml hand-editing including invalid yaml; adoption on a second Mac; MCP + SKILL end-to-end from clean Claude Desktop.
  2. Launch when: LS checkout live + tax cleared, auto-update proven, R2 auth shipped, folders/Live/agent stable through beta, MCP listed. Launch story leads with the folder: "a folder on your Mac that is your website — on your domain, in your Cloudflare account, operable by Claude." Surfaces: cheldrop.com, MCP directories, Product Hunt, your network. Launch execution gets its own plan.
  3. Windows after Mac launch. Note v2 raises Windows effort: tray/background/notification behavior and login items differ meaningfully on Windows. Still a distribution multiplier, not a validation multiplier.
  4. Post-launch backlog: starter theme gallery for cheldrop.css, brandable TOC/toolbar building on the theme system, "did the client view it" (Worker-side counter in the user's own account — keeps the we-host-nothing promise), menu-bar-only mode refinements, expiring vault links, versioning/rollback (folder history), interactive Markdown checkboxes, site locking with countdown.

What changed from v1, and why (for the record)

Site folders went from feature to architecture: cheldrop.yaml in-folder becomes the config source of truth (lowdb → registry + secrets), which buys portability, disaster recovery, hand-editability, and a file-based Claude interface for free. Live sync + background agent moved ahead of beta, because beta on the pre-folder product would validate the wrong product; a 2–3 person onboarding smoke test stays in Phase 0 to keep stranger-account learning flowing. R2 server-side auth was promoted from "honesty" to "prerequisite": unattended republish + never-store-the-password is only coherent when the Worker owns auth. Cloudflare sync shrank (folders now handle local recovery). The MCP split into MCP-for-provisioning + SKILL-for-files. Cost: build time goes from ~3–4 weeks to ~5–6; realistic launch slides from September toward October 2026. Chosen deliberately: depth over date — "a folder that is your website" is a launch story, "a nicer Cloudflare GUI" is not.

August 19, 2026 Raw file Download