Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ PORT=3001
UPLOADS_DIR=./uploads
STATIC_DIR=./dist

# Where site runtime dependencies (the packages a site's `package.json`
# declares) are installed for bundling. Default: `instatic-runtime-cache` in
# the OS temp dir. Temp cleaners may reap old files there; the server detects
# a reaped package and reinstalls on demand (needs registry access), so set a
# persistent path to avoid that. It must NOT be under UPLOADS_DIR, which is
# served publicly at /uploads/*.
# RUNTIME_CACHE_DIR=./.tmp/runtime-cache

# ─── AI credential encryption ───────────────────────────────────────────────
# Local dev auto-creates .tmp/secret.key. Production deployments must set
# INSTATIC_SECRET_KEY to the output of:
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ All notable changes to Instatic will be documented here.

This project is pre-1.0. Breaking changes may appear in minor or patch releases until a stable release line exists.

## Unreleased

### Editor, import, and publishing

- Added **God Mode**, a per-user editor mode for structure editors that replaces the properties sidebar with a Code Dock of three panels: an editable HTML projection of the selection or the whole page (edits apply live, with a confirm for destructive or stale changes, reverse selection sync from the cursor, and breadcrumbs), a CSS panel over the style-rule registry, and a JS panel editing the page script. Each panel formats with Prettier, offers context-aware completions (classes, tokens, data fields), and can expand into a full-size editor. Enable it under Settings → Preferences; toggle with ⌘⇧G.
- Fixed the site editor crashing the browser tab ("Aw, Snap") on large sites. Two causes: every live HTML apply in God Mode rewrote the whole projected subtree into the collaboration document, and the undo history retained each rewrite until the tab ran out of memory; and connecting to the collaboration server re-assembled the whole site once per page instead of once, so a 20-page site did seconds of blocked work and hundreds of megabytes of allocation at load. A live apply now writes only what changed, and the site is assembled once.
- Made the toolbar's "N code errors" status a button: it opens the first error's file in the Code Editor, whose Problems list shows every error with its `file:line:column`. Before, the count was a passive label and the Problems list only appeared once a script file was open.
- Fixed publish validation failing with `Could not resolve "<package>"` for a dependency the site declares. The runtime dependency cache lives in the OS temp directory, and temp cleaners delete package files by age while leaving the install-complete marker behind, so the server kept trusting an emptied cache. A cache now counts as installed only while every locked package is on disk, and a reaped one is reinstalled on demand. `RUNTIME_CACHE_DIR` moves the cache to a persistent path.

## 0.0.18 - 2026-09-01

### Security
Expand Down
6 changes: 4 additions & 2 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ Three categories, three voices:
| [features/modules.md](features/modules.md) | Module engine, defining first-party blocks |
| [features/dashboard.md](features/dashboard.md) | Dashboard workspace, widgets, grid, customize mode |
| [features/spotlight.md](features/spotlight.md) | Cmd+K command palette |
| [features/god-mode.md](features/god-mode.md) | God Mode: Code Dock (HTML \| CSS \| JS) replacing the properties sidebar |
| [features/agent.md](features/agent.md) | AI agent integration and provider-agnostic runtime |
| [features/mcp-connectors.md](features/mcp-connectors.md) | Instatic as an MCP server — external AI clients drive the CMS over MCP |
| [features/templates.md](features/templates.md) | Entry templates + dynamic bindings + token interpolation |
Expand Down
6 changes: 4 additions & 2 deletions docs/editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -553,9 +553,11 @@ contract on the right.

`src/admin/pages/site/sidebars/RightSidebar/RightSidebar.tsx`. Accepts a `mode` prop (`'site' | 'hidden'`):

- `'site'` — expands when a node or class is selected AND the panel is docked AND not collapsed. Determined by `selectRightSidebarExpanded` (`src/admin/pages/site/store/store.ts`).
- `'site'` — expands when a node or class is selected AND the panel is docked AND not collapsed AND God Mode is off. Determined by `selectRightSidebarExpanded` (`src/admin/pages/site/store/store.ts`).
- `'hidden'` — always collapsed (site viewer; no `pages.draft.save` capability).

While **God Mode** is active the docked right sidebar is suppressed entirely and the bottom **Code Dock** (HTML | CSS | JS panels) takes over as the styling surface; Properties stays reachable as a floating window. The CSS panel is a live two-way projection of the style-rule registry (edits apply through `applyStylesheetEdit`, one undo step per flush). See [`docs/features/god-mode.md`](features/god-mode.md).

`isExpanded` is derived from synchronous editor store state only — never from async prop availability. This means the sidebar lands at its final width on the very first render with no transition.

Property controls are driven by the selected node's module schema (`src/core/module-engine/`).
Expand Down Expand Up @@ -591,7 +593,7 @@ The sidebar shell expands/collapses by animating `--*-panel-width`. The panel sl

`src/admin/pages/site/toolbar/`:

- `PublishButton`, `PublishActionGroup` — publish current site / page
- `PublishButton`, `PublishActionGroup` — publish current site / page. The status chip beside Publish (draft synced, connecting, checking code, N code errors) is a passive `role="status"` label except when code errors name a file: then it is a button that opens the first error's file in the Code Editor, whose Problems list shows every error with its `file:line:column` (gated by `src/__tests__/toolbar/publishStatusAction.test.tsx`).
- `SettingsButton` — opens the Settings modal (see below)
- `ZoomControls` — canvas zoom
- `ModulePickerDropdown` — opens the module inserter modal
Expand Down
4 changes: 3 additions & 1 deletion docs/features/editor-preferences.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,12 @@ Why a catalog (not hand-rolled per-preference code):
- **Type-safe ids.** `as const` preserves the literal union type. `useEditorPreference('layersShowTag')` compiles, `useEditorPreference('layersShowtag')` does not.
- **Defaults can't drift.** The schema and `DEFAULT_EDITOR_PREFS` are derived from the catalog at module load. There is no separate "registered" list to keep in sync.

Boolean entries may declare a **capability gate**: `gate: 'structure-edit'` hides the row from users failing `canEditStructure` (`src/admin/access.ts`). The gate hides the Settings row only — the feature the preference unlocks must also self-gate (see the `godMode` preference and [`god-mode.md`](god-mode.md)).

The discriminated union has three branches:

```ts
interface BooleanPreferenceDef { id, type: 'boolean', category, label, description, default: boolean }
interface BooleanPreferenceDef { id, type: 'boolean', category, label, description, default: boolean, gate? }
interface SelectPreferenceDef { id, type: 'select', category, label, description, options, default: string }
interface DynamicSelectPreferenceDef { id, type: 'select-dynamic', category, label, description, optionsSource, default: string }

Expand Down
Loading