Roadmap
Last updated: 2026-10-06.
Guiding principle: start small, ship vertical slices. Every phase ends with something that works end to end in the playground, has tests, and is documented.
Phase 0: Foundation ✅ (2026-10-02)
Section titled “Phase 0: Foundation ✅ (2026-10-02)”- pnpm monorepo:
packages/tapestry(plugin) andplayground(site); split into the plugin repo andtapestry-playgroundon 2026-10-09 (ADR 0038) - Supply-chain hardening in
pnpm-workspace.yaml - TypeScript 6 strict, Biome, Vitest
- Playground: Astro 7 + StudioCMS 0.6 + libSQL (local SQLite file)
- Docs: CLAUDE.md, architecture, data model, security, ADRs, devlog
Phase 1: Render pipeline ✅ (2026-10-02)
Section titled “Phase 1: Render pipeline ✅ (2026-10-02)”Goal: a page stored as a component tree renders as real Astro components.
- Document format v1 and
defineComponent()with six prop types - Validator with limits, URL safety, never-throw cleaning
- Renderer:
<tapestry-node>and URL-encoded props,Node.astrowrapper - StudioCMS page type
tapestry/canvas(renderer and editor) - Phase 1 editor: JSON textarea, live validation, component reference
- Six example components in the playground and a seed script
- 75 unit tests, including the real ultrahtml pipeline
- Verified: dev render, dashboard editor load, production build and render
- Dashboard save round trip verified in a real browser (e2e, Phase 2 session)
Phase 2: Visual editor MVP ✅ (2026-10-02)
Section titled “Phase 2: Visual editor MVP ✅ (2026-10-02)”Goal: an editor can build a page without touching JSON.
-
UI clean-up (2026-10-07): Components panel in StudioCMS purple, icon buttons and purple markers in the page structure, keyboard hints in info popovers, canvas bottom toolbar
-
Evaluated Puck → build our own (ADR 0006)
-
Chose drag and drop: Pragmatic DnD + list-item hitbox (ADR 0007)
-
Preact 10 +
@preact/signalsmounted fromEditor.astro(dashboard-only, ~22.5 KB gzipped) -
Store: document signal, selection, immutable tree ops, undo/redo with typing coalescing
-
Component library panel (grouped by
category, searchable, click or drag to add) -
Layer tree: drag to reorder and nest, respecting
acceptsChildrenand blocking cycles -
Props panel generated from the prop schema, with inline validation
-
Keyboard: select, move, indent/outdent, delete, duplicate, undo/redo;
aria-liveannouncements -
Writes the document into
textarea[name=page-content](only after the first edit) -
JSON view (validated apply; repairs unreadable content)
-
Unit tests for tree ops and the store (29 new); browser e2e harness and a 14-step editor suite (ADR 0008)
Follow-ups (done 2026-10-06, session 16):
- Collapse/expand containers in the layer tree (toggle, ←/→, collapse/expand all, reveal on selection, opens while hovering during a drag)
- Auto-scroll while dragging in long trees
- Copy/cut/paste of nodes, also between pages (Ctrl/⌘+C/X/V; clipboard text validated, fresh ids)
- Per-node labels (“Hero – Pricing”) in the layer tree and on the canvas chip (editor-only, never rendered)
Site integration (admin bar, view, preview) ✅ (2026-10-04 – 2026-10-06; two items dropped)
Section titled “Site integration (admin bar, view, preview) ✅ (2026-10-04 – 2026-10-06; two items dropped)”Drupal-style movement between the site and the dashboard. Works for every StudioCMS page type. Guide: admin-bar.md. Decision: ADR 0009.
-
getPage(): draft-safe page loading (fixes the draft leak, known issue #10), cache and robots headers -
getViewer(): StudioCMS session check on public routes, fail closed -
<AdminBar>: server-rendered, zero JS, nothing for anonymous visitors; Edit page, Add page, Dashboard, status, Log out - “View page ↗” in the Tapestry editor (
pageUrlPatternoption) - StudioCMS corner menu disabled correctly (
features.injectQuickActionsMenu); public JS 18.7 KB → 174 B - e2e site suite (10 steps): anonymous, forged cookie, editor drafts, headers, bar position, Edit ⇄ View round trip, Log out
“View page” on StudioCMS’s edit screen for all page types: not planned (user decision, 2026-10-06). StudioCMS’s edit screen has no extension point (augments only affect rendered content); it would need a StudioCMS patch. Tapestry pages have “View page” in the editor, and the admin bar links back from the site.- Preview of saved drafts on the real URL (
?tapestry-preview, editors only; admin bar link). Done with publishing, below. Shareable preview links for people without an account: not planned (user decision, 2026-10-06)- Report upstream:
bySlugdrafts (known issue #10),featureskey (known issue #5)
Phase 3: Visual canvas ✅ (2026-10-05)
Section titled “Phase 3: Visual canvas ✅ (2026-10-05)”Goal: WYSIWYG, like Drupal Canvas. Decision: ADR 0010.
- Canvas mode (editors only) with invisible node markers;
tapestry-rootwrapper - Editors-only render endpoint (
/_tapestry/render): same pipeline, same-origin, size-limited - Iframe canvas showing the real page (site layout + CSS); live swap on edit (debounced, stale requests aborted)
- Click to select, hover outlines, selection chip (drag handle, duplicate, delete), navigation blocked
- Drag from the library or layers onto the canvas; drag components directly on the page (or by the chip) to move them; geometry module with unit tests
- Selection sync both ways (tree ⇄ canvas, scroll into view)
- Viewport switcher (Desktop / Tablet / Mobile), full-screen mode with Save and Ctrl/⌘+S
- e2e canvas suite (17 steps, real mouse drags), including visual parity with the public page and endpoint security
Next for the canvas:
- Inline text editing directly on the canvas for rich text (ADR 0013) and plain text props (ADR 0024)
- Per-node partial re-render: a settings change re-renders just that component (2026-10-07)
- Run component client scripts after a live swap: new scripts run once per canvas page (islands hydrate) (ADR 0030, 2026-10-07)
- Empty containers: visible drop zone inside the canvas (canvas mode only; 2026-10-06)
- Keyboard-accessible canvas navigation: arrows select, Alt+arrows move, Enter edits text, Delete, duplicate, copy/cut/paste (shared with the layer tree; 2026-10-06)
Publishing: drafts, publish, history ✅ (2026-10-05)
Section titled “Publishing: drafts, publish, history ✅ (2026-10-05)”Tapestry pages only. Decision: ADR 0011.
- Stored page format 2 (published, draft, history); format-1 pages read as published
- Save keeps changes as a draft; visitors keep seeing the published version
- Publish button; status pill (Not published yet / Published / Unpublished changes)
- History of the 5 previous published versions (
historyLimitoption), Restore to draft - Discard unpublished changes
- Editors preview the draft on the real URL; never-published pages are a 404 for visitors
- Admin bar shows the publishing status with Preview draft / View published
- StudioCMS’s anonymous REST API redacted to published content (middleware; known issue #22)
- 9 unit tests for redaction, 13 for revisions; e2e publishing suite (11 steps)
Possible follow-ups:
- Scheduled publishing (publish at a date/time; applied by every reader once due, no background job; 2026-10-07)
- Side-by-side comparison of a history entry with the live version or the draft: change list + both versions on the real page (2026-10-07)
- “Publish” permission separate from “edit” (
publishPermission; enforced on the server; ADR 0022, 2026-10-07)
Media library ✅ (2026-10-06, @nascencestudio/medialibrary)
Section titled “Media library ✅ (2026-10-06, @nascencestudio/medialibrary)”Decision: ADR 0016. Moved to its own repository, nascencestudio/medialibrary, on 2026-10-08 (ADR 0037); its roadmap continues there.
- Uploads checked by content (images incl. AVIF and sanitized SVG, video, audio, documents), per-kind limits
- Remote videos (YouTube, Vimeo) by link, privacy-friendly embeds
- Dashboard Media page: grid, filters, search, drag-and-drop upload with progress, alt text, usage, delete with warning
- Picker dialog for other plugins; Tapestry
mediaprops and rich text “Insert media” - Local-disk storage, public serving with ranges and a sandbox CSP
- Admin settings (Plugins → Media Library → Uploads): size limits per kind within a developer ceiling, SVG on/off (ADR 0018)
- Replace file (keeps id, alt, tags, focal point, captions; new URL) (ADR 0019)
- Tags with a library filter (instead of folders)
- Captions/subtitles for uploaded videos (WebVTT; SRT converted; files rebuilt)
- Focal point for images (click or arrow keys; crop previews;
object-position) - Responsive images: resized WebP copies +
srcset(sharp), admin backfill for older images - Later / on request: S3 storage (the user has no use for it now), AVIF copies, video posters/duration, document page counts, captions for audio
Deployment ✅ (2026-10-06)
Section titled “Deployment ✅ (2026-10-06)”- Docker (non-root, read-only FS) + Caddy HTTPS for a Hetzner Cloud server (ADR 0017, guide)
- CI: checks, e2e on a fresh site, production image with a sharp check (ADR 0020); runs once the repo is on GitHub
- Dependabot for pinned action SHAs and dependencies (
.github/dependabot.yml: weekly, 3-day cooldown likeminimumReleaseAge, minor/patch grouped; active once on GitHub)
Phase 4: Rich content ✅ (2026-10-05 – 2026-10-07)
Section titled “Phase 4: Rich content ✅ (2026-10-05 – 2026-10-07)”- Image prop: the
mediaprop type with the media library (alt text kept on the media item) - Rich text prop (
richtext) with a per-field toolbar allowlist, ProseMirror editor, JSON storage,RichText.astro(ADR 0012, 2026-10-05) - Rich text follow-ups (2026-10-06): inline editing on the canvas (ADR 0013); admin-configurable toolbars (ADR 0014); “remove formatting” button
- Inline editing for plain
textprops on the canvas: the element is found automatically, with an optionaldata-tapestry-text-propmarker (ADR 0024, 2026-10-07). (The “floating toolbar” part was done with ADR 0013: the toolbar sits under the chip.) - Link prop: a page on this site (by id, follows renames; drafts hidden from visitors) or a web address, plus new tab (ADR 0025, 2026-10-07)
- List/repeater and object props: items with the same fields, one level of nesting, add/remove/reorder with undo (ADR 0026, 2026-10-07)
- Named slots (e.g. a two-column layout with
leftandright):slotson the definition,sloton children; canvas, tree and keyboard support (ADR 0027, 2026-10-07) - Reusable patterns / saved sections: saved copies, inserted from the library (click or drag); author/admin delete (ADR 0028, 2026-10-07). Linked (shared) patterns: later.
- Component thumbnails/previews in the library: live previews on hover/focus (sandboxed, site CSS) and optional
thumbnailimages (ADR 0029, 2026-10-07)
Phase 5: Production readiness
Section titled “Phase 5: Production readiness”- Interactive components: framework components with
client: 'load' | 'idle' | 'visible'(generated island wrappers; StudioCMS patch keeps component scripts; canvas runs new scripts) (ADR 0030, 2026-10-07) - Document migrations framework: component versions with prop migrations (lazy, on read),
replacesfor renamed components, format migrations (next format is 3) (ADR 0031, 2026-10-07) - i18n: one page per language in translation groups (
languagesoption, translations menu,getPage()language + translations, links follow the language) (ADR 0032, 2026-10-07). StudioCMS’s content-language rows were not usable (no dashboard support). - Permissions (who can use which components):
permissionon definitions; locked for lower roles in the editor; enforced on save (ADR 0033, 2026-10-08) - Visual diff between versions: see “Compare” in Publishing (2026-10-07)
- Accessibility audit of the editor (axe-core in e2e, both themes; fixes for outline, contrast, reduced motion); performance budget for public pages (
pnpm budget, in CI) (ADR 0034, 2026-10-08) - Publish
@nascencestudio/tapestryto npm with provenance: prepared (0.1.0, READMEs, LICENSE, release workflow with provenance/trusted publishing, StudioCMS patch shipped; ADR 0035); repositories set (nascencestudio/tapestry, nascencestudio/medialibrary, ADR 0037); media library 0.1.0 published 2026-10-09 and used from npm; Tapestry’s release next - Documentation site: Starlight in
website/, generated fromdocs/, deployed to GitHub Pages (ADR 0036, 2026-10-08)
Site structure
Section titled “Site structure”- Templates: shared header and footer parts built in the editor, combined by templates that pages
choose (Template menu), draft/publish/history for parts,
<Region>for layouts (ADR 0041, 0.5.0, 2026-10-15) - Menus:
@nascencestudio/tapestry-menus(menus edited in the dashboard; Menu and Breadcrumbs components for templates and pages; next)
Companion plugins
Section titled “Companion plugins”- SEO:
@nascencestudio/tapestry-seo(robots.txt with crawler categories, sitemap fromlistPublicPages(), ADR 0039, 2026-10-11); the editor’s SEO button for per-page settings (seooption,virtual:tapestry/seo-client, ADR 0040, 0.4.0, 2026-10-12)
Later / maybe
Section titled “Later / maybe”- Real-time collaboration (Canvas has it; it’s significant work)
- AI-assisted page building
- In-browser “code components” (Canvas has these; weigh carefully, since running editor-authored code is a large security surface)
Source: docs/roadmap.md (view on GitHub)