-
Notifications
You must be signed in to change notification settings - Fork 142
Permalink
Choose a base ref
{{ refName }}
default
Choose a head ref
{{ refName }}
default
Comparing changes
Choose two branches to see what’s changed or to start a new pull request.
If you need to, you can also or
learn more about diff comparisons.
Open a pull request
Create a new pull request by comparing changes across two branches. If you need to, you can also .
Learn more about diff comparisons here.
base repository: CoreBunch/Instatic
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.0.6
Could not load branches
Nothing to show
Loading
Could not load tags
Nothing to show
{{ refName }}
default
Loading
...
head repository: CoreBunch/Instatic
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.0.7
Could not load branches
Nothing to show
Loading
Could not load tags
Nothing to show
{{ refName }}
default
Loading
- 5 commits
- 123 files changed
- 2 contributors
Commits on Jun 29, 2026
-
feat(framework): import Core Framework defaults from onboarding (#91)
* feat(framework): import Core Framework defaults from onboarding Add a Core Framework default-preset importer and wire it into the dashboard onboarding "framework" step. Engine (src/core/framework/coreFrameworkPreset.ts): - buildCoreFrameworkColorSettings() maps the Core Framework default color system (6 groups / 13 tokens — Brand, Background, Text, Base, Neutral, Status) into FrameworkColorToken[]: hsla values, dark-mode pairs, transparent steps, and per-token utility kinds from each token's `gen` list. Shades/tints are generated from a count (schema-native). - buildCoreFrameworkSettings({ includeUtilities }) returns a full FrameworkSettings (colors + typography + spacing + Core Framework preferences). Typography/spacing reuse the existing CF-mirroring defaults. Two import modes: - Full framework — every generated utility class plus :root variables; tree-shaking off so the whole utility set ships in framework.css. - Variables only — the same :root variables (base, shades, tints, transparent steps, scale clamps) with color utilities off and the typography/spacing class generators dropped. Onboarding UI: - FrameworkImportModal presents the two modes as role="radio" cards in the shared Dialog, loads the site, drops the built settings onto settings.framework, and saves the shell only (pages untouched). - The dashboard onboarding "framework" step opens the modal; the panel owns the modal so DashboardPage stays at its size budget. - useOnboardingState now exposes refresh() so the step flips to done after import. Adds FrameworkSettings to the framework schema (source of truth) and a §8.14 button-primitive allowlist entry for the radio cards. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * style(dashboard): refine framework-import card states and typography - Card backgrounds use overlay tints: idle --overlay-5, hover --overlay-10, active --overlay-20 (the previous active state relied on a box-shadow token used as a color, which rendered nothing). - Bigger, bolder, brighter text: titles --text-xl/700, descriptions --text-m/500 in --text, weight-500 lede. - Cleaner bullet list: mint accent checkmark icons instead of grey dots. 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 6f09654 - Browse repository at this point
Copy the full SHA 6f09654View commit details -
fix(security): harden sanitizers and regexes flagged by CodeQL (#94)
* fix(security): harden sanitizers and regexes flagged by CodeQL Address CodeQL code-scanning alerts across the sanitization and string-handling surfaces: - svgSanitize (upload boundary): close-tag regexes now match `</script foo>` / `</script\t\n>` / `</script/>` (bad-tag-filter), and stripping iterates to a fixpoint instead of a fixed 2 passes so split-tag obfuscation (`<scr<script>ipt>`) cannot survive. Adds the first test for this boundary. - sanitize.ts fallback: same close-tag fix + fixpoint loop in the no-DOMPurify-runtime path; plain-text post-strip reuses it. - markdownDocument.decodeEntities: decode `&` last to stop the `&lt;` -> `<` double-unescape (js/double-escaping). - siteItemNames: drop dynamic RegExp for startsWith/slice. - scaleModule / dependencyResolver: replace -> replaceAll. - htmlPagePlan importer: harden script close-tag match. - arch gate: cms-handlers-capability-gated skips __tests__ dirs. Verified: bun run build, bun run lint, bun test (5741 pass). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(security): pair block+opener strips in sanitize.ts fallback CodeQL still flagged stripHtmlFallback (js/incomplete-multi-character- sanitization) because the generic `<[^>]*>` tag strip isn't credited with removing a residual `<script` / `<style` opener left by block removal. Mirror the proven server SVG sanitizer: each block regex is now paired with an explicit opener regex (`<script…>` / `<style…>`), making the dangerous substring provably gone — the same shape CodeQL already accepts in svgSanitize.ts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(security): extract stripHtmlOnce so CodeQL sees the fixpoint CodeQL's incomplete-multi-character-sanitization didn't credit the inline chained-replace loop body as a fixpoint, re-flagging the same lines. Mirror the exact structure CodeQL already accepts in svgSanitize.ts: extract the replace chain into stripHtmlOnce(), and loop `current = stripHtmlOnce(current)` to a fixpoint. Behavior unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(security): per-regex do-while fixpoints in sanitize.ts fallback CodeQL evaluates each .replace() independently and only credits a replace that is itself looped to a fixpoint — an outer loop around a chain, or the chain in a helper, left every individual replace flagged. Restructure stripHtmlFallback into three single-literal-regex do-while-until-stable loops (script block, style block, remaining tags), the exact shape CodeQL's qhelp documents as the complete fix. Behavior unchanged: script/style content is still removed (covered by the no-DOM server-runtime test). 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 d32a262 - Browse repository at this point
Copy the full SHA d32a262View commit details -
feat(ai): MCP connectors — expose CMS tools to external AI clients (#109
) * chore(ai): add MCP SDK + fetch-to-node, scope SDK isolation gate to drivers only Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(ai): MCP connector model, token hashing, store + migration 018 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(content): extract actor-agnostic page-tree service; plugin handler delegates Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(ai): page-tree MCP tools + capability-filtered MCP registry Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(ai): MCP bearer auth, capability-scoped server, Web-standard HTTP transport mounted at /_instatic/mcp Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(ai): MCP connector CRUD handlers (list/create/revoke) with privilege floor + audit Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(admin): MCP connectors tab — create/list/revoke with capability picker + client snippets Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(ai): document MCP connectors; scope SDK gate note; fix Button title gate Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(ai): deterministic end-to-end MCP flow (stateless initialize/list/call) over the real handler Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(ai): type the MCP e2e RPC responses (drop explicit any) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(admin): MCP connector dialog reuses the Role dialog capability picker The capabilities list collided with the AiPage two-column field grid. Switch the dialog to the SiteCreateDialog form layout + the UsersPage capability-picker styles + shared CAPABILITY_META, grouped Read/Write, for visual consistency with the role management dialog. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(admin): extract shared CapabilityPicker used by Role + MCP dialogs Move the role dialog's capability checklist into a shared, presentational `@admin/shared/CapabilityPicker` (+ co-located CAPABILITY_META). RoleDialog and the MCP connector dialog both consume it, so they stay visually consistent and the markup/CSS lives in one place. UsersPage.module.css keeps only the role identity grid; users/utils/capabilities.ts keeps only the role grouping. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(ai): MCP live editor bridge — expose the full tool catalog via an open editor Browser-execution editor tools (HTML/CSS authoring, design tokens, page lifecycle, content CRUD, code assets, live-DOM reads) have no server impl — they run in the editor app. This relays MCP calls for those tools to the connector owner's open editor and awaits the result, reusing the chat bridge machinery wholesale (createBridge / resolveBridgeToolResult / /tool-result). - server/ai/mcp/editorBridge.ts: per-user bridge registry + NDJSON stream. - GET /admin/api/ai/editor-bridge: the stream the editor holds open. - MCP registry now exposes the full deduped catalog; server.ts routes browser tools to the live bridge (clear 'open the editor' error when none connected). - src/admin/.../useEditorMcpBridge.ts: editor-side listener (mounted in SitePage) running executeAgentTool + postToolResult, with reconnect. - MCP picker expanded to all tool-backed editing capabilities. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(ai): headless read_styles tool + clearer MCP results + write-flush + sharper descriptions Addresses live-use friction: - read_styles: returns the design system as a CSS stylesheet (tokens + classes) read straight from the DB via the publisher emitters — headless, no editor, no snapshot. Replaces the snapshot-dependent list_tokens (excluded from MCP along with list_breakpoints, which silently returned nothing over MCP). - MCP success with no payload now reads as {ok:true}, not the literal 'null', so mutating tools (deleteNode) report unambiguous success. - The editor bridge flushes the draft save after a write tool, so a follow-up headless read sees the change instead of stale state (fixes the duplicatePage 'looked like it failed' race). - Sharpened read_page_tree/mutate_page_tree descriptions to steer the agent (headless-by-id vs editor HTML/CSS authoring; pointer to read_styles). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(ai): forward MCP tool images (render_snapshot PNG was dropped) The MCP CallTool result emitted only text, discarding output.images — so render_snapshot's screenshot never reached the client. Forward images as MCP image content blocks. Adds an integration test relaying render_snapshot through the editor bridge and asserting the PNG arrives as an image block. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(ai): delete headless read_page_tree/mutate_page_tree — one source of truth These MCP tools (added earlier this branch) edited the DB directly, creating a second copy of each page with identical node ids. Mixed with the open editor's browser tools they desynced, and the editor's autosave clobbered the headless write (data loss the agent reproduced). Superseded by the live editor bridge: ALL page editing now goes through the editor store (browser tools), persisted by the existing save-flush. Removed the two tools + their registry wiring; tests repointed to the headless content reads. treeService stays — the plugin RPC (cms.content.tree.*) still uses it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(ai): editor MCP bridge self-heals — never permanently stops on auth blip The reconnect loop set stopped=true on a 401/403, so a transient auth failure during a dev-server restart silently killed the bridge for the whole session ('editor open but MCP can't see it'). Now it always retries (longer backoff for auth failures) and logs on connect, so the bridge survives restarts and brief session blips. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(ai): Tier 1 MCP tool improvements — list_breakpoints, read_styles summary, insertHtml created map - list_breakpoints: headless (reads the site shell) — fixes 'guessed desktop'; replaces the snapshot-based version that returned nothing over MCP. - read_styles: format:'summary' returns a compact class catalog (selector + referenced token vars, no declarations) for cheap scanning before editing. - insertHtml now returns 'created' — every inserted node { id, moduleId, classes } — so the agent can target nested nodes without re-dumping the tree. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(ai): Tier 3 — get_context tool (editor connected? which templates wrap pages?) Headless orientation tool: reports whether a live editor is connected (browser tools need it) and which everywhere/post-type templates wrap pages — the two things that silently confused live use. Reads bridge presence + template rows from the DB. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(ai): consistent snake_case + site_/content_ prefix for all agent/MCP tools Standardizes the whole agent toolset (shared by the built-in panel and MCP) on snake_case with a domain prefix, so the tool list self-groups and humans+agents can tell at a glance what's site vs content: insertHtml→site_insert_html, applyCss→site_apply_css, deleteNode→site_delete_node, addPage→site_add_page, render_snapshot→site_render_snapshot, read_styles→site_read_styles, create_document→content_create_document, list_collections→content_list_collections, … get_context stays unprefixed (cross-cutting). The old site/content list_documents name collision is resolved into distinct prefixed names. Scoped strictly to agent tool-name references (server defs, both executors, the panel row formatter, prompts, MCP registry/tools, SSOT gate, tests, docs) — never the identically-spelled TreeOperation kinds or editor-store methods. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(ai): Tier 2 — scoped render_snapshot via iframe + importer no double-prop render_snapshot: the canvas renders each breakpoint inside an <iframe> (the data-breakpoint-id is on the host wrapper, the nodes live in the iframe's document). The capture searched the host frame, so scoped node lookups never matched and full captures grabbed the empty wrapper. Now it resolves the breakpoint's iframe and uses contentDocument as the node-lookup + screenshot root, and defaults to the active breakpoint (not the first DOM frame, which is mobile in a mobile-first layout). Scoped site_render_snapshot({nodeId}) and the right-viewport full capture now work. HTML importer: a node that recurses into child nodes no longer also keeps a flattened 'text' prop — children are the source of truth. Fixes a loop <a> wrapping spans/tokens that got BOTH a text prop and children (ambiguous, double-render risk). Mirrors the conditional heading/label rules. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(ai): site_insert_html 'created' was always empty (stale pre-insert snapshot) runInsertHtml read activeDocumentNodes(store) from the snapshot captured BEFORE insertImportedNodes ran, so the just-created nodes (and auto-created classes) weren't in it — created came back []. Re-read fresh state after the insert. Now created returns the full inserted subtree { id, moduleId, classes } with resolved class names, so an agent can target nested nodes without re-reading the tree. Regression test added. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(ai): remove unused MCP review symbols --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for e554b0e - Browse repository at this point
Copy the full SHA e554b0eView commit details -
Configuration menu - View commit details
-
Copy full SHA for ec7fc99 - Browse repository at this point
Copy the full SHA ec7fc99View commit details -
Configuration menu - View commit details
-
Copy full SHA for 1a5625c - Browse repository at this point
Copy the full SHA 1a5625cView commit details
Loading
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.6...v0.0.7