Skip to content

Commit 478ba83

Browse files
authored
docs(project): refresh plugin and feature guides (CoreBunch#181)
* docs(plugins): update plugin system guide * docs(plugins): refresh adjacent plugin references * docs(plugins): clarify sandbox runtime summaries * docs(editor): fix relative reference links * docs(forms): update native form module picker notes * docs(forms): align forms index summary * docs(architecture): fix stale reference drift * docs(ai): clarify sdk isolation rules * docs(editor): align router and tree references * docs(data): align content storage schema * docs(deploy): align release bundle install notes * docs(audit): align audit log contract * docs(publisher): align runtime pipeline details * docs(publisher): align architecture references * docs(publisher): update hole endpoint references * docs(mcp): document connector token expiry * docs(auth): align capability names * docs(transfer): clarify imported media variants * docs(router): avoid stale admin route count * docs(readme): align publisher runtime summary * docs(import): fix site import adapter breadcrumbs * docs(ui): align primitive catalog * docs(modules): align base module registry notes * docs(architecture): refresh gate catalog * docs(design): complete token catalog * docs(admin): update workspace preload counts * docs(ai): document content agent scope * docs(readme): refresh ai and capability counts * docs(mcp): remove future auth phase language * docs(dashboard): align widget guide with source * docs(spotlight): refresh command palette guide
1 parent 845cb8b commit 478ba83

93 files changed

Lines changed: 1107 additions & 615 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.production.example

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# credentials. SQLite mode does not use Postgres at all. Just run:
66
# docker compose -f compose.prod.yml -f compose.sqlite.yml up -d
77
# Copy this file when you want to customize HOST_PORT, DOMAIN (TLS), the image
8-
# to pull, or when you need AI credentials.
8+
# to pull, or when you need encrypted server secrets.
99
#
1010
# Postgres installs:
1111
# Copy this file to .env and set POSTGRES_PASSWORD to a real value:
@@ -19,8 +19,9 @@
1919
# build. Change it to instatic:local if you do not want a GHCR-shaped local tag.
2020
INSTATIC_IMAGE=ghcr.io/corebunch/instatic:latest
2121

22-
# ─── AI credential encryption ───────────────────────────────────────────────
23-
# REQUIRED before adding Anthropic/OpenAI/OpenRouter credentials in production.
22+
# ─── Reversible server secret encryption ───────────────────────────────────
23+
# REQUIRED before adding Anthropic/OpenAI/OpenRouter credentials, saving plugin
24+
# secret settings, or enabling TOTP MFA in production.
2425
# Generate with:
2526
# bun run scripts/generate-secret-key.ts
2627
INSTATIC_SECRET_KEY=replace-with-output-of-generate-secret-key

README.md

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,8 @@ Railway is the fastest way to get Instatic live. Pick a template, hit the button
5858
|---|---|---|---|
5959
| **Railway** · *Recommended* | SQLite | A single site — blog, portfolio, small business | [Deploy →](https://railway.com/deploy/instatic-cms-sqlite?referralCode=Zm9bVJ&utm_medium=integration&utm_source=template&utm_campaign=generic) |
6060
| **Railway** | Postgres | Multiple authors, managed backups, room to grow | [Deploy →](https://railway.com/deploy/instatic-cms-postgres?referralCode=Zm9bVJ&utm_medium=integration&utm_source=template&utm_campaign=generic) |
61-
| **Render** ||| *Coming soon* |
62-
| **Fly.io** ||| *Coming soon* |
63-
| **DigitalOcean** ||| *Coming soon* |
61+
| **Render** | SQLite or Postgres | Teams that prefer Render services, disks, and managed Postgres | [Guide →](docs/deployment/render.md) |
62+
| **Docker / VPS** | SQLite or Postgres | Bring-your-own server, Caddy TLS, custom backup policy | [Guide →](docs/deployment/vps.md) |
6463

6564
SQLite is the right default for most sites. Reach for Postgres when you've got a team of authors or want managed database backups.
6665

@@ -106,7 +105,7 @@ Your whole design system lives as data. Change one token and every page that use
106105
- **Templates** handle the shared chrome. One layout for the whole site, separate layouts per post type, and a real 404 page you design yourself. Content flows into an outlet, so a header and footer get written once and wrap everything.
107106
- **Loops** repeat a layout over a collection: your posts, your pages, your media, or anything a plugin exposes as a source. Give a loop a couple of variants and it alternates between them as it goes. Good for post lists, product grids, galleries.
108107
- **Forms that belong to your CMS.** Build a form out of semantic fields and the submissions land in your own data tables. Instatic can read the fields you placed and create the matching table for you. No third-party form service, no embed, no monthly fee for a contact form.
109-
- **An AI agent that actually edits the page.** Describe what you want and it builds it on the canvas as real, editable nodes, not a screenshot or a wall of code. It writes semantic HTML for structure and CSS for style, through the same import pipeline you use when you paste markup. 28 tools under the hood. Bring your own model: Claude, OpenAI, OpenRouter, or local Ollama. Your key, your model, your bill.
108+
- **An AI agent that actually edits the page.** Describe what you want and it builds it on the canvas as real, editable nodes, not a screenshot or a wall of code. It writes semantic HTML for structure and CSS for style, through the same import pipeline you use when you paste markup. A 35-tool Site scope builds pages; a 15-tool Content scope edits entries. Bring your own model: Claude, OpenAI, OpenRouter, or local Ollama. Your key, your model, your bill.
110109
- **Imports that hold up.** Paste raw HTML and get editable nodes. Or drop a whole static site — HTML, CSS, images, fonts — and Super Import turns it into pages, style rules, design tokens, and media. Every conflict is shown to you before anything is written, and the entire import is a single undo.
111110

112111
### 🗂 Manage
@@ -117,7 +116,7 @@ Your whole design system lives as data. Change one token and every page that use
117116
- **A Data workspace where you design your own collections.** At `/admin/data` you create custom post types and custom data tables with their own fields, then work the rows in a spreadsheet-style grid: search, sort, filter, bulk publish, bulk export. Custom post types come with a real editorial workflow — draft, scheduled, published — and version history on the published copy. Plain data tables are simple grids you can point at anything: the submissions from a form, a product catalog, a lightweight CRM, a list of testimonials. And every table you build is a content source a loop can render. Define a "Team" table once, loop it onto your about page, done.
118117
- **A content workspace for writing.** A focused surface for posts and collections, plus live mode so authors edit inside the real design of the site instead of a gray textarea.
119118
- **A media workspace that works like a file manager.** Folders and smart folders, bulk operations, usage tracking so you know where a file is actually used, replacement workflows, and pluggable storage adapters when you outgrow local disk.
120-
- **Access control that's real, not decorative.** Roles built from 36 capabilities, token-based sessions, TOTP two-factor with secrets encrypted at rest, account lockout with backoff after repeated failures, and step-up prompts before the dangerous stuff like deleting a user or signing out every device.
119+
- **Access control that's real, not decorative.** Roles built from 38 capabilities, token-based sessions, TOTP two-factor with secrets encrypted at rest, account lockout with backoff after repeated failures, and step-up prompts before the dangerous stuff like deleting a user or signing out every device.
121120
- **⌘K for everything.** A fuzzy command palette over the whole admin. Jump anywhere, do anything, without touching the mouse.
122121
- **Drafts stay drafts.** Unpublished edits never leak to a visitor. What you didn't publish, they don't see.
123122

@@ -129,19 +128,15 @@ Your whole design system lives as data. Change one token and every page that use
129128
- **An audit log that doesn't forget.** Every meaningful admin action writes a row: logins, content changes, role edits, plugin lifecycle. It's append-only, so it's a real record of who did what and when, not something anyone can quietly rewrite.
130129
- **Form data that's yours.** Submissions sit in your own tables. Query them, export them, build on them. No vendor in the middle.
131130

132-
This is the youngest pillar, and the one we're pushing hardest right now. First-party, privacy-respecting analytics are next. See the [roadmap](#early-on-purpose).
131+
The analytics surface today is intentionally operational: dashboard status, audit history, and owned form data instead of third-party visitor tracking.
133132

134133
### 🔌 Extend
135134

136-
<!-- TODO shot — extend-plugins.webp: Plugins page showing a plugin's permission prompts.
137-
<img src="docs/assets/readme/extend-plugins.webp" alt="The plugin system — sandboxed, permissioned, first-class" width="100%">
138-
-->
135+
Every CMS has plugins. The difference here is where backend plugin code runs.
139136

140-
Every CMS has plugins. The difference here is where they run.
137+
An Instatic plugin is a zip package with a manifest. Its server entrypoint runs in a per-plugin worker that hosts a **QuickJS-WASM sandbox**: no filesystem, no environment variables, no network at all unless the site owner grants it, one host at a time. Editor extensions and app-kind admin pages are different: they run in the admin window and require the explicit `editor.code` permission before install.
141138

142-
An Instatic plugin is a zip package with a manifest, and it runs inside a **QuickJS-WASM sandbox**. No filesystem. No environment variables. No network at all, unless the site owner grants it, one host at a time. A plugin can't read your secrets or phone home, because the sandbox never hands it the door. The classic "a plugin took down my site and emailed the database to a stranger" story doesn't run here.
143-
144-
Inside that sandbox the SDK is genuinely capable. A plugin can add:
139+
Through the SDK, a plugin can add:
145140

146141
- HTTP routes and its own admin pages
147142
- Storage and scheduled background jobs
@@ -156,17 +151,13 @@ Start with the [plugin system docs](docs/features/plugin-system.md) and the [tem
156151

157152
## Fast because there's almost nothing to load
158153

159-
<!-- TODO shot — clean-output.webp: devtools view-source of a published page next to the rendered page.
160-
<img src="docs/assets/readme/clean-output.webp" alt="A published Instatic page and its source — semantic HTML, compact CSS" width="100%">
161-
-->
162-
163-
A published Instatic page is mostly just a file sitting on disk. No framework to boot, no hydration step, no database round-trip on the common path. The browser pulls down semantic HTML and a compact stylesheet, and it's done. There's barely anything between the visitor and the content, so the pages feel instant.
154+
A published Instatic page is mostly just a file sitting on disk. No framework to boot, no hydration step, no database round-trip on the common path. The browser pulls down semantic HTML and compact CSS bundles, and it's done. There's barely anything between the visitor and the content, so the pages feel instant.
164155

165156
That speed isn't a setting you tune. It falls out of how publishing works, in three layers you never have to think about:
166157

167158
- **Static pages are baked straight to disk when you publish** and swapped in atomically. Visitors are served a file, not a render.
168-
- **Routes that genuinely change** hit an in-memory cache that's wiped wholesale on every publish, so nobody ever sees a stale page.
169-
- **The few truly per-visitor parts** are detected automatically and lazy-loaded by a runtime that weighs about 0.7 kB. Smaller than this paragraph.
159+
- **Routes that genuinely change** hit a versioned in-memory cache. Publishing bumps the version, so old entries miss lazily and nobody sees a stale page.
160+
- **The few truly per-visitor parts** are detected automatically and lazy-loaded by a runtime that weighs about 1.1 kB. Smaller than this paragraph.
170161

171162
What comes out the other end is plain HTML and compact CSS, all the way down. Nothing from the editor rides along: no React on your public pages, no editor runtime, no framework in the markup. And because it's just HTML and CSS, nothing holds your site hostage — you can read it, host it anywhere, or take it and leave. Full design: [the publisher](docs/features/publisher.md).
172163

@@ -228,7 +219,7 @@ One Bun server. A React admin built with Vite. A publisher that emits pages you'
228219
| **Server** | `Bun.serve` with a hand-written router |
229220
| **Database** | SQLite or Postgres — one `DbClient` interface, picked by `DATABASE_URL` |
230221
| **Validation** | TypeBox at every untyped boundary; schemas are the source of truth |
231-
| **Plugins** | QuickJS-WASM sandbox, owner-granted permissions |
222+
| **Plugins** | QuickJS-WASM backend sandbox, owner-granted permissions, explicit `editor.code` for admin-window code |
232223
| **AI** | Provider-agnostic drivers over raw HTTP/SSE, no vendor SDKs |
233224
| **Output** | Semantic HTML, compact CSS, baked static files plus auto-detected dynamic holes |
234225

docs/CONVENTIONS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ The `Related` section is mandatory. It tells the reader what to read next and wh
150150

151151
### Hard rules
152152

153-
1. **Anchor every claim to a real path.** Not "the editor store" — `src/editor/store/siteSlice.ts`. Not "the page tree mutations" — `src/core/page-tree/mutations.ts`. Paths give agents the next thing to read.
153+
1. **Anchor every claim to a real path.** Not "the editor store" — `src/admin/pages/site/store/slices/site/helpers.ts`. Not "the page tree mutations" — `src/core/page-tree/mutations.ts`. Paths give agents the next thing to read.
154154

155155
2. **Use the present tense and the indicative mood.** "The publisher converts the page tree to HTML." Not "The publisher should convert ..." or "The publisher will convert ...". If the behavior isn't true today, don't document it.
156156

docs/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ Three categories, three voices:
151151
| [features/mcp-connectors.md](features/mcp-connectors.md) | Instatic as an MCP server — external AI clients drive the CMS over MCP |
152152
| [features/templates.md](features/templates.md) | Entry templates + dynamic bindings + token interpolation |
153153
| [features/loops.md](features/loops.md) | `base.loop` + loop entity sources |
154-
| [features/cms-native-forms.md](features/cms-native-forms.md) | Visual form primitives, presets, secure public submissions |
154+
| [features/cms-native-forms.md](features/cms-native-forms.md) | Visual form primitives and secure public submissions |
155155
| [features/media.md](features/media.md) | Media workspace, upload pipeline, storage adapters |
156156
| [features/audit-log.md](features/audit-log.md) | Audit event catalog + recording new actions |
157157
| [features/site-transfer.md](features/site-transfer.md) | Export / import CMS bundle (JSON round-trip between instances) |
@@ -216,7 +216,7 @@ Quick map from "where do I look for X?" to the canonical file:
216216
| Plugin SDK | `src/core/plugin-sdk/` |
217217
| Plugin permission catalog | `src/core/plugin-sdk/capabilities.ts` |
218218
| Plugin manifest parser | `src/core/plugins/manifest.ts` |
219-
| Plugin sandbox host | `server/plugins/quickjs/vm.ts`, `server/plugins/modulePackVm.ts` |
219+
| Plugin worker + sandbox host | `server/plugins/pluginWorker.ts`, `server/plugins/host/workerPool.ts`, `server/plugins/quickjs/vm.ts`, `server/plugins/modulePackVm.ts` |
220220
| Publisher | `src/core/publisher/` |
221221
| CSS value sanitiser | `src/core/css-sanitize/sanitiseCssValue.ts` |
222222
| TypeBox helpers | `src/core/utils/typeboxHelpers.ts` |

0 commit comments

Comments
 (0)