Skip to content

Releases: taruma/PromptLab

v2.7.0: Stage. Render. Stream.

Choose a tag to compare

@taruma taruma released this 08 Sep 12:28
b877ea0

PromptLab v2.7.0 introduces a breakthrough visual output pipeline, dedicated split-screen drafting capabilities, and a comprehensive memory-safe backup overhaul. This release debuts the Auteur Script Visualizer (AuteurScriptView), rendering structured procedural prompt outputs into dynamic macro-states, collapsible staging blocks, and compact execution cards with zero-overhead format auto-detection. Alongside it, the new Output Renderer (OutputRendererModal) delivers an edge-to-edge split-screen workspace with live multi-mode preview, persistent local drafting, and full-height Lossless PNG Export at 2x retina sharpness (html-to-image). Under the hood, a unified v1.1 Content-Addressable Image Pool and Chunked Streaming Blob Serialization across Project Workspaces, Asset Library, and User Presets completely eliminates V8 single-string heap crashes (RangeError), coupled with rich pre-import visual inspection dashboards, duplicate-detection intelligence, scope controls, and defensive package validation.


✨ Highlights

🎬 Auteur Script Visual Rendering Pipeline & Quad-Surface Integration

PromptLab now provides first-class visual rendering for prompt templates producing procedural scripts divided into staging protocols and execution state-machines:

  • 🎭 Dedicated Retro Lab Visualizer (AuteurScriptView.tsx) — transforms raw procedural text into structured, high-density retro lab components featuring collapsible staging directives and compact execution timeline cards.
  • 🧩 Schema-Tolerant Dynamic Parser (lib/auteur-parser.ts) — employs an open-ended dynamic regex pattern \[([A-Z0-9 _%-]+)\] to parse arbitrary macro-blocks ([INTENT], [LOGIC], [CONTINUITY PROTOCOL], [REFERENCES], [EXECUTION]) without rigid whitelists. Dynamically extracts sub-states (STEP 1, STATE 1, 1., etc.) into structured action, speech, and metadata channels.
  • ⚡ Zero-Overhead Smart Auto-Detection (isAuteurScript) — lightweight regex detector immediately identifies Auteur Script formatted outputs without parsing latency, dynamically surfacing the AUTEUR view toggle in output toolbars.
  • 📂 Persistent Collapsible Staging (localStorage) — auxiliary staging blocks ([INTENT], [LOGIC], etc.) remain visible and uncollapsed by default for immediate auditing, with interactive collapse toggles persisted across sessions under prompt_generator_auteur_collapsed_staging. The primary [EXECUTION] payload is permanently locked open.
  • 🎚️ Calibrated Typography Scale — specifically calibrated font sizing prevents reading fatigue: text-[12.5px]–13px (font-mono) with leading-relaxed for dialogue and visual actions, text-[11px]–11.5px for sub-state pills, and text-[9px]–10px for technical instrumentation metadata.
  • 🔲 Quad-Surface Parity — fully integrated across all four generation, history, and editing surfaces:
    1. Main Generation Result panel (GenerationResultView.tsx)
    2. History Detail Viewer (HistoryOutputViewer.tsx)
    3. Distraction-Free Fullscreen Focus Modal (HistoryFullscreenOutputModal.tsx)
    4. Output Renderer Split Workspace (OutputRendererModal.tsx)

🖥️ Output Renderer Split-Screen Workspace & Lossless PNG Export

A dedicated split-screen creative workspace for formatting, drafting, and previewing generation outputs or arbitrary prompt text:

  • 🌐 Top Header Navigation Trigger (AppHeader.tsx) — retro cyan navigation button (Renderer, #output-renderer-header-btn) with Eye icon provides instant access to the renderer from anywhere in the workspace.
  • 🪟 Distraction-Free Split Workspace (OutputRendererModal.tsx) — full-bleed split dialog (Tier 2 z-50) registered with the universal LIFO Escape key stack (useModalEscape) and compound modal safety gates (isAnyModalActive).
  • ✍️ Edge-to-Edge Source Editor — full-height monospace text editor equipped with live line and character counters, alongside one-click "Workspace" (import active generation result) and "Clear" actions.
  • 💾 Persistent Draft Text (localStorage) — preserves editor text across modal open/close cycles and page refreshes (prompt_generator_output_renderer_draft), adhering to a strict non-destructive invariant that never overwrites user text automatically.
  • 📸 Full-Height Lossless Retina PNG Export (lib/image-export.ts) — integrated export button (Camera icon) in the preview toolbar measures the unconstrained scrollHeight of rendered output using html-to-image at 2x retina pixel ratio (pixelRatio: 2). Captures extensive long-form outputs and complete Auteur Script timelines in a single seamless, uncropped image with standardized filenames: screenshot_promptlab_{projectSlug}_{viewMode}_{YYYY-MM-DD}_{HHMMSS}_{uniqueId}.png.

🔀 Unified Multi-Mode Output Pipeline & Codebase Deduplication

Generation output rendering across the entire application has been unified into a single, high-craft architecture:

  • 🎛️ Universal Multi-Mode Output View (MultiModeOutputView.tsx) — reusable 4-mode viewer component implementing segmented controls:
    • MD — Formatted Markdown with custom-styled typography, tables, and code fences
    • RAW — Monospace plain text preserving whitespace and lineation
    • JSON — Syntax-highlighted JSON with line numbers, token color coding, and line counters
    • AUTEUR — Procedural script visualization with collapsible staging blocks
  • 🧹 Shared Output Helpers (lib/output-render-helpers.tsx) — centralized JSON extraction (extractCleanJson), JSON line syntax highlighting (highlightJsonLine), and brutalist Markdown typography mappings (outputMarkdownComponents).
  • 🚀 Eliminated 450+ Lines of Duplication — refactored GenerationResultView.tsx, HistoryOutputViewer.tsx, and HistoryFullscreenOutputModal.tsx onto the unified rendering engine.

📦 Project Workspace Backups: v1.1 Image Pool, Scope Controls & Pre-Import Inspection

Multi-project workspace backup and migration has been overhauled for crash-proof scalability, data integrity, and complete inspection visibility:

  • 🛡️ Critical History Image Preservation Fix — resolved an issue where project backups previously omitted reference images attached to generation history records. Both assetLibrary and project.history images are now aggregated into a single unified export pool.
  • 🗜️ v1.1 Deduplicated Image Pool — stores unique image Base64 payloads once in a top-level images: Record<string, string> dictionary keyed by SHA-256 contentHash (or fallback ID), stripping inline payloads from individual history items (img.base64 = "").
  • 🌊 Chunked Streaming Blob Serialization — streams discrete string parts directly into new Blob(chunks, { type: "application/json" }), bypassing the V8 single-string memory ceiling (~512MB) and eliminating RangeError: Invalid string length crashes on large projects.
  • 🎛️ Configurable Export Scope Modal (ProjectExportModal.tsx) — Tier 3 (z-[60]) dialog providing 3 quick-scope presets:
    • Full Backup — complete archive with prompts, presets, assets, and full history with images
    • Compact History — all prompts, presets, assets, and history text/metrics with history images stripped for lightweight sharing
    • Starter Template — prompts, presets, and assets only; zero history records
  • 🔍 Pre-Import Inspection Dashboard (ProjectImportConfirmModal.tsx) — Tier 3 (z-[60]) inspection dialog featuring a real-time summary breakdown ribbon (PRESETS, HISTORY, ASSETS, IMAGES), project name collision resolution with auto-incrementing suffixes, prompt inspection tabs, and an auto-switch toggle.
  • ⚡ Event-Loop Yielding Hydration — pre-hydrates IndexedDB images store in batches of 10 with setTimeout(0), ensuring a fluid 60 FPS browser UI throughout large workspace imports.

🖼️ Asset Library Import/Export Overhaul: v1.1 Pool & Visual Inspection

Backing up and restoring image assets is now faster, memory-safe, and visually auditable:

  • 🗜️ v1.1 Content-Addressable Image Pool — eliminates multi-megabyte Base64 payload duplication by consolidating shared images under SHA-256 contentHash keys with 100% backward compatibility for legacy v1.0 imports.
  • 🌊 Chunked Streaming Blob Construction — replaces monolithic string concatenation with streaming array chunks, making library exports immune to V8 string heap limits.
  • 🔍 Pre-Import Visual Inspection Modal (AssetImportModal.tsx) — Tier 3 (z-[60]) inspection dashboard featuring a real-time breakdown ribbon (TOTAL IN FILE, +NEW UNIQUE, ALREADY EXISTS), scrollable thumbnail preview grid with NEW (emerald) and EXISTS (amber) status tags, and merge strategy controls.
  • 🎯 Dual-Criteria Duplicate Detection — checks incoming assets against both SHA-256 contentHash and id, backed by an asynchronous background hash resolver for existing session assets.
  • ⭐ Export Favorites / Pinned — added dedicated favorite/pinned export action in AssetExportDropdown.tsx with live count badges and capture-phase Escape isolation.

🛡️ User Presets Import/Export System Hardening & Defensive Validation

Preset management is now fully fortified against accidental file misplacements and format collisions:

  • 🛡️ Defensive Type Validation — lib/preset-export.ts strictly validates package types, immediately rejecting accidental uploads of History exports (promptlab_history_export), Asset Library backups (promptlab_asset_library), or Project backups (promptlab_project) with descriptive guidance pointing users to the correct dialog.
  • 🔎 Heuristic History Collision Prevention — examines untyped containers with items: [...] for signature history fields (generationResult, outputs, specs), preventing generation records from polluting user pr...
Read more

v2.6.1: Scalable History & Performance Overhaul

Choose a tag to compare

@taruma taruma released this 06 Sep 03:47
cac80c8

PromptLab v2.6.1 is a critical stability and performance release focused on large-scale generation history management, instant UI rendering, and crash-proof data portability. This release resolves the RangeError: Invalid string length crash on large history exports by introducing a Content-Addressable Deduplicated Image Pool (v1.1) and Chunked Streaming Blob Serialization, slashes card render latency across deep history sets through Excerpt Regex Pre-Slicing and Pre-Mapped Sorting Comparators, and establishes a robust, Idempotent History Import Pipeline with pool-first IndexedDB hydration.


✨ Highlights

🛡️ Crash-Proof History Export & Chunked Streaming Serialization

Exporting extensive generation history containing multi-modal reference images across hundreds of records previously caused a fatal browser crash (RangeError: Invalid string length) due to full Base64 image strings being duplicated across every referencing history record into a single monolithic string passed to JSON.stringify:

  • 📦 Content-Addressable Image Pool (Schema v1.1) — exportHistoryToJSON now extracts unique reference images into a top-level images: Record<string, string> pool keyed by SHA-256 contentHash. Individual history items store lightweight pointers with base64: "". When prompts reuse reference images across multiple generations, total backup payload sizes shrink by 90%–95%.
  • 🌊 Chunked Streaming Blob Serialization — replaced monolithic stringification with streaming chunk serialization, writing JSON structural fragments, metadata, the image pool, and individual history items directly as an array of discrete chunks to new Blob(chunks, { type: "application/json" }). This completely bypasses V8's single-string heap limits, enabling effortless export of 500+ history records containing dozens of multi-modal images.
  • 🛡️ Fault-Tolerant Image Resolution — if an image was purged or is unavailable in IndexedDB, the exporter logs a diagnostic warning and proceeds without failing the entire export.

⚡ History Modal & Card Rendering Performance Overhaul

Navigating large history archives is now significantly faster and more responsive thanks to targeted algorithmic optimizations and memory cleanup:

  • ✂️ Card Excerpt Regex Pre-Slicing — pre-slices rawOutput to 250–400 characters before stripping markdown syntax (replace(/[#*_>~-]/g, " ")). Eliminates multi-pass regex scanning across full-length generation outputs (often 5,000–30,000+ characters) on every card render cycle in HistoryListSidebar, HistoryCardSummary, and HistorySection`, cutting CPU cycles and garbage collection overhead.
  • 🚪 Modal Closed-State Guards & Memory Cleanup — HistoryViewerModal now guards derived filter and sorting computations with if (!isOpen) checks, preventing background calculations while typing prompts in the main workspace. Automatically clears resolved base64 images from memory upon closing the modal, eliminating lingering heap pressure.
  • ⚡ Parallelized Reference Image Loading — refactored sequential for...of image retrieval from IndexedDB to use Promise.all across valid reference images, eliminating slot-switching lag for records with multiple reference images.
  • 🏎️ Pre-Mapped Sorting Comparator (Schwartzian Transform) — re-architected sortHistoryItems with a Schwartzian transform pattern in lib/history-grouping.ts. Pre-mapping sort keys (parsed dates, numeric costs, and lowercase titles) once per item reduces comparator work from $O(N \log N)$ down to $O(N)$ linear passes, with an instant early-exit guard for short lists.
  • 🦥 Lazy JSON Extraction & Formatting — deferred extractCleanJson in HistoryOutputViewer via useMemo so that JSON parsing and syntax highlighting only run when the user explicitly switches to JSON view mode (viewMode === "json"). Default raw monospace and formatted markdown views completely bypass JSON parsing overhead.
  • 🔍 Search Substring Fast-Path — reordered matchesSearchQuery in lib/search-utils.ts to test direct case-insensitive substring matching before executing multi-pass text normalization, skipping 4 regex replacements per target string on direct hits.

🔄 Robust & Idempotent History Import Pipeline

Restoring generation history and syncing archives across multiple browsers is now safe, non-blocking, and idempotent:

  • 🛡️ Defensive File-Type Verification — validates parsedData.type upfront, immediately surfacing clear guidance if a user accidentally attempts to import a Project (promptlab_project) or Asset Library (promptlab_asset_library) JSON backup instead of a History export.
  • 💾 Pool-First IndexedDB Hydration — pre-hydrates the incoming images pool into IndexedDB via saveStoredImage. Leverages PromptLab's SHA-256 contentHash index so that images already stored in the browser link via dedupRefId with zero redundant disk writes.
  • 🔁 Idempotent Duplicate Detection — checks incoming records against existing workspace history by unique id (with a legacy signature fallback for older exports). Skips already-existing records so that round-tripping backups between devices never produces duplicate cards.
  • ⏳ Non-Blocking Batching (60 FPS) — processes incoming records in batches of 20 with event-loop yielding (setTimeout(0)), guaranteeing the UI remains silky-smooth and responsive without triggering "Page Unresponsive" warnings even when importing 500+ records.
  • 🧠 Metadata Preservation — preserves thinking traces (thinkingResult), detailed token metrics (tokenUsage), and computed cost metrics (estimatedCost) intact across export and import cycles.
  • 📊 Clear UI Feedback — the status banner in HistoryViewerModal reports both newly imported and skipped duplicate counts (e.g. "Successfully imported 10 history record(s) (500 already up-to-date skipped)!").

✨ What's New

  • 📦 History Export Schema v1.1 — content-addressable top-level image pool keyed by SHA-256 hash.
  • 🌊 Chunked Streaming Blob Export — export generation history of arbitrary volume without V8 string length crashes.
  • 🔄 Idempotent History Import — smart duplicate skipping and defensive backup type validation.
  • ⚡ Non-Blocking History Import Batching — imports hundreds of items smoothly with event-loop yielding.
  • 🏷️ Import Status Feedback — explicit notification of imported vs skipped duplicate records.

🔧 Fixed & Optimized

  • 🐛 Fixed RangeError: Invalid string length on history export with large multi-modal datasets.
  • 🐛 Fixed React Hook Synchronous State Update Lint Warning — relocated setResolvedImages({}) into the useEffect cleanup return in HistoryViewerModal.
  • ⚡ Optimized Card Excerpt Regex Cleaning — pre-slices output text to 250–400 characters, eliminating heavy regex passes over full outputs on every card render.
  • ⚡ Optimized History Sorting — pre-mapped Schwartzian transform reduces sort comparator operations to $O(N)$.
  • ⚡ Optimized Search Matching — added case-insensitive substring fast-path prior to full text normalization.
  • ⚡ Optimized Reference Image Resolution — parallelized IndexedDB queries using Promise.all.
  • ⚡ Optimized History Modal Lifecycle — bypasses filtering derivations when closed and flushes base64 image memory on exit.
  • ⚡ Optimized Output Viewer JSON Parsing — deferred JSON extraction and formatting until JSON view mode is actively toggled.

📁 Files Affected

  • package.json & package-lock.json — version bump to 2.6.1
  • CHANGELOG.md — added [v2.6.1] release entry with performance, fixed, and added sections
  • AGENTS.md — updated Rule M documentation covering streaming chunk exports, Schwartzian sorting, and excerpt pre-slicing
  • lib/history-export.ts — implemented v1.1 deduplicated image pool export, chunked streaming Blob serialization, defensive file validation, pool-first IndexedDB hydration, and idempotent batched import
  • lib/history-grouping.ts — refactored sortHistoryItems with pre-mapped Schwartzian transform comparator and early-exit guard
  • lib/search-utils.ts — added case-insensitive direct substring fast-path to matchesSearchQuery
  • components/HistoryViewerModal.tsx — added closed-state memoization guards, memory cleanup on close, parallel image resolution with Promise.all, import status banner, and hook cleanup fix
  • components/history/HistoryListSidebar.tsx — pre-sliced card excerpt before regex formatting (250 chars)
  • components/HistoryCardSummary.tsx — pre-sliced card excerpt before regex formatting (250 chars)
  • components/HistorySection.tsx — pre-sliced card excerpt before regex formatting (400 chars)
  • components/history/HistoryOutputViewer.tsx — wrapped extractCleanJson in useMemo conditioned on viewMode === "json"

Full Changelog: v2.6.0...v2.6.1

v2.6.0: Filter. Focus. Accelerate.

Choose a tag to compare

@taruma taruma released this 06 Sep 02:09
1623730

v2.6.0: Filter. Focus. Accelerate.

PromptLab v2.6.0 delivers a major upgrade to sequence inspection, generation history discovery, and workspace workflow ergonomics. This release decomposes the monolithic history viewer into a modular, high-craft architecture featuring a Modular Output & Reasoning Viewer with RAW Monospace default rendering, an expandable Thinking Trace Accordion, and a distraction-free Fullscreen Focus Modal. For sequence exploration, an overhauled Sidebar Filtering & Grouping Engine introduces multi-select media filters with strict AND matching, dynamic preset and model extractors, contextual date bucketing (TODAY, YESTERDAY, PREVIOUS 7 DAYS, OLDER), and a 2-button View Density Switcher (Detailed vs Compact). In the active workspace, creators can now seamlessly paste images directly from their OS clipboard with Ctrl+V / Cmd+V, trigger synthesis via Ctrl+Enter / Cmd+Enter, and dismiss layered dialogs predictably via a centralized Universal LIFO Modal Escape Stack (useModalEscape) backed by a standardized 5-tier z-index scale.


✨ Highlights

🗂️ History Preview Panel Redesign & Modular Output Viewer

Generation output inspection in the Session History Explorer has been completely re-architected into modular, reusable subcomponents adhering strictly to Analog Brutalist Retro Lab ergonomics:

  • 📜 Modular Output Viewer (HistoryOutputViewer.tsx) — isolated subcomponent supporting 3-mode rendering defaulting strictly to RAW Monospace on every modal open and slot change. Includes one-click toggles to Formatted Markdown (MD) (with custom-styled typography, blockquotes, and code fences) and Syntax-Highlighted JSON (JSON) (with line numbers, per-token syntax colors, and line counts). Includes live character and word counters in the header.
  • 🧠 Collapsible Reasoning / Thinking Trace Accordion — automatically surfaces an expandable amber/slate accordion when thought tokens (thinkingResult) are recorded, displaying parsed thought markdown alongside a {count} thought tokens metric badge.
  • 🔍 Distraction-Free Fullscreen Focus Modal (HistoryFullscreenOutputModal.tsx) — full-viewport reading overlay (Tier 3 z-[60]) for inspecting deep narrative responses or complex JSON schemas, coordinated with the universal Escape stack.
  • ✏️ Inline Sequence Title Renaming — an edit pencil trigger (Edit3) beside the sequence title enables inline renaming with Enter to save, Escape to cancel, and touch-friendly check/cancel action controls.
  • 🎛️ Unified Color-Coded Metadata Ribbon — replaced disconnected engine labels with a pixel-aligned, color-categorized ribbon (h-5, text-[9px] baseline): Blue for Model, Amber for Reasoning, Purple for Preset, Emerald for interactive Cost Popover, and Slate for Tokens. Temperature and Max Tokens appear dynamically only when differing from default values.
  • 📋 Dynamic Parameter Copy Triggers — individual one-click copy buttons with transient Copied! feedback for each dynamic variable value.

🔍 History Sidebar Overhaul: Sorting, Filtering & Date Grouping

Finding, auditing, and comparing past prompts is significantly faster and more granular:

  • 🗄️ Collapsible Filter & Sort Drawer — a compact [SORT & FILTER ▾] drawer button houses sorting options, dynamic presets, models, reasoning levels, and media filters while preserving vertical space for the slot list.
  • 🏷️ Multi-Select Media Filters (AND Logic) — toggle chips (IMG, VID, AUD, DOC) support multi-selection with strict AND-matching logic (e.g., selecting IMG + VID surfaces only generations containing both images and video references).
  • 🧩 Dynamic Presets & Models Extraction — automatically scans historical records to extract available presets and models with live item counts, alongside a dedicated Custom (No Preset) option.
  • 📅 Smart Contextual Date Grouping — when sorting by Date, slots are sectioned under sticky, collapsible retro-lab headers (TODAY, YESTERDAY, PREVIOUS 7 DAYS, OLDER). Sorting by Cost or Name transitions to a continuous flat ranked list with #N rank badges.
  • 🎚️ View Density Toggle (Detailed vs Compact) — a 2-button header switcher toggles between rich 4-row cards (with narrative excerpts and full badge stacks) and streamlined 2-line compact cards (with minimalist color-coded indicator dots: Black for Images, Amber for Videos, Purple for Audio, Teal for Documents). Persisted in localStorage (promptlab_history_density_mode).
  • ⌨️ Keyboard Arrow Navigation — ArrowUp and ArrowDown hotkeys step through filtered slots with smooth scrolling and input focus protection.

🎯 Universal Search & Integrated Side Scope Selector

The history search bar has been enhanced with deep targeting capabilities:

  • 🎯 Integrated Side Scope Selector — a compact icon-only trigger embedded into the right edge of the search box opens a w-72 popover with descriptive subtitles and an inline DEFAULT badge.
  • 🌐 7 Target Search Areas — defaults to All Content (Universal) (scanning titles, objectives, parameter keys & values, generated outputs, media labels, and compiled prompt specs), with granular targeting for:
    • Slot Name / Title (default)
    • Main Objective / Idea (idea)
    • Generated Output (output)
    • Media Reference Labels (visual_reference)
    • Dynamic Parameters (parameters)
    • Compiled Prompt Specs (compiled_prompt)

📋 OS Clipboard Image Paste Support (Ctrl+V / Cmd+V)

Adding reference images is now as simple as copying a screenshot from anywhere in your OS:

  • 📋 Native Clipboard Listener (use-clipboard-image-paste.ts) — intercepts image paste events anywhere in the active workspace.
  • 🗜️ Automatic Canvas Compression & Deduplication — compresses pasted images to high-quality JPEG (90% quality), generates a SHA-256 content hash, stores the binary blob in promptlab_db, and maps it to the next dynamic @imageN casting tag.
  • 🏷️ Smart Sequential Auto-Labeling — detects generic names (such as image.png, image, or empty blob) and assigns clean labels (Pasted Image 1, Pasted Image 2, etc.).
  • 📂 Auto-Expansion Feedback — automatically expands and persists the Visual Assets accordion section when an image is pasted.
  • 🛡️ Zero Text Interference & Modal Safety Gates — bypasses text and HTML clipboard events to ensure textarea and input typing remain completely uninterrupted, and disables pasting when any modal is open.

⚡ Generation Keyboard Shortcut (Ctrl+Enter / Cmd+Enter)

Trigger sequence synthesis without reaching for the mouse:

  • ⌨️ Cross-Platform Shortcut Hook (use-generate-shortcut.ts) — triggers generation via Ctrl+Enter (Windows/Linux) or Cmd+Enter (macOS).
  • 🛡️ Textarea Newline Suppression — intercepts and suppresses accidental newline insertions inside multiline textareas (Main Objective / Idea).
  • 🔒 Execution Gates — disabled when generation is currently processing (isLoading) or when any modal overlay is active.
  • 🏷️ Analog Brutalist Affordance — subtle <kbd>Ctrl+↵</kbd> badge on the "Generate Sequence" button with descriptive tooltip.

🛡️ Universal LIFO Modal Escape Stack & 5-Tier Z-Index Architecture

Coordinating nested modals, drawers, and popovers is now completely deterministic:

  • 📚 LIFO Modal Escape Coordinator (use-modal-stack.ts) — global Last-In, First-Out stack array ensuring pressing Escape pops and dismisses strictly the topmost active dialog without triggering parent closures.
  • 📐 5-Tier Z-Index Scale:
    • Tier 1 Canvas (z-10): Floating tags, card actions, asset badges.
    • Tier 2 Primary Modals (z-50): HistoryViewerModal, PromptConfigModal, ProjectManagerModal, AssetLibrarySidebar, EngineControlsModal.
    • Tier 3 Sub-Modals & Confirmations (z-[60]): HistoryFullscreenOutputModal, VideoPlayerModal, DeleteHistoryConfirmModal, ClearHistoryConfirmModal, LoadWorkspaceConfirmModal, PresetCompareModal, DiscardChangesConfirmModal.
    • Tier 4 Floating Popovers (z-[70]): HistoryCostPopover, Export dropdowns, Quick Selector menus.
    • Tier 5 Portaled Hover Previews (z-[80]): HistoryImageCardWithHover hover preview with SHA-256 hash badge.
  • 🎯 Capture-Phase Sub-Overlay Prioritization — popovers and menus capture Escape on document to dismiss without bubbling up to the window modal stack.
  • 🔒 Input Propagation Halts — search filter inputs and inline title renaming intercept Escape to clear text or cancel edits without closing parent modals.

💰 Click-to-Toggle Itemized Cost Breakdown Popover

  • 🖱️ Intentional Click Interaction — converted hover-triggered cost breakdown to an intentional click toggle in GenerationResultView.tsx, eliminating accidental popover flashing.
  • 📜 Historical Model Rate Isolation — HistoryCostPopover in history inspection computes line-by-line token expenditures strictly using each historical record's archived model specifications (selectedItem.model), never leaking active workspace engine settings.
  • 📐 Boundary-Aware Alignment — dynamically measures container clearance against scrollable containers (.overflow-y-auto) on open to prevent right-edge clipping by the vertical scrollbar.

✨ What's New

  • 🗂️ Modular History Architecture — extracted monolithic 1,344-line HistoryViewerModal.tsx into clean subcomponents: HistoryListSidebar.tsx, HistoryDetailPanel.tsx, HistoryCostPopover.tsx, HistoryImageCardWithHover.tsx, HistoryOutputViewer.tsx, and HistoryFullscreenOutputModal.tsx.
  • 📐 Canonical History Type System (types/history.ts) — centralized...
Read more

v2.5.1: Next-Gen Flash & Promotional Rates

Choose a tag to compare

@taruma taruma released this 02 Sep 22:21
f300acb

PromptLab v2.5.1 introduces native support for Google's newly unveiled Gemini 3.8 Flash (gemini-3.8-flash), establishing it as the new default model across the entire workspace. In addition, this release integrates Google's introductory promotional pricing across the Gemini Flash series (3.8, 3.7, and 3.6 Flash) through December 31, 2026, cutting input and output token costs in half across all real-time cost estimations, itemized breakdown popovers, and model selector cards.


✨ Highlights

⚡ Gemini 3.8 Flash Default Baseline

Gemini 3.8 Flash is Google's most intelligent Flash model to date, engineered for long-horizon software engineering, autonomous agents, and complex enterprise workflows with a 1,048,576 token context window and March 2026 knowledge cutoff. PromptLab adopts Gemini 3.8 Flash as the primary default engine across the application:

  • 🚀 Default Workspace Engine — gemini-3.8-flash is now the initial selected model in the workspace state (app/page.tsx), the server-side proxy fallback (app/api/generate/route.ts), and the Engine Controls reset-to-defaults baseline (components/EngineControlsModal.tsx).
  • 🔗 Latest Alias Resolution — MODEL_ALIASES["gemini-flash-latest"] in lib/pricing.ts now resolves directly to gemini-3.8-flash.
  • 🎛️ Quick Model Selector — the Flash Latest option in components/QuickModelSelector.tsx now displays a 3.8 badge, and the active status indicator maps gemini-3.8-flash to "3.8 Flash".
  • 🏷️ Specific Models Catalog — added gemini-3.8-flash to the top of SPECIFIC_MODELS with a green NEW badge, Mar 2026 cutoff, and Sep 2, 2026 release date.
  • 🎥 Agentic Video Understanding — lib/video-utils.ts (isAgenticVideoSupported) now supports gemini-3.8-flash, enabling autonomous timeline exploration (Think → Act → Observe) with dynamic frame extraction on the new model.

🏷️ Introductory Promotional Pricing (Flash Series)

Google is offering promotional introductory rates for Gemini 3.8 Flash, Gemini 3.7 Flash, and Gemini 3.6 Flash effective through December 31, 2026:

Metric Introductory Promotional Rate (Through Dec 31, 2026) Standard Rate (Starting Jan 1, 2027)
Input Tokens $0.75 / 1,000,000 tokens $1.50 / 1,000,000 tokens
Output Tokens (incl. thoughts) $3.75 / 1,000,000 tokens $7.50 / 1,000,000 tokens
Context Cache Base $0.075 / 1,000,000 tokens $0.15 / 1,000,000 tokens
Context Cache Storage $0.50 / 1,000,000 tokens / hour $1.00 / 1,000,000 tokens / hour

PromptLab's central pricing engine in lib/pricing.ts automatically reflects these rates:

  • UI Rate Badges: Model cards in EngineControlsModal display IN: $0.75 / 1M and OUT: $3.75 / 1M.
  • Itemized Cost Breakdown: The Retro Lab brutalist cost popover in GenerationResultView computes exact line-by-line costs for uncached prompt tokens, cached prompt tokens, candidate tokens, and thought tokens using the promotional rates.
  • Historical Stability: Generations saved during this period store their calculated cost string at generation time, keeping archival cost records stable.

✨ What's New

  • ⚡ Gemini 3.8 Flash Model Integration — added gemini-3.8-flash to MODEL_PRICING_TABLE, MODEL_ALIASES, SPECIFIC_MODELS, and LATEST_MODELS.
  • 🏷️ Introductory Pricing for Flash Models — updated pricing configurations for Gemini 3.8 Flash, 3.7 Flash, and 3.6 Flash to $0.75 / 1M in and $3.75 / 1M out.
  • 🎥 Agentic Video Understanding on 3.8 Flash — updated isAgenticVideoSupported in lib/video-utils.ts and tooltips in VideoAssetCard.tsx.
  • 🎛️ Quick Model Selector 3.8 Badge — updated top navigation dropdown badge for Flash to 3.8 with 3.8 Flash label mapping.
  • 🏷️ Dynamic Version Display — footer status bar displays PromptLab v2.5.1 by Taruma Sakti automatically from package.json.

🔄 Changed

  • Default Model: Swapped default workspace model from gemini-3.7-flash to gemini-3.8-flash across app/page.tsx, app/api/generate/route.ts, and EngineControlsModal.tsx.
  • Cost Estimation Fallbacks: Updated fallback model parameter in HistoryCardSummary.tsx and HistoryViewerModal.tsx from gemini-3.7-flash to gemini-3.8-flash.
  • Model Badges: Marked gemini-3.8-flash as isNew: true and updated gemini-3.7-flash to isNew: false in SPECIFIC_MODELS.
  • Documentation: Synchronized baseline references in AGENTS.md and engine feature lists in README.md.

📁 Files Affected

  • package.json & package-lock.json — version bump to 2.5.1
  • lib/pricing.ts — added gemini-3.8-flash, updated gemini-flash-latest alias, and applied promotional rates to 3.8, 3.7, and 3.6 Flash
  • lib/video-utils.ts — added gemini-3.8-flash to isAgenticVideoSupported
  • app/page.tsx — updated selectedModel initial state to gemini-3.8-flash
  • app/api/generate/route.ts — updated fallback model to gemini-3.8-flash
  • components/EngineControlsModal.tsx — added 3.8 Flash to specific models, updated latest model subtitle, and reset defaults handler
  • components/QuickModelSelector.tsx — updated Flash badge to 3.8 and added label mapping
  • components/VideoAssetCard.tsx — updated agentic mode tooltips
  • components/HistoryCardSummary.tsx & components/HistoryViewerModal.tsx — updated cost calculation fallback model
  • CHANGELOG.md — added [v2.5.1] release entry
  • AGENTS.md & README.md — synchronized model baseline and documentation

v2.5.0: Explore. Structure. Deduplicate.

Choose a tag to compare

@taruma taruma released this 02 Sep 10:16
81cb579

PromptLab v2.5.0 transforms the playground into a full-fledged multimodal lab. This release introduces Google's Agentic Video Understanding with autonomous timeline exploration, sets Gemini 3.7 Flash as the default system baseline, and expands casting references beyond images and video to include Audio (@audioN) with a dedicated player modal and Documents (@docN) up to 2 GB via Files API. On the output side, PromptLab introduces Guaranteed Structured JSON Output with live schema validation and a syntax-highlighted 3-mode viewer, alongside an Itemized Cost Breakdown Popover detailing uncached prompt, context cache savings, output, and thought tokens. Under the hood, an IndexedDB v3 architecture with SHA-256 content-hash deduplication and an automatic legacy LocalStorage purge eliminates browser storage quota crashes, supported by an interactive Storage & Quota Monitor Modal and Asset Library power tools (pinning, favoriting, select mode, and shared project tracking).


✨ Highlights

🎥 Agentic Video Understanding (MediaProcessing.AGENTIC)

PromptLab natively supports Google's Agentic Video Understanding for Gemini 3.7 Flash models, enabling autonomous timeline exploration (Think → Act → Observe) with dynamic frame extraction and significantly lower token/API costs for longer video assets compared to brute-force sampling.

  • 🎚️ Segmented Mode Toggle — each VideoAssetCard features an Analog Brutalist segmented toggle between STATIC (standard 1 FPS fixed-rate frame sampling, default) and AGENTIC (model-driven dynamic timeline navigation).
  • 🛡️ Option A Non-Destructive Fallback — switching to a model that does not yet support agentic video (such as Gemini 3.1 Pro Preview / Gemini Pro Latest) preserves your AGENTIC preference in workspace memory, renders a dashed amber Paused status tag on the video card, and automatically executes a safe STATIC fallback on the backend without discarding user intent.
  • 📺 YouTube Video MIME Typing — YouTube references passed via fileData now include explicit mimeType: "video/mp4" transmission in app/api/generate/route.ts.
  • 💾 Cross-Surface Persistence — processingMode persists across workspace session state, generation history archives, and JSON backup export/import schemas (lib/history-export.ts).

⚡ Gemini 3.7 Flash & Quick Header Switchers

Gemini 3.7 Flash (gemini-3.7-flash) is now the default model across PromptLab, paired with streamlined quick-switching controls in the top navigation bar.

  • 🚀 Default System Baseline — updated workspace defaults to Gemini 3.7 Flash with MEDIUM reasoning effort and 1.0 temperature.
  • 🎛️ Quick Model & Thinking Switcher (QuickModelSelector) — an icon button in AppHeader.tsx opens a compact 4-row control panel:
    • Row 1 (Status): Active model and thinking level indicator (Flash Latest • MEDIUM).
    • Row 2 (Model): Rapid alias switching (Flash, Flash Lite, Pro) with automatic version badges.
    • Row 3 (Thinking): Reasoning effort levels (HIGH, MEDIUM, LOW, MIN), automatically disabling MIN for Pro models.
    • Row 4 (Structured Output): One-click toggle for Structured JSON generation.
  • 🔑 Quick API Key Switcher (QuickApiKeySelector) — instant switching between the Default System Key and custom Vault keys, featuring a BYOK (Bring Your Own Key) status badge, key count badge, masked string preview, and multi-tab synchronization.

📑 Multimodal Casting: Audio (@audioN) & Documents (@docN)

Multi-modal reference handling now extends beyond visual media. The generation pipeline parses MIME types and emits dedicated casting tags across prompts and history:

  • 🎵 Audio Reference Tags (@audioN) — Files API audio assets (audio/* formats: MP3, WAV, OGG, M4A, FLAC) map to @audio1, @audio2, etc., in {{ visual_references }}.
  • 🎧 Dedicated Audio Player Modal (AudioPlayerModal) — custom audio preview dialog with HTML5 controls, volume slider, playback scrubber, and MIME type metadata.
  • 📄 Document Reference Tags (@docN) — PDFs, text files, CSV, JSON, Markdown, and source code files map to @doc1, @doc2, etc., in {{ visual_references }}.
  • 🏷️ Workspace File Picker & Badges — file picker accepts image/*,video/*,audio/*,application/pdf,text/* up to 2 GB. VideoAssetCard renders purple theme + music icons for audio and teal theme + document icons for text/PDF documents. History cards display separate AUD (purple) and DOC (teal) badges.

💰 Itemized Cost Breakdown Popover & Streaming Cost Finalization

A complete overhaul of generation cost accounting provides granular transparency for complex multimodal and high-reasoning workloads:

  • ⏱️ Streaming Cost Finalization — the emerald cost badge remains hidden during active generation (isLoading === true), rendering verified final costs immediately upon completion to avoid misleading intermediate numbers.
  • 🧾 Interactive Breakdown Popover — hovering or tapping the cost badge in GenerationResultView opens a Retro Lab brutalist popover displaying line-by-line itemized calculations:
    • Prompt Input (Uncached): Token count $\times$ input rate per 1M $\rightarrow$ subtotal.
    • Context Cache: Cached token count $\times$ discounted base rate per 1M $\rightarrow$ subtotal, with a highlighted Saved $X.XXXXXX badge.
    • Output Response: Candidate text tokens $\times$ output rate per 1M $\rightarrow$ subtotal.
    • Reasoning Thoughts: Thought tokens $\times$ output rate per 1M $\rightarrow$ subtotal.
    • Total Estimated: Aggregate token count and final USD cost.
  • 🧠 Server-Side Thought Tokens Capture — thoughtsTokenCount is captured directly from Gemini API usageMetadata and streamed to the client, visibly balancing total tokens: TOKENS: {total} ({prompt} IN [{cached} CACHED] / {candidates} OUT + {thoughts} THOUGHTS).
  • 🔄 Backward-Compatible Thought Token Fallback — lib/pricing.ts derives thought tokens via $\max(0, \text{total} - \text{prompt} - \text{candidates})$ for legacy history records.

🧩 Structured JSON Output & Syntax-Highlighted JSON Viewer

Enforce deterministic, machine-parseable JSON generation with integrated schema validation and dedicated rendering:

  • 🔒 Server-Side JSON Schema Enforcement — /api/generate accepts responseMimeType: "application/json" and an optional responseSchema, attaching them directly to the Gemini API generation config.
  • 📝 Live JSON Schema Editor — EngineControlsModal provides an expandable JSON Schema textarea with real-time syntax validation (emerald Valid Schema vs. red Syntax Error badge with error tooltips) and starter schema templates.
  • 🎨 3-Mode Output Renderer with Syntax-Highlighted JSON View — GenerationResultView adds a dedicated JSON View featuring:
    • Markdown code-fence stripping and parse fallback with an amber Raw / Unparsed JSON badge.
    • Per-token syntax highlighting: keys (bold charcoal), strings (teal), booleans (indigo), null (stone italic), numbers (amber), and delimiters (warm gray).
    • Line numbers, row hover highlights, and auto-lock state (STRUCTURED JSON (LOCKED)).
  • 🟢 Pulsing Footer Status — emerald JSON OUTPUT badge (bg-emerald-950/70 border border-emerald-500/50 text-emerald-400) illuminates in the status bar whenever structured output is active.

🗄️ IndexedDB v3 Schema, Content-Hash Deduplication & Quota Guard

Solves browser storage quota limits (QuotaExceededError) by decoupling image payloads, purging legacy LocalStorage bloat, and monitoring storage health:

  • 🗃️ IndexedDB v3 Schema & SHA-256 Content Hashing — promptlab_db v3 indexes images by contentHash. Identical images store lightweight reference pointers (dedupRefId), eliminating duplicate base64 payloads across workspaces, asset libraries, and history.
  • 🔗 Reference-Safe Deletion & Promotion — deleting a master image record automatically promotes the first dependent record to master and repoints references, preventing broken images.
  • 🛡️ Cross-Project Reference Protection — deleteStoredImage() verifies whether an image is referenced by any other project's library or history before deleting binary data.
  • 🧹 Legacy LocalStorage Purge — migrates history records from localStorage into IndexedDB on launch, immediately freeing up ~4.1 MB of origin quota (dropping usage from 90%+ down to safe levels).
  • 📊 Storage & Quota Monitor Modal (StorageUsageModal) — real-time diagnostic modal displaying LocalStorage usage percentage, standard 5 MB quota bar, key-by-key breakdown table, and IndexedDB origin quota via navigator.storage.estimate().
  • 📈 Interactive Footer Usage Badge — auto-refreshing storage indicator in FooterStatusBar pulses red when usage reaches 80% and opens the storage modal on click.

📌 Asset Library Power Tools — Pinning, Favoriting & Select Mode

The persistent Asset Library received major workflow and safety upgrades:

  • 📌 Pinning & Favoriting — pin important reference images to the top (📌) or mark them as favorites (★) with amber highlights and dedicated filter tabs (All, Pinned, Favs).
  • ☑️ Select Mode & Bulk Operations — toggleable selection mode with Select All / Deselect All for batch export and deletion.
  • 🛡️ Two-Step Deletion Safety — clicking delete transforms the button into an inline 4-second auto-cancel confirmation state, eliminating accidental image deletions.
  • 📥 Drag-and-Drop JSON Restore — drop .json asset library backup files directly into the library dropzone to preview, detect duplicates, and restore assets.
  • 👥 Shared Project Badges — asset cards display badges showing the count of other projects sharing the asset, complete with project list tooltips.
  • 📐 Streamlined 2-Row Toolbar — unif...
Read more

v2.4.1: Teach, Don't Preach

Choose a tag to compare

@taruma taruma released this 29 Jul 03:07

PromptLab v2.4.1 is a focused patch that strips all AI-centric and prompt-generation language from the 10 built-in system presets, refocusing them as pure educational and analytical tools for understanding filmmaking craft. Every preset now teaches cinematic language, composition, color theory, camera movement, shot breakdown, style definition, or narrative treatment — without prescribing output formats or spitting out copy-paste prompts for generators.


✨ Highlights

📚 Presets Refocused on Education, Not Prompt Generation

All 10 built-in presets were refactored to serve as tool-agnostic teaching references. The goal: users learn to see, describe, and think about visual media with the fluency of a filmmaker — regardless of what tools they use downstream.

What was removed:

  • Dedicated output sections that produced AI prompt fragments, generation tokens, style bibles, video prompt keywords, and copy-paste-ready generator inputs
  • Intro paragraphs that framed presets as prompt factories for "AI image/video generators"
  • Final instruction lines in prompt templates that directed output toward "generation prompts" or "generative tools"

What remains — and is now the focus:

  • Deep multi-dimensional analysis of cinematic language
  • Structured breakdowns of color palettes, composition geometry, camera movement, shot sequences, and genre conventions
  • Glossaries of technical terminology with plain-English definitions
  • Creative variations, re-imaginings, and directing insights
  • Educational craft notes on treatment writing and visual communication

Design philosophy: Users who want to convert their analysis into prompts can pair an educational preset (e.g., Cine DeepDive for analysis) with another tool or preset designed for prompt construction. The presets themselves stay focused on what they do best: teaching the craft.


✨ What's New

  • 🧹 Stripped prompt-generation sections from all 10 system presets — removed "GENERATION TOOLKIT," "PROMPT FRAGMENTS," "STYLE BIBLE," "VIDEO MOTION TOKENS," and similar output sections from every system_prompt.txt
  • ✏️ Rephrased intro paragraphs — 6 intro passages across 5 presets now emphasize teaching, description, and visual literacy instead of prompt construction
  • 📝 Cleaned prompt template instructions — 5 prompt_template.txt files had their final instruction lines simplified to focus on analysis and explanation

🔄 Changed

  • cine_deepdive — Removed GENERATION TOOLKIT section (prompt fragments + style tokens); renumbered §6 → §5
  • color_mapper — Removed GENERATION COLOR TOKENS section (palette keywords, negative tokens); renumbered §8 → §7; cleaned prompt template final line
  • comp_decoder — Removed PROMPT COMPOSITION TOKENS section; rephrased intro from "writing AI image/video prompts" to "communicating visual ideas effectively"; renumbered §6 → §5
  • film_lingo — Removed PROMPT FRAGMENTS section (Midjourney, DALL-E, Runway, Sora references); cleaned prompt template final line
  • genre_lexicon — Removed GENERATION TOOLKIT section; rephrased intro from "AI image/video generation" to "digital creation"; renumbered §6 → §5; cleaned prompt template final line
  • motion_lab — Removed VIDEO MOTION TOKENS section; rephrased intro from "writing AI video generation prompts" to "communicating camera direction with precise motion descriptors"; renumbered §6→§5, §7→§6
  • scene_lab — Removed GENERATION EXTRACTS section; renumbered §6 → §5
  • shot_interp — Removed VIDEO PROMPT FRAGMENTS section; rephrased intro from "writing prompts for AI video generators" to "writing precise shot descriptions"; renumbered §6 → §5
  • style_architect — Removed STYLE BIBLE section; rephrased intro from "working with AI image/video generators" and "handed directly to an AI generator" to "briefing collaborators... building a reference library" and "a definitive creative reference"; renumbered §7→§6, §8→§7; cleaned prompt template final line
  • vis_narrative — Removed GENERATION PROMPTS section; cleaned prompt template final line

📁 Files Affected

15 files across all 10 preset folders:

  • 10 system_prompt.txt files — sections removed + intros rephrased
  • 5 prompt_template.txt files — final instruction lines cleaned (color_mapper, film_lingo, genre_lexicon, style_architect, vis_narrative)

v2.4.0: Import. Inspect. Enforce.

Choose a tag to compare

@taruma taruma released this 29 Jul 02:19

PromptLab v2.4.0 delivers the biggest preset expansion yet — 10 specialized folder-based presets replace the original 3 flat JSON presets, each with its own system_prompt.txt and prompt_template.txt. This release also introduces a fully redesigned preset import experience with configurable Duplicate vs. Replace strategies, a rich summary inspector, and a unified pipeline for URL and local file imports. On the UI side, simplified color-coded header buttons, a Ko-fi support link, mobile-responsive layout refinements, and a Quick Preset Selector row redesign with system prompt excerpt previews make the workspace more intuitive. For deployments, the new ALLOW_SERVER_ENV_KEY flag gives operators fine-grained control over server-side API key usage.


✨ Highlights

🎬 10 New Folder-Based Presets

Replaced the 3 original flat JSON presets (AI Casting & Screenplay, AI Director & Storyboard, VFX & Speculative Worldbuilder) with 10 new specialized folder-based presets, each storing meta.json, system_prompt.txt, and prompt_template.txt as individual files. The per-preset architecture means each preset defines its own output formatting rules (plain text, Markdown, JSON, etc.) rather than relying on a global system_prompt.txt (which was emptied in this release):

  • Cine DeepDive — Cinematic Language Educator for multi-dimensional scene analysis across all cinematic layers (shot design, composition, camera movement, lighting, color, lenses, editing, sound) with AI generation toolkit and creative re-imagining.
  • Color Mapper — Color Language Specialist for extracting, naming, and designing color palettes with grading style identification, color psychology notes, and AI generation color tokens.
  • Comp Decoder — Visual Composition Analyst for reverse-engineering images into compositional building blocks (geometry, weight distribution, depth layers, line dynamics) with AI prompt composition tokens.
  • Film Lingo — Cinematic Language Translator for converting concepts into rich cinematic language with ready-to-use AI generation prompts.
  • Genre Lexicon — Genre & Tone Lexicon for defining and articulating genre conventions, tonal registers, and their visual signatures.
  • Motion Lab — Camera Motion Specialist for naming and analyzing camera movements (dolly, handheld, Steadicam, crane, zoom) with emotional motivation, movement arc analysis, and AI video motion tokens.
  • Scene Lab — Scene Construction Coach for turning character interactions into fully visualized scene descriptions with camera, lighting, and blocking choices expressing emotional subtext.
  • Shot Interp — Shot Language Interpreter for reverse-engineering finished scenes into professional shot-by-shot breakdowns with narrative purpose and directing insights.
  • Style Architect — Visual Identity Architect for defining comprehensive visual style guides with color philosophy, composition doctrine, lighting signature, AI style bibles, and creative director's notes.
  • Vis Narrative — Visual Narrative Architect for crafting director's treatment blueprints, tonal maps, and AI generation prompt suites.

🔄 Preset Import — Strategy, Inspector & Unified Pipeline

When importing presets from a URL query parameter or a local JSON file, you now get full control over how duplicates are handled, a detailed breakdown of what will be imported, and a visual inspector to review each item before committing.

  • 🔀 Duplicate vs. Replace Strategy Selector — the redesigned PresetImportConfirmModal presents a segmented toggle letting you choose between Create Duplicate (safe default — assigns a fresh ID and auto-increments the name with a numeric suffix like "My Preset (2)" on ID or name conflicts) and Replace Existing (overwrites the matching preset by its ID with the incoming content). Switching the strategy live re-evaluates the import result without re-uploading.
  • 📊 Four-Column Summary Grid — the modal displays a rich metadata box (preset name, source URL/file) and a Detected / New / Replaced / Skipped counts breakdown, giving you an at-a-glance audit of what the import will do.
  • 🔍 Expandable Item Inspector — an expandable, scrollable list shows every individual preset item with action badges (NEW, REPLACE, SKIPPED). Skipped items reveal their reason (exact ID match or identical name+content match with a different ID), so nothing is silently dropped.
  • ✅ Workspace Application Checkbox — optionally apply the imported preset directly to the active workspace ("Apply as Active Workspace Prompt") in one click.
  • 🌐 Unified URL & Local File Import Pipeline — the "Import JSON" action in the Configure Prompts modal now routes through the same openJsonPresetImport() pipeline as URL imports. Both flows share the PresetImportConfirmModal and useUrlPresetImport hook, giving local file imports the strategy selector, summary grid, and item inspector.
  • 🔗 preseturl Query Parameter — the URL preset import detector now also recognizes ?preseturl= (case-insensitive) alongside the existing presetUrl, configUrl, preset, and config parameters.

🛡️ Preset Workspace Safety — Replace Confirmation & State Persistence

  • 🚨 Preset Replace Confirmation Modal (PresetReplaceConfirmModal) — switching presets via the Quick Preset Selector when the active workspace contains unsaved prompt edits now triggers a dedicated confirmation dialog. Choose "Keep My Edits" (cancel switch) or "Replace Prompts" (confirm overwriting active system instructions and prompt template) to prevent accidental data loss.
  • 💾 Active preset state persistence across page refresh — loadedPresetId is now persisted in localStorage (prompt_generator_loaded_preset_id), so refreshing the browser retains the active preset connection and its [EDIT] badge status instead of resetting to "Custom Workspace."
  • 📸 Snapshot-based discard in Configure Prompts modal — opening the prompt configuration editor now captures an initial snapshot of the active preset state, ensuring that clicking "Cancel" and confirming discard accurately restores loadedPresetId, activeEditingPresetId, and newPresetName to their exact snapshot values.

🖌️ UI Refinements — Header, Quick Preset Selector & Mobile Layout

  • 💙 Ko-fi Support Button — a standalone KofiButton component styled with Ko-fi's signature soft blue background (#72a4f2) sits in the top navigation bar. Toggleable via the NEXT_PUBLIC_ENABLE_KOFI_BUTTON environment variable.
  • 🏷️ Simplified Header Navigation Buttons — top header actions streamlined to single-word labels with distinct pastel color accents for glanceability: Assets (Teal), Engine (Indigo), Prompts (Amber), and Clear (Rose with RotateCcw icon). Labels are hidden on mobile for compact icon-only buttons.
  • 📱 Mobile Header & Visual Assets Responsive Layout — the header splits into two rows on mobile: Row 1 with branding and Project Manager button (Quick Preset Selector hidden), Row 2 with icon-only action buttons stretching evenly. Visual Assets section header restored to a clean single-row desktop layout with title, action buttons, and the {{ visual_references }} tag.
  • 📝 Quick Preset Selector Row Redesign — each preset row now shows a 2-line system prompt excerpt preview beneath the preset name, giving users a quick understanding of what each preset does without opening the Configure Prompts modal. The "Manage All Presets & Prompts" footer button was removed for a cleaner dropdown experience.
  • 📖 Updated Lab Manual — refreshed onboarding guide reflecting current header control names, Files API uploads (up to 2 GB), preset URL sharing, and a quick tips bar highlighting Multi-Project Workspaces, Reasoning Effort levels, and History Archives.

🔐 ALLOW_SERVER_ENV_KEY — Enforce User-Supplied API Keys

A new deployment-level configuration flag lets you disable the server-side GEMINI_API_KEY, requiring every end-user to supply their own custom API key in Engine Controls — perfect for public or shared deployments where you don't want to expose shared API quotas.

  • 🚦 Gate the Server Key — set ALLOW_SERVER_ENV_KEY="false" to block all generation and file upload requests that don't include a user-supplied custom API key. The default is "true" (backwards-compatible — existing deployments continue working without changes).
  • 🧾 Differentiated Error Messages — users see a specific "Server environment API key usage is disabled on this deployment. Please enter your custom Gemini API key in 'Engine Controls'" message instead of a generic "No Gemini API key found" error, providing clear, actionable guidance.
  • ⚡ Per-Request Dynamic Client Instantiation — the generation handler (app/api/generate/route.ts) no longer uses a static module-level GoogleGenAI singleton. Instead, it creates a dynamic client instance on every request based on the resolved active API key (custom key first, then server env key if permitted), ensuring the correct key and user-agent are always used.
  • 🔧 Centralized getActiveApiKey() Helper — the Files API upload handler (app/api/upload-file/route.ts) extracts a shared helper function that centralizes key resolution logic across all upload actions: direct resumable, chunked proxy, list, delete, and single-file upload. Every action path now gets consistent key enforcement with proper differentiated error responses.

✨ What's New

  • 🎬 10 new folder-based presets — Cine DeepDive, Color Mapper, Comp Decoder, Film Lingo, Genre Lexicon, Motion Lab, Scene Lab, Shot Interp, Style Architect, and Vis Narrative replace the 3 original flat JSON presets
  • 🔀 Configurable import strategy — choose Duplicate (safe, auto-incrementing names) or Replace (in-place overwrite by ID) for preset imports
  • 📊 **Redesigned Pres...
Read more

v2.3.0: Upload. Measure. Persist.

Choose a tag to compare

@taruma taruma released this 28 Jul 05:38

PromptLab v2.3.0 integrates direct Gemini Files API integration for uploading media up to 2 GB with two upload paths and a built-in file browser, a comprehensive token usage and cost estimation system with real-time per-model pricing badges, and smarter preset state persistence that survives page refreshes. This release also delivers intelligent processing state polling, automated Base64 fallback when Files API assets expire, and hardened error handling across the entire upload and generation pipeline.


✨ Highlights

📤 Gemini Files API — Direct Uploads & Smart Browser

Upload images and videos up to 2 GB directly to Google's Gemini Files API via two upload paths — a high-speed direct resumable stream and a reliable chunked proxy — plus a "Select Existing" file browser for reusing previously uploaded assets without re-uploading.

  • ⚡ High-Speed Direct Resumable Upload (handleDirectResumableUpload in AddFilesApiModal.tsx) — requests a resumable upload session header (X-Goog-Upload-URL) from a new action: "resumable_session" backend endpoint and streams binary file bytes directly from the browser to Google Cloud via XMLHttpRequest with real-time percentage progress tracking (30%–95%), completely bypassing Vercel's 4.5 MB request body limit and execution timeouts for large media files up to 2 GB
  • 🔁 Smart CORS Verification — if browser CORS policies block reading the raw completion response, a background action: "list" call automatically checks Gemini Files API storage to confirm file creation without raising CORS error popups or duplicating uploads. If direct upload is blocked entirely, the system seamlessly falls back to the chunked proxy pipeline
  • 📦 Chunked Proxy Upload — splits large files into 2 MB chunks uploaded sequentially with a session uploadId, staged in system temp storage (start, chunk, finish, cancel actions), then reassembled and streamed to Gemini Files API via @google/genai
  • 🔍 "Select Existing" Tab — browse, search, and attach previously uploaded files stored on Google's Gemini Files API without re-uploading. The backend route supports action: "list" and action: "delete" commands using ai.files.list() and ai.files.delete(). Each file card displays filename, size, MIME type badge, ACTIVE/PROCESSING status, 48-hour expiration countdown, fileUri with a quick copy button, custom reference label input, and an instant "Delete" button with an in-modal confirmation banner (replacing native confirm() dialogs frequently blocked in iframe environments)
  • 🔄 Processing State Polling — both server-side and client-side automatically poll media files stuck in PROCESSING state until they reach ACTIVE. The generation route polls ai.files.get() up to 15 times at 2-second intervals per image/video reference before invoking generation. The upload modal polls up to 8 times post-upload (direct path) and up to 10 verify + 8 processing iterations (CORS verification path), showing "Processing media tracks on Google Cloud..." status feedback. Errors now differentiate between PROCESSING ("wait a few seconds and try again"), FAILED ("re-upload or select a different asset"), and expired/inaccessible states ("48-hour expiry or API key mismatch") with specific resolution guidance for each
  • 🛡️ Pre-Verification & Automatic Base64 Fallback — the generation pipeline pre-verifies every fileUri resource with ai.files.get() before invoking generateContentStream(). Inaccessible Files API assets (48-hour expiration, API key mismatch, or FAILED state) automatically fall back to inline Base64 data if available in the workspace asset payload. When fallback is impossible, it reports a clear asset-specific error identifying the exact @imageN/@videoN tag and resource ID with step-by-step resolution instructions
  • 🏷️ FILES API Badge & History — all Files API assets display an emerald-green FILES API badge on their asset cards (VisualAssetCard and VideoAssetCard) with local blob URL preview playback. References persist in HistoryItem objects with isFilesApi, fileUri, and expirationTime metadata, allowing historical generations to recall and re-run using active Files API URIs within their 48-hour lifecycle

💰 Token Usage Tracking & Cost Estimation

A comprehensive token tracking and cost estimation system gives you real-time visibility into generation costs, with per-model pricing badges in the engine controls and persistent cost data in your history.

  • 📊 Real-Time Token Display — the output panel header shows TOKENS: {total} ({prompt} IN [{cached} CACHED] / {candidates} OUT), updated live as the server broadcasts usageMetadata (prompt, candidates, total, and cached content token counts) via SSE usage events
  • 💵 Estimated Cost Badge — an emerald-green cost badge appears alongside the character count, computed by calculateEstimatedCost(selectedModel, tokenUsage) from the new lib/pricing.ts module. Costs display in USD ($0.001234 or < $0.000001 for sub-micro amounts)
  • 🗂️ 6-Model Pricing Table — lib/pricing.ts covers Gemini 3.6 Flash, 3.5 Flash, 3.5 Flash-Lite, 3.1 Pro Preview (tiered ≤200K / >200K), 3.1 Flash-Lite, and 3 Flash Preview, with audio input rate support and model alias resolution via MODEL_ALIASES
  • 🎛️ Pricing Rate Badges in Engine Controls — each model selection card in EngineControlsModal now displays per-model IN: $X.XX / 1M / OUT: $X.XX / 1M pricing rates in its footer, sourced from getModelPricingSummary(). Tiered pricing models display a range (e.g. $2.00–$4.00 / 1M)
  • 💾 Persistent Cost History — tokenUsage and estimatedCost are stored in HistoryItem objects at generation time via calculateEstimatedCost() and preserved across history JSON import/export. Cost display in HistoryCardSummary and HistoryViewerModal prefers the stored estimatedCost field over recomputation, keeping your historical cost data stable even if pricing rates change in the future
  • 🔁 Session-Surviving Token State — active tokenUsage persists to localStorage under prompt_generator_token_usage so your token counts survive page refreshes alongside other session state, restoring automatically on mount

💾 Preset Persistence & Error Hardening

  • 📌 Preset Selection Persistence — the active loadedPresetId is now persisted to localStorage under prompt_generator_loaded_preset_id and restored on application load. The loaded preset selection stays visible even when editor content diverges, with an amber [EDIT] badge on the preset list item indicating modified content alongside a [Deselect] option to clear the association
  • 🚫 413 Prevention — the chunked proxy upload pipeline completely eliminates HTTP 413 "Request Entity Too Large" errors for files up to 2 GB
  • 🧹 SSE Error Unwrapping — both server-side and client-side now properly unwrap stringified nested JSON error objects from the GoogleGenAI SDK into clean, human-readable text. 403 PERMISSION_DENIED errors on expired Files API assets now provide clear actionable guidance explaining 48-hour expiry and API key binding
  • 🖼️ Empty src Sanitization — six components (VisualAssetCard, VideoAssetCard, AssetLibrarySidebar, AssetImportModal, HistoryViewerModal, VideoPlayerModal) now rigorously sanitize image and video sources, rendering clean fallback placeholder UI instead of passing empty string "" values to <img>, <video>, or <iframe> src attributes, eliminating browser console warnings and unwanted network requests

✨ What's New

  • 📤 Gemini Files API integration — upload images/videos up to 2 GB via direct resumable upload or 2 MB chunked proxy
  • ⚡ High-speed direct resumable upload — streams bytes directly to Google Cloud via XHR, bypassing Vercel's 4.5 MB limit
  • 🔁 Smart CORS verification — background file listing confirms upload completion without error popups
  • 🔍 "Select Existing" file browser — browse, search, and attach previously uploaded Files API assets
  • 🔄 Processing state polling — server-side (15× at 2s) and client-side (8-18×) polling until files reach ACTIVE
  • 🛡️ Pre-verification with Base64 fallback — auto-fallback when Files API assets expire or are inaccessible
  • 🏷️ FILES API badge on asset cards with local blob URL preview playback
  • 💰 Token usage tracking — real-time token counts (prompt/candidates/cached/total) via SSE events
  • 💵 Estimated cost badge — live USD cost computed per-model from lib/pricing.ts with 6 models covered
  • 🎛️ Pricing rate badges in Engine Controls model selector cards
  • 💾 Cost history persistence — tokenUsage + stable estimatedCost stored in HistoryItem objects
  • 📌 Preset selection persistence — loadedPresetId survives page refreshes; [EDIT] badge on modified presets
  • 🚫 413 "Request Entity Too Large" prevention in Files API uploader
  • 🧹 SSE error unwrapping — 403 PERMISSION_DENIED on expired Files API assets now shows clear guidance
  • 🖼️ Empty src sanitization — six components prevent empty src attributes on media elements

🐛 Fixed

  • Files API Pre-Verification & Automatic Base64 Fallback — inaccessible fileUri resources automatically fall back to inline Base64 data if available; clear asset-specific errors when fallback isn't possible
  • Gemini Stream Error Formatting & 403 Permission Error Handling — SSE stream errors like 403 PERMISSION_DENIED on expired Files API file references are no longer swallowed internally; server and client both unwrap stringified nested JSON error objects with actionable guidance explaining 48-hour expiry and API key binding
  • In-Modal Deletion Confirmation for Gemini Files API Resources — native browser confirm()/alert() dialogs replaced with inline in-modal confirmation banner that works reliably inside pr...
Read more

v2.2.0: Organize. Visualize. Iterate.

Choose a tag to compare

@taruma taruma released this 26 Jul 09:27

PromptLab v2.2.0 introduces multi-project workspace management with independent IndexedDB-backed workspaces, a redesigned thinking trace visualization engine, one-click Quick Preset Selector in the navigation bar, and substantial UI density improvements across the entire workspace. This release also extracts the VisualAssetsSection into a standalone component, upgrades the IndexedDB schema to v2, and delivers richer history browsing with fuzzy search and inline output excerpts.


✨ Highlights

📂 Multi-Project Workspace Management

PromptLab graduates from a single-workspace tool to a full multi-project creative environment. Create, rename, switch, and delete independent workspaces — each with its own system instructions, prompt templates, custom presets, generation history, and asset library — all persisted in IndexedDB.

  • 🗂️ Full-screen ProjectManagerModal for browsing, searching, and managing all projects with a toggleable grid/compact view
  • 🔄 One-click project switcher in the AppHeader — swap workspaces without opening the full manager
  • 🧬 "Copy from Current" — clone your active workspace (prompts, presets, and asset library) into a fresh project for variant exploration without losing the original state
  • 📤 Project import/export with image bundling — export entire workspaces as versioned JSON files (promptlab_project v1.0) with all asset image blobs retrieved from IndexedDB; import validates payloads, restores images, and auto-resolves name collisions with incrementing suffixes
  • 📡 Cross-tab synchronization — BroadcastChannel-based messaging keeps the project dropdown and active workspace in sync across open browser tabs in real time
  • 🧳 Backward-compatible migration — legacy localStorage session data is automatically detected and migrated into a "Main Workspace" default project on first access, with transparent sync to legacy keys so all existing components continue to function without modification

🧠 Thinking Trace Visualization

The engine reasoning trace panel has been completely redesigned to provide clear, real-time insight into the model's internal thought process — now enabled for all models (the previous model-name gate has been removed).

  • 💡 Pulsing amber dot + PROCESSING badge during active thinking; transitions to a green dot + COMPLETED badge when finished
  • 📽️ Slideshow card mode during active streaming — the latest parsed reasoning block fades in with a custom slideFadeIn CSS animation for smooth, cinematic transitions
  • 📜 Completed full-log mode — the entire reasoning trace renders as a scrollable markdown-formatted block (max-h-[180px]) when generation finishes
  • 🔽 Auto-collapse on output — the reasoning panel automatically hides once generation output starts streaming, keeping the workspace clean during long generations
  • 💾 Thinking results persisted in HistoryItem objects and restored from localStorage — reasoning traces survive page refreshes, history save, and history recall

⚡ Quick Preset Selector & History Refinements

  • 🎛️ QuickPresetSelector in AppHeader — rapid one-click switching between system and custom prompt presets directly from the top navigation bar, reducing the need to open the Configure Prompts modal for routine preset changes
  • 🃏 Reusable HistoryCardSummary component — a rich preview card showing timestamp (24-hour format), media badges (IMG/VID counts with icons), model badge, preset badge, title/idea excerpt, and a cleaned markdown-free output excerpt (~220 characters). Integrated consistently across LoadWorkspaceConfirmModal, DeleteHistoryConfirmModal, and HistorySection
  • 🔎 Fuzzy search with tokenized matching — new lib/search-utils.ts module with normalizeText() and matchesSearchQuery(). History search now correctly matches hyphenated terms (e.g., "sci-fi" ↔ "sci fi") and supports multi-word keyword queries across all search scopes
  • 📝 Output excerpt preview in history list items — a 2-line italic excerpt of the cleaned generation output (~140 characters) appears beneath each history card in the HistoryViewerModal sidebar, giving quick context without opening the detail panel
  • 👆 Auto-scroll to selected history item — scrollIntoView with smooth behavior ensures the active item is always visible in long history lists
  • ❌ Clear search button — a dismiss X inside the history search input for one-click query clearing

🎨 UI Polish & Density

  • 📐 Compact 5-column visual asset grid — refined from 4 columns to md:grid-cols-3 lg:grid-cols-5 with reduced internal padding and gaps across VisualAssetCard, VideoAssetCard, and the drag-and-drop uploader for significantly denser information layout
  • 🖼️ Aspect-ratio-preserving hover previews — image hover previews now use object-contain with dynamic w-fit max-w-[340px] sizing, displaying each reference at its natural proportions rather than a rigid square box
  • 📥 Collapsible generation result — the output panel now supports collapsing with state persisted in localStorage for session-to-session continuity
  • 📋 Enhanced copy button — redesigned with Copy / Check (checkmark on success) lucide-react icons alongside the text label, replacing the plain text-only button
  • 🔢 Live character count badge — {N} CHARS using toLocaleString() formatting appears next to copy/expand controls when output is present
  • ⏱️ Preset timestamp metadata — createdAt and updatedAt fields added to all presets (system + custom), with date-based sorting options and a formatPresetDateShort helper for consistent date display
  • ◀️ Standardized section chevrons — all accordion sections now use ChevronRight (▶) when collapsed and ChevronDown (▼) when expanded, following standard UI conventions
  • 📄 Unified export filename convention — all export types (assets, history, presets, projects) follow promptlab_{projectSlug}_{feature}_{date}_{time}_{uniqueId}.json with a shared slugify() helper; asset library JSON exports are now pretty-printed with 2-space indentation

✨ What's New

  • 📂 Multi-project workspace management — lib/projects.ts + ProjectManagerModal with full CRUD, import/export, and IndexedDB persistence
  • 🔄 Project switcher in AppHeader — compact dropdown for one-click workspace switching
  • 🧬 "Copy from Current" project creation — clone the active workspace into a new project instantly
  • 📡 Cross-tab project synchronization via BroadcastChannel (promptlab_project_sync_channel)
  • 🧳 Backward-compatible migration — legacy localStorage data auto-migrated to "Main Workspace" project on first access
  • 🎛️ QuickPresetSelector component — rapid preset switching from the top navigation bar
  • 🧠 Redesigned thinking trace visualization — pulsing amber dot during processing, slideshow card mode with slideFadeIn animation, completed full-log view with markdown rendering, and auto-collapse behavior
  • 🌐 Universal thinking/reasoning for all models — server-side includeThoughts: true for every model (model-name gate removed)
  • 🃏 HistoryCardSummary reusable component — rich preview cards with timestamp, media badges, model, preset, and output excerpt
  • 🔎 Fuzzy search utility (lib/search-utils.ts) — tokenized matching with hyphen/punctuation normalization
  • 📝 Output excerpt previews in HistoryViewerModal list items (~140 characters, cleaned markdown)
  • 👆 Auto-scroll to selected history item with smooth behavior
  • ❌ Clear search button (X) in history viewer search input
  • 📥 Collapsible generation result section with localStorage-persisted state
  • 📐 Compact 5-column visual asset grid — denser layout with reduced padding and gaps
  • 🖼️ Aspect-ratio-preserving hover previews — object-contain with dynamic max-width
  • ⏱️ Preset timestamp metadata — createdAt / updatedAt fields with date-based sorting
  • 📋 Enhanced copy button with icons — Copy / Check lucide-react icon states
  • 📄 Unified export filename convention — all exports follow promptlab_{projectSlug}_{feature}_{date}_{time}_{uniqueId}.json with pretty-printed asset library JSON
  • 🎨 @keyframes slideFadeIn CSS animation in globals.css for smooth section transitions

🐛 Fixed

  • 🐛 Standardized section accordion chevrons across VisualAssetsSection, LabManualSection, HistorySection, and preset list accordions — now consistently using ChevronRight (collapsed) / ChevronDown (expanded)
  • 🐛 Project management stability — isSwitchingProjectRef guard prevents auto-save and asset-library callbacks from firing during active project switches, eliminating state race conditions
  • 🐛 Zero-projects fallback — handleProjectsUpdated() auto-creates a default workspace when no projects exist
  • 🐛 Project deletion fallback — enhanced flow ensures the active project correctly falls back to the next available project after deletion
  • 🐛 Persistence layer — updated to support both legacy (prompt_generator_history) and current (prompt_generator_history_v1) localStorage history keys

🔄 Changed

  • ⚡ Compact 5-column visual asset grid — refined from 4 columns to md:grid-cols-3 lg:grid-cols-5 with tighter internal spacing
  • ⚡ Hover preview preserves original image aspect ratio — object-contain with dynamic sizing replaces fixed 280px square preview
  • ⚡ HistorySection header restructured — inline "Clear All" button removed (now only in full HistoryViewerModal), expand/collapse chevrons moved left, layout reorganized for cleaner filter tab separation
  • ⚡ History Viewer sidebar visual refresh — selected items use warm amber highlight (bg-[#FEF3C7]) instead of dark left-border, non-selected items have transparent border for consistent alignment, card spacing tigh...
Read more

v2.1.0: Capture. Compare. Export.

Choose a tag to compare

@taruma taruma released this 24 Jul 07:50

PromptLab v2.1.0 introduces multi-modal video references (MP4 uploads + YouTube URLs), Markdown-rendered generation output, history diff comparison, asset library import/export, and a major architecture refactor extracting 9 reusable components from the monolithic workspace.


✨ Highlights

🎬 Multi-Modal Video & YouTube Support

PromptLab now supports video references alongside images. Upload MP4 files (≤30 seconds, ≤35 MB) or add YouTube URLs — both map to @videoN annotations in your prompt templates and stream to Gemini as inlineData / fileData parts.

  • 📹 Local MP4 upload with automatic validation and Base64 encoding
  • ▶️ YouTube URL references with auto-extracted thumbnails and embedded iframe previews
  • 🔗 Unified {{ visual_references }} pipeline combining all image and video assets server-side
  • 🃏 Three-state VideoAssetCard handles YouTube (playable), cached MP4 (playable), and uncached historical MP4 (NO LOCAL STREAM placeholder)
  • 🖥️ Full-screen VideoPlayerModal for pre-generation preview of both MP4 and YouTube references
  • 💾 Video metadata preserved in history — recall, export, and import with purple {N} VID badges

📝 Markdown-Enabled Output Rendering

The generation output panel now supports a Formatted Markdown / Raw Monospace toggle. Output is rendered with react-markdown using custom-styled headings, lists, bold, italic, inline code, and horizontal rules — all in PromptLab's brutalist aesthetic. The raw monospace view remains available for users who prefer the original plain-text output.

🔍 History Diff Compare

A new [Diff] button in the HistoryViewerModal detail panel opens the shared PresetCompareModal to show line-by-line differences between a saved history item's prompt configuration and your current active workspace. Audit how your system instructions and prompt templates have evolved over time with unified or split diff views.

📤 Asset Library Import & Export

The asset library now supports JSON export (All or Selected images) and import with automatic duplicate detection. Previously exported library files can be re-imported, with a processing summary reporting total imported, duplicates skipped, and errors encountered.

🟢 Optional Core Idea

The Main Objective / Idea field is no longer required for generation. You can now run generations using only dynamic parameters and your prompt template — useful for lightweight testing or pure template-driven workflows.


✨ What's New

  • ✨ Markdown rendering toggle in generation output (Formatted / Raw) via GenerationResultView
  • ▶️ YouTube URL video references with @videoN mapping, thumbnail extraction, and iframe preview
  • 🎬 Multi-modal video support — MP4 upload with validation, Base64 encoding, and unified reference pipeline
  • 📦 VideoAssetCard component with three-state rendering (YouTube / cached MP4 / uncached MP4)
  • 📦 VideoPlayerModal component for full-screen video preview (HTML5 + YouTube iframe)
  • 💾 Video history tracking — metadata persists across sessions, exports, and imports
  • 🎨 YouTubeIcon custom SVG component replacing all lucide-react Youtube imports
  • 📤 Asset library JSON export and import with duplicate detection
  • 🔍 History diff compare via shared PresetCompareModal
  • 🟢 Optional Core Idea — generation works without the Main Objective field
  • 💬 PromptTemplateHelpTooltip component for inline {{ variable }} syntax guidance

🐛 Fixed

  • 🐛 Empty-string prompt inputs are no longer overwritten by filesystem template defaults
  • 🐛 History cards for custom prompts now show a CUSTOM badge
  • 🐛 Broken YouTube thumbnails gracefully degrade to a YouTubeIcon placeholder

🔄 Changed

  • ⚡ Simplified history item loading — centralized state management handles restoration
  • ⚡ "Reset Prompts" now clears the editor client-side for instant feedback

🏗️ Architecture

  • 🏗️ Extracted 9 reusable components from page.tsx: AppHeader, FooterStatusBar, LabManualSection, MainIdeaSection, ParameterInputsSection, ClearSessionConfirmModal, DeleteHistoryConfirmModal, DiscardChangesConfirmModal, LoadWorkspaceConfirmModal
  • 📉 Main workspace file reduced by ~475 lines (net)

⬆️ Upgrade Notes

  • ✅ No breaking changes. All existing localStorage data, IndexedDB images, history items, and custom presets are fully compatible with v2.1.0.
  • 💾 Video references added to history before upgrading from v2.0.0 will not contain video metadata — only generations created in v2.1.0+ will include the new videos field.
  • 🎨 The lucide-react Youtube icon is no longer used; a custom YouTubeIcon SVG component replaces it throughout the UI.

🔗 Resources