Change Notes
Synthograsizer Suite — Build History & Release Log
NEXT
Unreleased
In Progress — 2026-06-12
Backend Tiers, Safety Controls & Feedback
-
feat
Local-model backend tier — run text generation on your own hardware, unrestrictedSettings → Backend & Safety now offers two text backends: Google AI (cloud — Google's safety filters and Prohibited Use Policy apply) and Local model (any OpenAI-compatible endpoint: Ollama, LM Studio). On the local tier Synthograsizer applies no content filters of its own — your hardware, your discretion, within the Terms §6 floor. Mixed-mode v1: images, video, and music always generate via Google. Includes endpoint test-connection + model picker (
GET /api/backend/local/models), JSON-mode mapping with graceful fallback for servers that rejectresponse_format, and SSE streaming. Hosted instances are pinned to Google and reject config changes. -
feat
User-controlled Google safety thresholdsPer-category selectors (Harassment / Hate speech / Sexually explicit / Dangerous content / Civic integrity) adjust Google's
safety_settingswithin what its API permits — values pass through verbatim and Google's rejections surface honestly at generation time. Saved server-side; precedence: per-request > saved defaults > permissive baseline. Hosted instances clamp per-request settings to the operator's defaults — closing a pre-existing hole where any client could sendBLOCK_NONE. -
feat
"Report wrongly blocked" + one-click feedbackSafety blocks are now a typed error end-to-end (
SafetyBlockedError→ structured 422), so the error panel shows what was blocked and why, with a Report wrongly blocked button: prefilled GitHub issue form (wrongly_blocked.yml) and/or a local report toPOST /api/feedback(JSONL on the operator's disk). Prompts are never auto-included — sharing one is an explicit checkbox. General "Send feedback" lives in the settings modal. -
security
Phase-1 hardening: SSRF guard, upload consent, retention, rate limiting
synth_fetchnow validates URLs and every redirect hop against private/loopback/metadata addresses with a 10s timeout and 2 MB cap (workflow-engine/urlGuard.js); ANALYZE_URL gets a scheme/private-literal pre-check. First image upload shows a one-time consent notice (images go to Google's APIs — see Terms §7). Hosted mode (SYNTH_HOSTED=1): env-only API key, per-IP rate limiting (429 + Retry-After), and an hourly retention purge (default 30 days). None of this affects a normal local install.
Responsive Layout & UI Consistency
-
feat
Layout now holds together across phone, tablet, and desktop widthsThe AI Studio Tools grid switched from a hard
repeat(3, 1fr)torepeat(auto-fit, minmax(170px, 1fr)), so tiles reflow 3-up → 2-up → 1-up instead of squeezing. The app bar's controls are now grouped into wrap units (Mode / Links / Theme) that drop to a second row as whole groups rather than splitting mid-group, with a stacked-bar breakpoint at ≤1080px and tightened chrome below 600px. Verified clean at 1577 / 1024 / 768 / 375. -
fix
Theme picker no longer clips off the right edge at mid widthsThe app-bar mode container had
flex-shrink: 0, pushing the Cel-Pastel button past the viewport (partially unclickable) on screens narrower than ~1620px. It now shrinks and wraps to a tidy right-aligned row; dividers that would dangle at a row edge are dropped once wrapping begins. -
fix
Connections panel reads as an aligned 2-up chip gridMIDI / Scope / Display / API were four full-width rows each hugging the right edge under a left-aligned header — lopsided and disorganized. They now pair into a wrapping grid (Display spans its row for the BG swatch), matching the treatment the Cel-Pastel theme already had.
-
fix
D-Pad value text shrinks to fit instead of truncatingThe Hardware theme pins the center value to a fixed 38px with
nowrap + ellipsis, so longer values like "razor-edge stillness" rendered as "razor-edge st…". The dormantresizeControlValueText()hook is reimplemented as a shrink-to-fit (down to a 14px floor, transition suspended during measurement) and now runs on every value change, not just window resize. -
fix
Glitcher Studio & Workflows tiles now carry their theme color
.btn-glitcher-largeand.btn-workflow-largewere missing from the Hardware theme's accent block (and Glitcher from Cel-Pastel's icon group), so they fell back to an un-themed grey. Glitcher gets a teal tint matching its brand accent; Workflows joins its Flow-category green. Output action buttons (Copy / Like / Code / Send to Chat) were re-colored from the label tint (~1.9:1) to full text contrast (~9.7:1) so they no longer read as disabled.
Gemini Prompt Engineering
-
refact
Template / narrative / transform prompts rewritten for schema reliability + intent inferenceEvery Gemini-facing prompt in
backend/services/gained an explicit "interpret the request" layer: terse user input is expanded into a specific, opinionated reading rather than a generic one, and explicit user constraints (named variables, counts, fixed phrases) are honored over defaults. Narrative generation now requires exactly one self-contained prompt per image in input order; image-variation requires exactly five; smart-transform handles the EMPTY-input and no-reference edge cases. The external-LLM authoring guides (SYSTEM_PROMPT.txtand friends) were de-duplicated against the canonical prompt and corrected — one shipped a stale flat-array schema.
Glitcher CSS Consolidation & Repo Cleanup
-
refact
Standalone Glitcher's 8-file CSS
@importchain flattened into one fileThe accretedstyles/fixes/*.csspatch cascade (where.effect-modulewas redefined 11× across files) was inlined intoeffect-studio.cssin exact load order — byte-identical cascade, verified in-browser. The orphanedquick-fixes.css(referenced nowhere) was deleted. -
chore
Trimmed stale scratch dirs, dead bundles, and a leftover design exportRemoved
tmp/,scratch/, an emptypresentation/shell, a stray rootnode_modules/, two superseded ChatRoom build bundles, an orphantweaks-panel.jsx, a deadgenerateAgentResponseSyncexport, and the untracked.design-handoff/raw export (the curateddesign-handoff/remains).REPO_MAP.mdupdated with each pass.
Local-Disk Persistence — Agent Logs & Workflow Runs
-
feat
Agent Studio conversations auto-save on closeWhen you close the Agent Studio modal with at least one message in the transcript, the session is persisted to
JSON/Agent Studio Logs/<agent-name>-<hash>.jsonwith the same payload shape as the manual ⤓ Export button: goal, mode, agents, messages, workflow chips, artifacts, and composer context if launched from the Composer. Empty sessions (modal opened but no chat) are skipped to keep the folder clean. Content-addressed dedup means closing/reopening the same conversation lands on the same file. -
feat
Workflow runs auto-save on completionWhen the Workflow Runner fires
workflow_complete(success OR failure), the run is logged toJSON/Workflow Outputs/<workflow-name>-<hash>.jsonwith the template name, run id, params used (image params stripped — they're huge base64 blobs), step results, status, and duration. Failed runs are saved too — useful for diagnostics. The run metadata is captured at_runWorkflowstart time so the complete handler has everything it needs.
Local-Disk Persistence — Auto-Backup & Restore
-
feat
New
/api/save-outputgeneric endpoint — content-addressed JSON backup for any storePOST{kind, content, filename_hint?}. Files land atSynthograsizer_Output/JSON/<Kind>/<slug>-<6-char sha256>.json. Server-side dedup is content-addressed (id + timestamps stripped before hashing) so repeated saves of the same logical content land on the same file. Supported kinds:agent_profile,taste_profile,agent_log,story_output,workflow_output(last three reserved for follow-ups). Sibling endpoints:GET /api/list-outputs/{kind}for picker UIs (returns lightweight per-kind summary),GET /api/get-output/{kind}/{filename}for full content,DELETE /api/delete-output/{kind}/{filename}. -
feat
Auto-backup wired into AgentProfileStore and TasteProfileStoreEvery
.save()now fires a best-effort POST to/api/save-outputalongside the local localStorage / IndexedDB write. Failures are silent (backend may be offline). Net effect: on first load of the Composer, every built-in agent gets re-saved through the store and back-filled to disk — instant historical backup. The user no longer loses agents to a wiped browser cache. -
feat
"Restore from Disk" modals on two surfacesComposer Library overflow menu (
⋯) gets a "📁 Restore from disk…" item that lists everyAgent Profiles/*.jsonwith a one-click Restore button per row. The active-profile pill on the Synthograsizer app bar gets the same affordance forTaste Profiles/*.json. The pill now stays visible even when no profile is active (shows "No active profile") so Restore is always reachable.
Taste Profile → Composer · End-to-End Handoff
-
feat
"Send to Composer" now lands you in the Session room with a pre-built Welcome Session — not an empty LibraryAll 4 tuned agents auto-placed in channels 1–4, session named "<profile> · First Session", goal pre-filled, three shared anchors (session_context, tone, output_rules) derived from the profile's tagline + axes + narrative inclinations. One click "Launch Session" and the crew is collaborating.
-
feat
New
TasteProfileStore— persists synthesised profiles, supports multiple personas with an active pointerMirrors AgentProfileStore's shape; full CRUD + subscribe. Lives in localStorage (lightweight at this scale). An artist can keep "Neon Sirens" and "Quiet Erosion" side-by-side and switch which one their agents read from. -
feat
Agent bios pull dynamically from the active Taste Profile
resolveProfileBio()now injects synthetic placeholders —{{taste_tendency}},{{taste_narrative}},{{taste_subject}},{{taste_profile_name}},{{taste_tagline}},{{taste_palette_primary/secondary/accent}},{{taste_axes_summary}}— resolved at render time against whichever profile is active. Switch profiles, every agent re-skins instantly. Profile-defined variables with the same name still win (no surprise overrides). -
feat
New Composer command bus action:
openSessionFromTasteProfileLikeopenSessionFromRecipebut addresses agents byprofileId(deterministic) and acceptssharedAnchors+sessionNamein addition togoal. Fired from a one-shot sessionStorage handoff so the redirect from /taste-profile/ is seamless. -
feat
Sketch-only Remix path — surgical p5.js edits without regenerating the whole templateNew
mode: "p5_edit"endpoint takes the loaded sketch + an instruction and returns RAW JavaScript (no JSON envelope, no schema overhead). The frontend merges the result back, leavingpromptTemplateandvariablesuntouched. Surfaced as an inline "Edit scope" toggle in the Remix panel — appears only when the loaded template has a p5.js sketch, defaults to "Sketch only" (the common AV case). Should dramatically reduce timeouts on Pro for visual edits since the model no longer has to re-emit the entire template every time. Includes aREQUIRES_FULL_REMIXescape hatch: if the model decides the edit needs variable / prompt changes it prepends a comment and the frontend prompts the user to switch scope. -
feat
Active-profile pill in the Synthograsizer app bar — visible status + one-click profile switcherPersistent indicator showing which Taste Profile is currently active (with a green / cherry status dot). Clicking it opens a small menu listing all saved profiles, with switch / clear / "Manage on Taste Profile" actions. Subscribes to
TasteProfileStorechanges so it stays in sync if the active profile is updated in another tab. Hidden in Composer mode (where the Taste-Profile shortcut already gets hidden). Styled for both Hardware and Cel-Pastel themes.
Cel-Pastel Theme — Optional Visual Mode
-
feat
Second theme: 1990s DIC-animation pastels (Madeline / Care Bears) with 2.5px navy-ink outlines and offset sticker shadowsLayered on top of the Hardware theme via
body.theme-cel-pastel— Hardware remains the default and is unaffected when the picker is set to Hardware -
feat
Theme picker in the Synthograsizer app bar (Hardware ↔ Cel-Pastel) and on the Taste-Profile topbar (Dark ↔ Cel-Pastel)Persists to
localStorage['synthograsizerTheme']; each page gracefully normalizes the other's vocabulary ('dark' ↔ 'hardware') so navigation stays consistent -
feat
Cel-Pastel overrides for Studio, Perform, and Composer modes — including the Composer "needs more room" mobile fallbackCovers the full Taste-Profile surface (steps 1–4): dropzone, pair cards, synth spinner, stat cards, aesthetic axes, palette swatches, tag chips, agent cards, JSON preview
AV / Resolume Control-Surface Mode
-
feat
New
/synthograsizer/av.htmlperformance surface — knob grid wired for OSC dispatch to Resolume (or any OSC-aware receiver)Standard Synthograsizer page is unaffected at runtime; the AV hooks inapp.jsstay no-op unlesswindow.SYNTH_AV_MODEis set (only by av.html) -
feat
Per-variable source-tag mapping — CODE / AI / BOTHA variable set to
source: 'code'drives OSC only and is masked from the LLM prompt; set to'ai'fills the prompt without firing OSC;'both'does both -
feat
Throttled OSC dispatch (~30 fps) with per-variable diff suppression and per-knob curve / range / send-type configSend types:
float,int,trigger. Curves: linear, exponential, logarithmic, custom. Sends only fire when the normalized value actually changes -
feat
AV Inspector drawer — live-edit OSC mappings, set host/port, save/load profilesProfiles persist via the new
AVProfileStore; override edits apply to the running surface immediately without reload -
feat
Per-template AV variants under
templates-av/with automatic fallback totemplates/Same template can have a performance-tuned variant (smaller knob set, OSC-wired) without forking the LLM template. Ships with AV variants forsvg-flow-particles,lissajous-lab,synthograsizer-prompt -
feat
Resolume preset helpers — clip launch, layer opacity, blend-mode address buildersPre-built OSC address templates targeting Resolume's standard composition routing
Taste Profile — Onboarding Polish
-
feat
"Both / Neither" skip button on every taste-pair axisLets the artist leave an axis unconstrained instead of forcing a false choice; the marker biases to 0.5 (range 0.4–0.6) in
buildProfile()and the backend prompt was hardened to honor neutral answers -
feat
PNG metadata extraction on upload — auto-fills the prompt-history fieldReads
tEXt,iTXt, andzTXtchunks. Knows the formats used by AUTOMATIC1111 (parameters), ComfyUI (workflow/prompt), NovelAI (Description), and genericComment -
feat
GIF first-frame extraction for animated uploadsFrame is rendered onto a canvas and resized like any still image; lets you train on a GIF without uploading the full animation
-
feat
Thumbnail remove button — hover-reveal × on each upload previewClean up mistakes without restarting the upload step
-
feat
Hardened agent-synthesis prompt with explicit schema block + pre-emit validation checklistEvery agent now reliably ships
bioTemplate+variables+anchors; the Send-to-Composer flow has a client-side fallback that synthesizes a minimum-viable template if any field is still missing -
feat
Send-to-Composer flow waits for IDB writes to settle before navigatingSaves all 4 agents, verifies each landed in the cache, then waits ~600 ms before redirecting so the Composer page's
loadAllAsync()doesn't race the writes
Template Auto-Save — Deduplication
-
feat
Deterministic content-fingerprint filenames for auto-saved templatesAuto-save now derives a 1–3-word slug from the template name (or first source tag) + 6-character SHA-256 of the canonical content. No more timestamp spam in the output directory
-
feat
Directory scan on save — catches duplicates from older timestamp-named filesIf any existing file in the output directory has the same content fingerprint (even under a different name), the save returns
status: existspointing at the original instead of creating a copy
Agent Profile Engine — Storage & Intelligence
-
feat
IndexedDB storage backend for AgentProfileStoreReplaces synchronous 5 MB-limited localStorage; profile saves/loads are now fully async, eliminating UI jank on large agent rosters with embedded assets
-
feat
Zero-friction auto-migration from localStorage → IndexedDB on first loadExisting profiles are transparently moved on first run; no manual export/import step required
-
refact
Synchronous in-memory cache maintained for backward compatibilityLegacy call-sites using
AgentProfileStore.loadAll()continue to work until they are updated toloadAllAsync() -
feat
Anti-repetition intelligence in agent bio resolutionresolveProfileBio() now re-rolls weighted-random attribute picks up to 3 times to avoid choosing the same value as the previous interaction, producing more varied and dynamic agent behaviour
Composer — Robust JSON Parser
-
feat
extractJSONArray() — multi-layer LLM output parser for variable generationReplaces fragile regex; gracefully handles markdown code fences, preamble/postamble prose, trailing commas, and single-quoted strings hallucinated by the model
Workflow Engine — Session Stability
-
fix
Removed hard-coded 5-minute SSE timeout in WorkflowRunnerThe kill-switch would silently cancel complex long-running tasks (e.g. video generation) at exactly 5 minutes regardless of activity
-
feat
Dynamic 10-minute inactivity keepalive replaces static timeoutTimer resets automatically on every workflow_step_start / workflow_step_chunk event; connections only close if the backend goes genuinely silent for 10 minutes
-
fix
p5.js Template Gen timeout raised to 5 minutes for Pro modelPro model generating a full self-contained p5 sketch (lookup maps, 4–7 variables, draw loop) was being cut off by the shared 150s frontend abort; now 300s frontend, 300s backend, 300s workflow-engine path — all three layers aligned
Agent Composer — Generation Instructions
-
feat
User-editable style instruction field for agent profile generationStructural rules (JSON format, variables, anchors) always enforced; tone and style are now customizable per-user
-
feat
Agent profile edit-in-place — refine existing profiles instead of regenerating from scratchCurrent profile JSON sent alongside the generation prompt so the model can make targeted changes
-
feat
Collapsible generation instructions panel in Composer Editor roomState persisted to localStorage; factory-default reset button included
-
style
Visual context cues when generation instructions are activeIdentity row and Bio template highlighted with gen-context-active state; taste vector bias automatically included when a vector is set
Template Generator
-
feat
Multi-image reference support for Remix modeAttach up to 8 reference images to visually guide template evolution via multimodal prompt assembly
V0.7
Latest
2026-05-08
Major UI Overhaul
-
feat
V6→V7 UI audit — unified app bar, full layout overhaul, Agent Studio re-skinSingle persistent top bar across all modes; layout-switcher promoted to app-bar-modes; hardware theme fully applied to Agent Studio
-
feat
Agent Composer complete — 4-room mode (Library → Editor → Session → Run) with live knob controlEach room is a discrete workflow step; knobs in Run room control live generation parameters in real time
-
feat
React chatroom: attach-chip CSS and gallery lightbox polish
Bug Fixes & Stability
-
fix
Consensus quorum now counts only unmuted agentsPreviously, muted agents still counted toward quorum threshold, producing incorrect vote outcomes
-
fix
Demo mode backend guard — non-demo routes blocked in demo context
-
fix
Veo 3.1 duration default corrected; multimodal beat continuity restored; workflow outcome now surfaces in UI
Code Quality
-
refact
Agent Studio CSS modernized — all !important overrides replaced with CSS custom properties and proper cascade ordering
-
feat
Storyboard: beatNarrative store, hidden/classList overlay, aria-labels, CSS contract doc
-
refact
Glitcher: removed dead selection fallback; FrameTimer guarded on frame count
V0.6
2026-05-01
Deployment & Demo
-
feat
Demo mode — Gemini Flash Lite locked in for demo sessions; CTAs route to demo.htmlFull interactive demo with no API key required; rate-limited to lightweight models
-
fix
Vercel routing corrected — /synthograsizer/ now resolves to full app
-
feat
Glitcher v2 embedded in Synthograsizer; comprehensive UI overhaulBidirectional bridge between Synthograsizer prompt output and Glitcher effect parameters
Storyboard Panel
-
style
Storyboard panel fully redesigned to match hardware synth themeCream chassis, warm brown borders, NeoBrutalism shadows, monospace labels throughout
-
fix
Hardware theme CSS class names corrected across all storyboard components
V0.5
2026-04-25 – 2026-04-30
AI Model & Generation
-
feat
Suite-wide upgrade to Gemini 3.1 Pro PreviewImproved output coherence, longer context window, faster multimodal responses across all generation endpoints
-
feat
Live Gemini token streaming in Agent Studio transcriptsTokens appear as they arrive — no more waiting for full response before text renders
-
fix
Imagen-only fields no longer sent on Gemini generation path
Agent Studio
-
feat
Codenames game template — Layer 1 secret knowledge prototypeMulti-agent Codenames with roles (spymaster / operative); agents maintain secret layer inaccessible to opponents
-
fix
Turn-order routing corrected; verbosity defaults tuned; Codenames protocol formalized
-
feat
Template library, artifact panel with debug console, MIDI lazy-init, Display mode renamed
Templates & Story Mode
-
feat
Beat navigator for story templates — previous/next beat controls with dot-position indicator
-
feat
Twin Spheres p5.js generative template added
Platform
-
feat
Glitcher Studio modal — P5 FX drawer within Synthograsizer with bidirectional bridge
-
refact
Landing page consolidated — Synthograsizer as primary product surface
-
chore
Repo polish — trust signals, cleaned surfaces, docs structure