- Stable release — unified CLI + web versions, 6 AI provider integrations, gallery system, prompt analysis
- Replaced flat diversity-picking architecture table with a progressive API Layers diagram — shows the
diversePick → pickWithHistory → createPicker → useDiversePickstack visually as an ASCII tower - Added collapsible usage examples with copy-paste TypeScript for all 4 API layers (pure function, combined, factory, React hook)
- Restructured architecture table to foreground concern per layer instead of listing every export — scannable at a glance
- Noted migration path:
createPickeranduseDiversePickshare an identical call signature, enabling React-free testing of the same logic
- Redesigned README hero section — replaced wall-of-badges with a scannable layout: bold tagline, intentional badge colors (
#3178c6TypeScript,#0ea5e9Tailwind,#d946efFramer,#8b5cf6zero-any,#22d3eeMIT), and HTML table screenshots for consistent rendering - Replaced ASCII box-drawing
How It Worksdiagram with rounded Unicode (╭╰) and circled numbers (①②③) for visual personality - Added inline blockquote accents to "What Makes This Different", "Engineering Highlights", and "Design Philosophy" sections for typographic rhythm
- Consolidated at-a-glance stats into a single-line monospace counter strip — replaces the 3×2 table that repeated badge data
- Tightened footer to a 3-line sign-off with
<sub>tagline
- Synced all test counts in README to 429 tests / 2,200 assertions (was 417/2,144 in 6 locations) — reflects diversity-picking test additions from 0.8.2–0.11.0
- Updated diversity-picking architecture table with
pickWithHistory,createPicker, andparseFieldKeyAPIs added in 0.10.0–0.11.0 - Added "Temporal coupling elimination" to Engineering Highlights — documents the
pickWithHistory→createPickerlayered API design - Updated diversity-picking doc reference to mention 71 tests and the full
diversePick → pickWithHistory → createPickerAPI progression - Added
createPickeras a dedicated architecture layer row — headless/non-React consumers now have a documented entry point
pickWithHistory<T>(options, recent, maxSize)— combined pick+push that returns{ value, recent }in one call, eliminating the temporal coupling betweendiversePickandpushRecentcreatePicker<T>(windowSize)— stateful per-key picker factory for non-React consumers (tests, scripts, CLI), drop-in replacement for theuseDiversePickhook's return valuePickResult<T>interface for typed pick-with-history return values- 12 new tests covering
pickWithHistory(5 tests) andcreatePicker(4 tests) including sequential non-repeat guarantees, per-key isolation, andbuildRandomPromptintegration
useDiversePickhook now delegates topickWithHistoryinternally — same behavior, reduced surface area for bugs- Test count: 71 tests / 701 assertions in
diverse-pick.test.ts(up from 59/~600) - Full suite: 429 tests / 2,200 assertions (up from 420/2,147)
parseFieldKeyutility — single-responsibility parser for dot-delimited field keys, eliminates duplicatedsplit('.')logic acrossbuildRandomPrompt- 3 new tests for
parseFieldKeycovering two-segment, multi-dot, and single-segment keys
buildRandomPromptnow merges categories sharing a field prefix instead of overwriting — fixes data loss when multiple wizard categories contribute fields to the same data model key (e.g.subject-info+subject-detailboth writing tosubject.*)flattenPromptToTextnow trims values before inclusion — whitespace-only strings are excluded from output instead of producing artifacts like" , real"- Updated 2 existing tests to reflect corrected merge and trim behaviors
- Data loss bug: when two categories shared a field prefix (e.g. both using
shared.*), the second category's fields completely replaced the first. Now both categories' fields are preserved via merge
- Deleted deprecated
generateCompactJSONexport — all callers migrated togenerateJSON(prompt, true)which has been the canonical API since 0.7.0 - Removed 10 stale imports of
generateCompactJSONacross 5 test files
- Renamed
generateCompactJSONdescribe blocks togenerateJSON compact modefor clarity — tests now exercise thecompactparameter directly instead of through a wrapper
- Complexity analysis section in
docs/diversity-picking.md— documents O(n) time/space fordiversePick, O(w) forpushRecent, O(c×f) forbuildRandomPrompt, and O(v) forflattenPromptToTextwith real-world scale context - Three usage examples in diversity-picking doc — per-field randomize button (React), full-prompt Quick Mode pattern, and headless usage outside React for tests/scripts
- Six new proven invariants (#10–#15) in the invariants table: probabilistic fairness (chi-squared), pigeonhole coverage, reference equality semantics, large pool correctness, per-field isolation, and negative maxSize boundary
- Updated test count in diversity-picking doc from 35 to 59 tests across 10 describe blocks — reflects all edge-case, probabilistic, and boundary tests added in 0.8.2–0.8.3
- Updated README documentation section with expanded description of diversity-picking doc contents
- Enhanced README hero section with a punchier tagline that sells the Flash Era personality and zero-blank-box-anxiety value prop
- Added "At a Glance" quick-stats table below the badge row — 6 key numbers (13 categories, 7,000+ prompts, 3 models, 417 tests, 2 platforms, 240 patterns) for instant scanability
- Added "What Makes This Different" subsection under "Why This Exists" — highlights diversity-aware randomization, model-aware output, composable architecture, and test invariants as portfolio differentiators
- Improved screenshot alt text from generic labels to descriptive captions that communicate what each screen shows
- Added "Why This Exists" entry to Table of Contents (was missing despite the section existing)
- Polished footer with a thematic closing line that ties the Flash Era aesthetic to the engineering story
- 13 new tests for diversity-picking algorithm covering probabilistic fairness (chi-squared distribution sanity), pigeonhole coverage guarantee (window = n-1 forces all options before repeats), negative maxSize boundary, empty-suggestions contract propagation, field iteration order preservation, whitespace-only value behavior in flatten, mixed empty/populated category structure, insertion-order preservation in flatten output, and full-cycle multi-category simulation with diversity + structure invariants
- Total test count: 404 → 417 (17 files), assertions: 1,832 → 2,144
- 11 new tests for diversity-picking edge cases and algorithm invariants — reference equality semantics for object options (Set uses
===, not structural equality), duplicate handling in bothdiversePickandpushRecent,maxSize=0boundary, large pool (1000 options) correctness, single-segment and multi-dot key parsing inbuildRandomPrompt, category prefix collision behavior ("last wins" documented), window eviction proof (items slide out and become re-eligible), full-window graceful degradation, and per-field history isolation simulating the realuseDiversePickhook pattern - Total test count: 393 → 404 (17 files), assertions: 1,707 → 1,832
- Synced
web/package.jsonversion from0.1.0to0.8.1— was never bumped from the Next.js scaffold default, causing a 20-release drift from CHANGELOG versions
- Added
.todoignoreat project root — excludesnode_modules/,.next/,dist/,build/,coverage/, and.git/from TODO/code-debt scanning to prevent upstream dependency internals (e.g. Zod'sfrom-json-schema.jsTODOs foruniqueItems/contains) from being flagged as project debt
- Extracted
MODEL_NAMES,MODEL_COLORS, andisValidModeltype guard into sharedweb/src/lib/models.ts— eliminates 4× copy-pasted model metadata across wizard, quick, preview, and generate pages - Created
useCopyToClipboardhook (web/src/hooks/useCopyToClipboard.ts) — replaces 3× duplicateduseState/setTimeoutclipboard pattern in quick, preview, and result pages, with proper timer cleanup viauseRef - Replaced raw
['nano-banana', 'openai', 'kling'].includes()checks withisValidModel()type guard in wizard and preview pages — adding a model is now a single-file change
- Technical reference document
docs/diversity-picking.md— comprehensive deep-dive into the sliding-window exclusion algorithm covering the problem statement, step-by-step click trace, graceful degradation behavior, 4-layer architecture diagram (pure algorithm → composition → React binding → integration), full API reference for all 5 exported functions/hooks, 9 proven invariants table with consequence analysis, and design decision rationale (window vs shuffle, Set-based exclusion, key derivation strategy, default window sizing) - Linked new diversity-picking doc from README Documentation section
- Added collapsible "Proven properties" table to Diversity-Aware Randomization README section — documents 8 algorithmic properties verified by the 35-test suite (exclusion, graceful degradation, type generality, statistical diversity, window sliding, integration, key derivation, round-trip fidelity)
- Updated Engineering Highlights diversity row with exported interfaces, full function inventory, and cross-link to proven properties
- Refined test table description for diversity suite with superset-recent, immutability, 12-round no-triple-repeat, and build→flatten round-trip detail
- Exported
PickableFieldandPickableCategoryinterfaces fromdiverse-pick.ts— consumers can now type-check against the expected shape instead of duck-typing - Replaced
||with??(nullish coalescing) inbuildRandomPromptcategory key derivation — only falls back tocategory.idwhen no fields exist, not on empty string - Added inline documentation explaining why output keys derive from field key prefixes rather than category IDs (data model vs UI label divergence)
- 14 tests for
buildRandomPromptandflattenPromptToText— covers category key derivation, field pass-through, empty categories, unicode handling, empty value filtering, and build-flatten round-trip integration with diversity picker - Total test count: 379 → 393 (17 files), assertions: 1,687 → 1,707
- Expanded "Diversity-Aware Randomization" README section from 4-line overview to full algorithm walkthrough with step-by-step click trace showing window sliding and graceful fallback behavior
- Added architecture table mapping the 4-layer stack (pure algorithm → React hook → wizard → Quick Mode) with file paths
- Enhanced feature bullet with cross-link to architecture detail section
- Updated Engineering Highlights and Challenges & Solutions entries with test counts, cross-links, and fallback documentation
- Improved test table description for diversity suite to explicitly name all tested functions
- Extracted
buildRandomPromptandflattenPromptToTextpure functions from Quick Mode page intodiverse-pick.ts— prompt assembly is now testable and reusable without React - Made
useDiversePickhook generic over value typeT(defaultstring) instead of hardcoded tostring - Reduced Quick Mode's
handleRandomizefrom 18 lines of inline logic to 6 lines composing extracted utilities
- 52 tests for web-side pure functions (
diverse-pick.ts,validation.ts) — first test coverage for the web layer diversePicktests: empty array throw, exclusion behavior, full-pool fallback, statistical diversity, readonly safety, integration withpushRecentsliding windowvalidatePrompttests: type rejection (null/undefined/number/object/array/boolean), whitespace-only rejection, 10K char boundary, C0/C1 control char stripping, unicode preservationvalidateApiKeytests: format validation, injection defense (SQL, XSS, header injection), 256-char boundary, special character allowlist- Total test count: 327 → 379 (17 files), assertions: 1,458 → 1,687
- Added "Data Pipeline" section to README documenting the 6 scripts that refresh and expand the prompt library (fetch → translate → extract → generate → update)
- Credited second prompt source
@YouMind-OpenLab/awesome-nano-banana-pro-prompts(5,600+ prompts) — was previously undocumented - Expanded multi-model table with per-model behavioral notes: DALL-E 3's revised-prompt feature, Kling's two-phase async polling architecture
- Updated Inspiration Gallery section with concrete numbers: 240 patterns across 5 categories, Showcase page with 13-category breakdowns
- Added
useInspirationDatahook to project structure (lazy-loading data layer for all prompt files) - Expanded sound system description: 5 named sounds, off by default, opt-in, persisted preference
- Added Data Pipeline link to table of contents
- Added "Engineering Highlights" section to README — showcases technical decisions (zero-
anytypes, composable pipeline, diversity-aware randomization, centralized validation, data-driven parsing, test invariants) with rationale for each - Added "Diversity-Aware Randomization" and "Input Validation & Sanitization" architecture subsections documenting the sliding-window algorithm and centralized validation layer
- Updated project structure tree to reflect new files:
diverse-pick.ts,validation.ts,useDiversePick.ts,usePatterns.ts - Added 2 new Challenges & Solutions entries: randomize repetition fix and type safety at serialization boundaries
- Added "Zero Any" and "Assertions: 1,458" badges to header badge row
- Added 7 HTTP security headers to all Next.js routes via
next.config.ts:X-Content-Type-Options,X-Frame-Options,Referrer-Policy,Permissions-Policy,Strict-Transport-Security,X-XSS-Protection,X-DNS-Prefetch-Control - Sanitized upstream API error responses in all 3 generation routes (nano-banana, openai, kling) — error messages from third-party APIs are no longer forwarded to the client, preventing info leakage of internal hostnames, request IDs, and API internals
- Added
.catch()guards on all upstreamresponse.json()error parsing to prevent unhandled exceptions when APIs return non-JSON error bodies - Mapped upstream HTTP status codes to generic client-facing messages (401 → invalid key, 429 → rate limited, other → upstream failure)
- Audited npm dependencies: 0 vulnerabilities in
web/(root has no lockfile — CLI uses Bun) - Reviewed CLI arg parsing and API input validation — existing
validation.tssanitization (length limits, control char stripping, API key format regex) is solid, no injection vectors found
- Extracted
diversePickpure function andpushRecenthelper intoweb/src/lib/diverse-pick.ts— diversity-aware random selection with sliding-window recent exclusion - Created
useDiversePickReact hook (web/src/hooks/useDiversePick.ts) wrapping the pure function with per-field-key recent tracking viauseRef - Refactored
WizardStep.tsxrandomize handler to useuseDiversePickinstead of naiveMath.random()— consecutive clicks now cycle through varied suggestions - Refactored Quick Mode
handleRandomizeto useuseDiversePick— full-prompt randomization avoids repeating the same suggestion per field across clicks
- Eliminated all
anytypes fromcleanObjectinsrc/generators/json.ts— replaced withunknownfor full type safety at the serialization boundary - Unified
generateJSONandgenerateCompactJSONinto a singlegenerateJSON(prompt, compact?)API —generateCompactJSONis kept as a deprecated re-export for backward compatibility - Replaced 5-branch
else ifpreset parsing chain insrc/cli/args.tswith a data-drivenPRESET_FLAGSlookup map — adding new presets is now a one-line change - Removed dead
presetFlagsarray fromargs.ts(declared but never referenced)
- Upgraded README to portfolio-grade with table of contents for quick navigation
- Added "How It Works" 3-step visual flow diagram for instant comprehension of the product
- Promoted Quick Mode feature to prominent callout (was previously undocumented in README)
- Updated testing section to reflect 327 tests across 15 test files (was stale at 303/14)
- Added cross-cutting invariants row to test table (24 tests were missing from the table)
- Wrapped Project Structure and Challenges & Solutions in collapsible
<details>sections to reduce scroll fatigue - Added author attribution link in footer
- Added showcase count detail (30 hand-picked + 113 AI-generated)
- Cross-cutting test suite (
src/cross-cutting.test.ts) — 24 tests covering cross-format consistency (NL vs JSON generators stay in sync on the same ImagePrompt), cleanObject edge cases (nested array filtering, deep empty object collapse, falsy value preservation), PROMPT_SECTIONS pipeline invariants (purity, return type contracts, fragment validation), and parseArgs boundary conditions (missing flag values, unknown flags, trailing commas) - Documents intentional asymmetry:
semantic_negativesis JSON-only, no NL section handles it - Total tests: 327 (up from 303)
- Template-through-pipeline integration tests (
src/core/templates.test.ts) — 36 tests verifying every built-in template produces valid natural language and JSON output, vibes survive the pipeline, deep nested fields survive cleanObject, template merging with user data works correctly, and template data integrity (slug format, description length, aspect ratio consistency) - Total tests: 303 (up from 267)
- Widened
getNestedValuetype signature to acceptnull | undefinedroots without throwing — matches runtime behavior that the function already handled safely - Recovered 6 edge-case tests from failed agent branch (
passion/tests-diversity-picked-tests-mlofibhk) that targeted the wrong file path after a refactor movedsetNestedValue/getNestedValuetolib/nested.ts
- Tests for null/undefined root objects, falsy value preservation (
'',0,false), in-place intermediate mutation, independent branch isolation, and a full wizard simulation roundtrip (267 total tests, up from 261)
- Converted
showPostGenerationMenufrom unbounded recursion to iterativewhileloop — eliminates stack overflow risk in long sessions with repeated copy/save actions - Replaced 5 duplicated
p.cancel('Cancelled'); process.exit(0)blocks inprompts.tswith a singleexitIfCancelledassertion function that also provides TypeScript type narrowing - Extracted
getNestedValue/setNestedValuefromprompts.tsinto sharedsrc/lib/nested.tswith properRecord<string, unknown>typing (replacedany), added guard against primitive intermediates insetNestedValue
- Unit tests for
getNestedValueandsetNestedValue(src/lib/nested.test.ts) — 13 tests covering dot-notation traversal, missing paths, null traversal, intermediate creation, sibling preservation, and primitive-to-object overwrite
- API reference documentation (
docs/API.md) covering all three generation endpoints (Nano Banana, DALL-E 3, Kling) with request/response schemas, validation rules, error codes, and rate limiting behavior - Full CLI command reference with all flags, shortcuts, and usage examples
- Validation rules table documenting prompt length limits, control character stripping, and API key format requirements
- Documentation section in README linking to API reference and contributing guide
- Redesigned README as a portfolio-grade landing page with centered hero section, test count badge, and "Why This Exists" value proposition
- Added Quick Start section for instant onboarding (clone → run in 2 commands)
- Replaced ASCII architecture diagrams with Mermaid flowcharts (renders natively on GitHub)
- Restructured testing section as a scannable table with per-module test counts
- Converted Challenges & Solutions from prose paragraphs to a comparison table
- Promoted Privacy & Security to its own top-level section
- Added back-to-top navigation link and centered footer
- Unit tests for category data integrity (
src/core/categories.test.ts) — 16 tests validating all 13 categories are inallCategoriesandcategoryMap, unique names and emojis, field key dot-notation validity, no duplicate keys across categories, non-empty suggestions, and core category prompt_type/subject.description presence - Unit tests for display text wrapping (
src/cli/display.test.ts) — 11 tests covering word-boundary wrapping, exact-width boundaries, long words exceeding width, unicode wrapping, empty input, and displayOutput integration via console capture - Unit tests for Gemini analyzer error paths and parsing (
src/analyzer/gemini.test.ts) — 14 tests covering missing API key error, missing file error, JSON markdown fence stripping (\``jsonand plain````), MIME type detection for all 5 supported formats plus fallback, and documents a known limitation where triple backticks inside JSON string values get silently stripped
- Unit tests for all 13 section generator functions (
src/generators/sections.test.ts) — 56 tests covering empty inputs, partial data, deduplication logic (hair style vs structure), action/body_position precedence, accessory field filtering, film texture date_stamp "none" exclusion, vibes formatting tiers (1/2/3+/4+), and PROMPT_SECTIONS pipeline order verification
- Comprehensive TSDoc for the entire
ImagePrompttype tree (src/types/prompt.ts) — every interface and field now has descriptions, examples, and cross-references - JSDoc for all 13 section generators in
sections.ts— documents output format, precedence rules, and edge cases - JSDoc for
generateNaturalLanguage,generateJSON,generateCompactJSON, andcleanObjectwith@exampleblocks and{@link}references - Architecture note in README referencing inline documentation
- Extracted generic
useLocalStorage<T>hook (web/src/hooks/useLocalStorage.ts) — typed, SSR-safe localStorage sync with cross-tab updates viaStorageEvent - Refactored
useFavoritesto useuseLocalStorage— eliminated manual load/save boilerplate, fixed stale-closure bug intoggleFavoriteby making it atomic - Refactored
useFreeTierto useuseLocalStorage— removed standalonegetStoredUsage/saveUsagefunctions, reduced from 86 to 52 lines
- Unit tests for
JsonStore(src/lib/json-store.test.ts) — 11 tests covering load defaults, deep-clone isolation, save/overwrite, roundtripping complex structures, exists check, and ensureDir callback - Unit tests for packs and templates (
src/core/core.test.ts) — 18 tests covering pack composition, preset expansion, deduplication, always-include-core invariant, full-coverage assertion, template integrity, unique names, and listing API surface
- Fixed Passion Agent failures caused by hardcoded hook paths in
~/.claude/settings.json— replaced/Users/t./with$HOMEso hooks resolve correctly on both MacBook Pro and Mac Mini - Root-caused 6 consecutive agent failures: SessionEnd hook
session-auto-save.mjscouldn't be found on Mac Mini (usertdot) because paths were synced from MacBook Pro (usert.) via Syncthing
- Unit tests for CLI argument parser (
src/cli/args.test.ts) — 22 tests covering all 15 flag branches, shorthand aliases, pack comma-splitting, favorites subcommands, and combined flag handling
- Extracted generic
JsonStore<T>class intosrc/lib/json-store.tsto eliminate duplicated load/save boilerplate across storage modules - Refactored
config.ts,favorites.ts, andpresets.tsto useJsonStore— reduced combined storage code by ~30% (52 deletions, 35 insertions) presets.tsuses astoreFor(name)factory pattern for its directory-backed collection- Deep-clones default values to prevent shared-reference mutation bugs
- Added centralized input validation and sanitization for all API routes (nano-banana, openai, kling)
- Enforce 10,000 character prompt length limit to prevent abuse via oversized payloads
- Strip control characters (null bytes, C0/C1 range) from prompts before forwarding to APIs
- Validate API key format and length (max 256 chars, alphanumeric + limited special chars)
- Updated Next.js from 16.1.1 to 16.1.6 to fix 3 high-severity vulnerabilities (DoS via Image Optimizer, HTTP deserialization DoS, unbounded memory via PPR)
- Verified no hardcoded API keys or secrets anywhere in codebase
- Added live demo link, bug report, and feature request links to README header
- Added environment variables table documenting
GEMINI_API_KEYserver-side scope - Added "Deploy Your Own" section with Vercel one-click deploy button and manual instructions
- Added API key pricing table with per-image costs for Gemini, DALL-E 3, and Kling
- Fixed prompt count discrepancy: updated from 1,050+ to 1,180+ to match actual data
- Rewrote README as portfolio-grade documentation covering both web app and CLI tool
- Added multi-model comparison table, free tier documentation, CLI command reference
- Added architecture section with composable pipeline diagram and page flow
- Restructured project tree to reflect full codebase (analyzer, hooks, inspiration, data pipeline)
- Screenshots now displayed in responsive table layout
- Tech stack shown as web/CLI comparison table
- Added badges for Bun runtime and MIT license
- Refactored natural language generator into composable section pipeline
- Extracted 13 independent prompt section generators into
sections.ts - Reduced
natural.tsfrom 131 lines to 18 lines usingflatMappipeline pattern - Each section (subject, hair, clothing, camera, etc.) is now an independently testable pure function
- Exported
PROMPT_SECTIONSarray and individual section functions for external use and custom pipelines
- Unit tests for prompt building edge cases: action/body_position precedence, section ordering, deep nesting cleanup, Unicode handling, generator consistency
- Testing section in README
- 15 pre-existing test failures caused by capitalization sensitivity when testing sections in isolation without a subject