NEXT Unreleased In Progress — 2026-06-12
  • feat
    Local-model backend tier — run text generation on your own hardware, unrestricted
    Settings → 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 reject response_format, and SSE streaming. Hosted instances are pinned to Google and reject config changes.
  • feat
    User-controlled Google safety thresholds
    Per-category selectors (Harassment / Hate speech / Sexually explicit / Dangerous content / Civic integrity) adjust Google's safety_settings within 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 send BLOCK_NONE.
  • feat
    "Report wrongly blocked" + one-click feedback
    Safety 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 to POST /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_fetch now 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.
  • feat
    Layout now holds together across phone, tablet, and desktop widths
    The AI Studio Tools grid switched from a hard repeat(3, 1fr) to repeat(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 widths
    The 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 grid
    MIDI / 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 truncating
    The 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 dormant resizeControlValueText() 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-large and .btn-workflow-large were 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.
  • refact
    Template / narrative / transform prompts rewritten for schema reliability + intent inference
    Every 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.txt and friends) were de-duplicated against the canonical prompt and corrected — one shipped a stale flat-array schema.
  • refact
    Standalone Glitcher's 8-file CSS @import chain flattened into one file
    The accreted styles/fixes/*.css patch cascade (where .effect-module was redefined 11× across files) was inlined into effect-studio.css in exact load order — byte-identical cascade, verified in-browser. The orphaned quick-fixes.css (referenced nowhere) was deleted.
  • chore
    Trimmed stale scratch dirs, dead bundles, and a leftover design export
    Removed tmp/, scratch/, an empty presentation/ shell, a stray root node_modules/, two superseded ChatRoom build bundles, an orphan tweaks-panel.jsx, a dead generateAgentResponseSync export, and the untracked .design-handoff/ raw export (the curated design-handoff/ remains). REPO_MAP.md updated with each pass.
  • feat
    Agent Studio conversations auto-save on close
    When 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>.json with 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 completion
    When the Workflow Runner fires workflow_complete (success OR failure), the run is logged to JSON/Workflow Outputs/<workflow-name>-<hash>.json with 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 _runWorkflow start time so the complete handler has everything it needs.
  • feat
    New /api/save-output generic endpoint — content-addressed JSON backup for any store
    POST {kind, content, filename_hint?}. Files land at Synthograsizer_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 TasteProfileStore
    Every .save() now fires a best-effort POST to /api/save-output alongside 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 surfaces
    Composer Library overflow menu () gets a "📁 Restore from disk…" item that lists every Agent Profiles/*.json with a one-click Restore button per row. The active-profile pill on the Synthograsizer app bar gets the same affordance for Taste Profiles/*.json. The pill now stays visible even when no profile is active (shows "No active profile") so Restore is always reachable.
  • feat
    "Send to Composer" now lands you in the Session room with a pre-built Welcome Session — not an empty Library
    All 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 pointer
    Mirrors 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: openSessionFromTasteProfile
    Like openSessionFromRecipe but addresses agents by profileId (deterministic) and accepts sharedAnchors + sessionName in addition to goal. 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 template
    New 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, leaving promptTemplate and variables untouched. 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 a REQUIRES_FULL_REMIX escape 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 switcher
    Persistent 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 TasteProfileStore changes 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.
  • feat
    Second theme: 1990s DIC-animation pastels (Madeline / Care Bears) with 2.5px navy-ink outlines and offset sticker shadows
    Layered 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 fallback
    Covers 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
  • feat
    New /synthograsizer/av.html performance surface — knob grid wired for OSC dispatch to Resolume (or any OSC-aware receiver)
    Standard Synthograsizer page is unaffected at runtime; the AV hooks in app.js stay no-op unless window.SYNTH_AV_MODE is set (only by av.html)
  • feat
    Per-variable source-tag mapping — CODE / AI / BOTH
    A 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 config
    Send 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 profiles
    Profiles 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 to templates/
    Same template can have a performance-tuned variant (smaller knob set, OSC-wired) without forking the LLM template. Ships with AV variants for svg-flow-particles, lissajous-lab, synthograsizer-prompt
  • feat
    Resolume preset helpers — clip launch, layer opacity, blend-mode address builders
    Pre-built OSC address templates targeting Resolume's standard composition routing
  • feat
    "Both / Neither" skip button on every taste-pair axis
    Lets 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 field
    Reads tEXt, iTXt, and zTXt chunks. Knows the formats used by AUTOMATIC1111 (parameters), ComfyUI (workflow / prompt), NovelAI (Description), and generic Comment
  • feat
    GIF first-frame extraction for animated uploads
    Frame 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 preview
    Clean up mistakes without restarting the upload step
  • feat
    Hardened agent-synthesis prompt with explicit schema block + pre-emit validation checklist
    Every 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 navigating
    Saves 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
  • feat
    Deterministic content-fingerprint filenames for auto-saved templates
    Auto-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 files
    If any existing file in the output directory has the same content fingerprint (even under a different name), the save returns status: exists pointing at the original instead of creating a copy
  • feat
    IndexedDB storage backend for AgentProfileStore
    Replaces 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 load
    Existing profiles are transparently moved on first run; no manual export/import step required
  • refact
    Synchronous in-memory cache maintained for backward compatibility
    Legacy call-sites using AgentProfileStore.loadAll() continue to work until they are updated to loadAllAsync()
  • feat
    Anti-repetition intelligence in agent bio resolution
    resolveProfileBio() 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
  • feat
    extractJSONArray() — multi-layer LLM output parser for variable generation
    Replaces fragile regex; gracefully handles markdown code fences, preamble/postamble prose, trailing commas, and single-quoted strings hallucinated by the model
  • fix
    Removed hard-coded 5-minute SSE timeout in WorkflowRunner
    The 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 timeout
    Timer 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 model
    Pro 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
  • feat
    User-editable style instruction field for agent profile generation
    Structural 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 scratch
    Current profile JSON sent alongside the generation prompt so the model can make targeted changes
  • feat
    Collapsible generation instructions panel in Composer Editor room
    State persisted to localStorage; factory-default reset button included
  • style
    Visual context cues when generation instructions are active
    Identity row and Bio template highlighted with gen-context-active state; taste vector bias automatically included when a vector is set
  • feat
    Multi-image reference support for Remix mode
    Attach up to 8 reference images to visually guide template evolution via multimodal prompt assembly
V0.7 Latest 2026-05-08
  • feat
    V6→V7 UI audit — unified app bar, full layout overhaul, Agent Studio re-skin
    Single 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 control
    Each 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
  • fix
    Consensus quorum now counts only unmuted agents
    Previously, 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
  • 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
  • feat
    Demo mode — Gemini Flash Lite locked in for demo sessions; CTAs route to demo.html
    Full 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 overhaul
    Bidirectional bridge between Synthograsizer prompt output and Glitcher effect parameters
  • style
    Storyboard panel fully redesigned to match hardware synth theme
    Cream 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
  • feat
    Suite-wide upgrade to Gemini 3.1 Pro Preview
    Improved output coherence, longer context window, faster multimodal responses across all generation endpoints
  • feat
    Live Gemini token streaming in Agent Studio transcripts
    Tokens appear as they arrive — no more waiting for full response before text renders
  • fix
    Imagen-only fields no longer sent on Gemini generation path
  • feat
    Codenames game template — Layer 1 secret knowledge prototype
    Multi-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
  • feat
    Beat navigator for story templates — previous/next beat controls with dot-position indicator
  • feat
    Twin Spheres p5.js generative template added
  • 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