-
-
Notifications
You must be signed in to change notification settings - Fork 486
Comparing changes
Open a pull request
base repository: CoreBunch/Instatic
base: v0.0.4
head repository: CoreBunch/Instatic
compare: v0.0.5
- 12 commits
- 150 files changed
- 2 contributors
Commits on Jun 13, 2026
-
fix(publisher): render current entry body in any content outlet (#62)
A base.outlet only rendered the post body when the node carried a persisted dynamicBindings.html overlay, which was set in exactly one place: the auto-seeded default template. A hand-dropped outlet (custom template) had no binding, so the publisher filled it with nothing and it rendered as an empty <main data-instatic-content-region></main> — on the published page, the content preview, and the Live Canvas alike. An outlet is, by definition, the hole the current entry's body flows into; there is no UI to bind it and the binding is always the same. Apply it implicitly via effectiveNodeBindings() at the shared resolution layer so every outlet renders the body, and drop the now-redundant persisted binding from the seed (single source of truth). Outside an entry route the entry stack is empty, so the binding stays inert and an everywhere layout's outlet still hosts a whole page. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for b9ee769 - Browse repository at this point
Copy the full SHA b9ee769View commit details
Commits on Jun 16, 2026
-
fix(canvas): render base.text tag:none as bare text to match publishe…
…d DOM (#63) * fix(canvas): render base.text tag:none as bare text to match published DOM A `base.text` node with `tag: none` publishes as bare text (no element) but the canvas wrapped it in a `<span>`. Descendant selectors such as `.ist-404__num span` then matched the phantom span in the editor while leaving the published page untouched — e.g. the 404 template's two `tag: none` "4"s rendered orange in the builder but black on the published page. The canvas now renders `tag: none` as bare text + `<br>` breaks, exactly like the publisher (`src/modules/base/text/index.ts`), so the canvas DOM equals the published DOM. This is the same canvas-equals-published principle that drove removing the per-node wrapper `<div>`. Trade-off: a `tag: none` node owns no element, so it has no in-canvas selection ring / hover / inline-edit; it is selected via the Layers panel and edited via the Properties "Text" field. The inline-edit branch still hosts a `<span>` for an active session, which is unreachable from the canvas for `tag: none` (no element to double-click). Verified live in the editor: the 404 template's "4"s now render black and the "0" orange, matching the front end; `.ist-404__num` DOM is `4<span>0</span>4`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(canvas): extract BareText component for tag:none rendering Satisfies react-doctor/no-render-in-render: a named component returning a fragment replaces the inline render helper. Still adds no host element, so the tag:none canvas DOM remains bare text matching the published page. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for 1a762ec - Browse repository at this point
Copy the full SHA 1a762ecView commit details -
fix(export): make the export size estimate server-accurate, including…
… media (#64) The "Estimated size" line in the Export dialog was a client-side guess that ignored media entirely (`mediaAssetCount` was hardcoded to 0) and underestimated content ~10x (flat 8 KB shell + 1.5 KB/row constants). Toggling "Media files" never moved the number, which read as "media isn't exported" — but media *is* exported correctly; only the estimate was wrong. Replace the heuristic with an exact, server-computed estimate that reuses the export's own selection logic as a single source of truth: - New `POST /admin/api/cms/export/estimate` runs the identical table/row/media selection as the real export but computes the byte size instead of streaming the bundle. It never reads media files off disk or base64-encodes them: it serializes the real selection with empty `bytesBase64` strings and adds each asset's analytic Base64 length (4*ceil(n/3)). Because Base64 is ASCII, this equals the real bundle byte length exactly. - `export.ts` is refactored to share `buildBundle` + media-metadata mapping between the download and estimate paths, so they cannot drift. - `useExportEstimate` now fetches this endpoint (debounced, cancellable) and formats the result; the dialog mirrors the exact ExportRequest it will send. Verified live against a real site (19 images, ~69 MB): estimate without media = 183,618 B, with media = 96,769,329 B — byte-identical to the actual download. Tests assert estimate === real download size for the no-media, no-shell, and embedded-media cases. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for 2eb0999 - Browse repository at this point
Copy the full SHA 2eb0999View commit details
Commits on Jun 17, 2026
-
docs(readme): rewrite the GitHub front page in a human voice with dee…
…per feature detail (#69) Replace the AI-flavored marketing copy with plainer, more human prose and expand the feature coverage. Highlights: - New anti-stack opening; drops the WordPress-vs-Webflow framing. - Deploy section is now a provider table (Railway recommended; Render, Fly.io, DigitalOcean marked coming soon for future one-click templates). - Deeper feature pillars (Design/Build/Manage/Analyze/Extend), including a dedicated Data workspace bullet (custom post types, custom tables, form collection, CRM, loop sources). - Publisher section reframed around speed + the three-layer pipeline. - Roadmap heading renamed 'This is the inception' -> 'Early, on purpose'; in-page anchors updated to match. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for 8e01106 - Browse repository at this point
Copy the full SHA 8e01106View commit details -
feat(data): granular full-site export dialog + cmd+k Export (#68)
* feat(data): granular full-site export dialog with per-row selection Rebuild the Data-workspace Export dialog as a sibling of the Site Import modal: a two-column category navigator + detail pane, everything selected by default so the primary action is a one-click full export. Content tables expose a per-row checklist (pages/posts/components/…) with per-table All/None; shell, media, folders and redirects are all-or-nothing toggles. Make a full export actually round-trip into a fresh instance identically by extending the bundle to also carry the media folder tree (+ each asset's folder membership) and published-URL redirects. Add includeMediaFolders / includeRedirects flags, an /export/summary endpoint for category counts, extended preview totals + import counters, and replace-strategy restore (parent-first folder ordering, post-write membership assignment, redirects inserted after their target rows). Credentials and instance-runtime state are deliberately excluded from the portable bundle. Replace the flat tables[]+rowIds export request with a unified tables: { tableId, rowIds? }[] model (omit → full export; per-entry rowIds → subset). A new round-trip test proves folders, membership and redirects survive export → import into a pristine instance. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(spotlight): make Export site reachable from cmd+k everywhere Hoist the Export dialog to a global modal (SiteExportModal) mounted at the admin shell and driven by adminUi.siteExport, mirroring SiteImportModal. Add a "Export Site" Spotlight command (data.export capability, available on any workspace) so export is reachable from cmd+k anywhere, and route the Data workspace's Export button + grid "Export selected" through the same openSiteExport(context) store action instead of a page-local dialog. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(site-transfer): add Export dialog screenshots Full-export overview (category navigator + detail) and the per-row content checklist, for the PR / feature doc. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>Configuration menu - View commit details
-
Copy full SHA for cca3acd - Browse repository at this point
Copy the full SHA cca3acdView commit details -
refactor(editor): make saved layouts the single source of truth (#66)
Layouts now exist only as SavedLayout rows in data_rows (table_id=layouts). Removed the code-defined insertion presets (7 layout + 2 form templates) and all their wiring; the inserter's Layouts group is sourced solely from site.layouts. Any built-ins we ship later are seeded rows in that same table, indistinguishable from a user save. Also closes the save-timing hole that dropped a just-saved layout (and any recent unsaved edit) when leaving the editor before the 30s autosave: - usePersistence flushes pending changes on editor unmount (SPA navigation), not just on beforeunload. - "Save as layout" persists immediately via EDITOR_SAVE_REQUEST_EVENT rather than waiting for the autosave debounce. Deleted insertionPresets.ts, formPresets.ts, useInsertPreset.ts, useInsertFormPreset.ts, and LAYOUT_WIRES. Removed the 'layout' inserter item kind across the model, dialog, notch, item button, and the user-preference schema. Docs and tests updated. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for a17aed3 - Browse repository at this point
Copy the full SHA a17aed3View commit details -
fix(content): route collection create/update/delete through step-up (#72
) Creating, updating, or deleting a content collection POSTs/PATCHes/DELETEs the step-up-gated data-tables endpoints (they change the public route surface). The Content page called the workspace mutations directly without useStepUp, so for accounts with step-up auth (or MFA) enabled the server's `401 { error: 'step_up_required' }` leaked into the dialog as raw red text instead of opening the password re-entry dialog. Mirror the Data page: wrap all three collection mutations in runStepUp, and have both collection dialogs swallow `step_up_cancelled` so backing out of the prompt is a silent no-op. Update/delete now bypass withEntryOp (whose generic catch would surface the cancellation as an error). Adds contentCollectionStepUp.test.tsx covering the create → step-up → retry flow and asserting the raw error code never reaches the UI. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for 34b70f1 - Browse repository at this point
Copy the full SHA 34b70f1View commit details -
feat(data): split system/custom table capabilities and lock system ta…
…bles (#71) * feat(data): split system/custom table capabilities and lock system tables Split the single `data.tables.read`/`manage` pair into a system-vs-custom family so a persona (e.g. the seeded Client role) can see and manage custom tables without ever seeing the four internal system tables: data.custom.tables.read / data.custom.tables.manage data.system.tables.read / data.system.tables.manage Server enforcement (the UI mirrors it, never the sole gate): - GET /data/tables filters per family — system tables are returned only to holders of a system read cap; content-row callers (loop pickers) still see the full list. Single-table reads gate the same way. - PATCH /data/tables/:id is kind-aware (canManageTable) and runs assertSystemTableUpdateAllowed: a system table's identity (name, slug, route base, labels, kind) and built-in fields are frozen for EVERYONE, while custom fields and the primary field stay mutable. - Row writes reject built-in cell edits on the structural system tables (pages/components/layouts) via lockedBuiltInCellKey; posts built-ins and all custom fields stay editable. The editor writes those trees via its own endpoints, so this never blocks it. Client: - TableSettings renders a reduced panel for system tables (Display + Fields only; General/Routing/Kind/Danger hidden) with a "system-managed" note. - fieldGuards locks built-in fields on system tables (no edit/delete/reorder) while custom fields and "Add field" stay available. - Grid/inspector cells render built-in values read-only on structural system tables via isBuiltInValueLocked. Shared rules live in @core/data/systemTableGuard so server and client agree. Roles resynced in both dialect migrations + SYSTEM_ROLES (owner/admin get all four; client gets data.custom.tables.read only). Docs + tests updated; new unit + capability-harness integration coverage added. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(data): group sidebar by system/custom; drop system-table note - DataSidebar splits tables into "System" and "Your tables" groups (labels show only when both groups are present, so a custom-only persona sees a plain list). - Remove the explanatory banner in TableSettings for system tables — the reduced panel speaks for itself. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(data): move sidebar actions into section/panel headers Match the Site explorer's header pattern: - Export / Import become icon buttons in the "Data tables" panel header (`headerActions`) instead of full-width footer buttons. - "New table" becomes an icon button in the "Custom tables" section header. - Section headers (System / Custom tables) carry a count, styled like the Site explorer sections. The Custom section always renders (empty → "None yet") so the New-table action has a home; the System section renders only when the user can see system tables. - Rename "Your tables" → "Custom tables". Footer removed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for 65bdfb8 - Browse repository at this point
Copy the full SHA 65bdfb8View commit details -
Configuration menu - View commit details
-
Copy full SHA for b5846a2 - Browse repository at this point
Copy the full SHA b5846a2View commit details -
fix(editor): make Settings modal and toolbar trailer truly global (#67)
The Settings modal is openable from every admin route, but its General and Publishing sections read site data straight off the heavy editor store, which is only hydrated on the Site editor. On Content / Data / Media / Plugins / Users / Account those sections rendered a permanent skeleton — the modal was "global" in name only. Separately, the settings cog was injected per-layout: Site, Plugins/Users/Account, and Content had it, but Media and Data did not. Fix both: - Hoist SettingsButton into the Toolbar shell so the trailer (Settings → Open live page → Account) is identical on every route, the same way the left nav is. Remove the per-layout/per-page injections (AdminCanvasLayout, AdminPageLayout, ContentToolbar) and the now-dead ToolbarDivider. - Add useSiteSettingsController: one uniform site-settings source that delegates to the editor draft on the Site editor (joins autosave) and loads/saves via cmsAdapter (shell-only write + site-reload event) everywhere else. General and Publishing consume it instead of the editor store directly, so they work on every admin page without forcing editor-store hydration into the light layouts. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for 6988c18 - Browse repository at this point
Copy the full SHA 6988c18View commit details -
feat(agent): add document-targeted site tools
* feat(agent): add document-targeted site tools * fix(agent): update snapshot token benchmark read surface
Configuration menu - View commit details
-
Copy full SHA for ab5f3e8 - Browse repository at this point
Copy the full SHA ab5f3e8View commit details -
Configuration menu - View commit details
-
Copy full SHA for c001430 - Browse repository at this point
Copy the full SHA c001430View commit details
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff v0.0.4...v0.0.5