Muse Studio

Creative Multimedia Workshop — idea capture and organization, multi-source asset search with circuit breaker, layered soundscape design, interactive narrative building, and MadLibs-style creative writing. The most complex integration in the AP ecosystem, crossing the language boundary between a Python REST backend (stock-art-collector) and a TypeScript/React frontend.

Zone: staging/ (active development, v0.1). Part of Phase 2 Wave C.

Key Decisions

DecisionRationaleDate
ADR-001: TypeScript circuit breaker over Python dependencyAvoids cross-language runtime dependency — AssetManager follows same interface patterns as stock-art-collector’s SourceAdapter ABC; actual API calls go through the REST API on port 30702026-02-06
ADR-002: Declarative soundscape layersStores layer configs as data (preset name, volume, playback rate, loop flag); React UI creates the Web Audio graph from declarative config — same pattern as Tavern’s SoundEffects, keeps core logic testable in Node.js2026-02-06
ADR-003: DJB2-variant string hash for deduplicationTrue pHash requires image pixel processing (canvas/sharp); URL-based dedup handles 90% of cases; Python stock-art-collector already implements real perceptual hashing server-side2026-02-06
ADR-004: Built-in MadLibs templatesBundle 3 templates (adventure-hook, character-intro, scene-setter) with {key} interpolation; simpler than @ap/narrative-engine’s InterpolationEngine, matches creative writing context2026-02-06
ADR-005: Tab-based React UI with view-per-module pattern4 views (Creative Dashboard, Idea Workspace, Soundscape Mixer, Story Builder) map to 5 core TypeScript modules; MadLibs integrated into Story Builder rather than standalone2026-02-12

Patterns Established

PatternDescriptionReusable
Declarative audio layer configStore soundscape layers as plain data objects; let the UI layer create the Web Audio graphYes
TypeScript circuit breaker wrapping Python REST APIAssetManager mirrors Python SourceAdapter interface; all external calls go through REST port boundaryYes
View-per-module tab layoutOne tab per primary workflow, backed by one or more modules; compound features (e.g., MadLibs) colocated with their closest workflowYes

Lessons Learned

LessonContextImpact
Cross-language boundary via REST is cleaner than shared typesPython stock-art-collector provides Unsplash/Pexels/Pixabay search — exposing it as a REST API on port 3070 allows the TypeScript frontend to treat it as any HTTP serviceAdopted as the integration pattern for all Python→TypeScript boundaries
MadLibs content depth mattersWeb port started with 3 templates vs 20+ in iOS original — content regression is a real risk on rewritesCarry over content breadth explicitly; don’t assume feature parity without counting
@ap/audio import in Node.js tests requires aliasingAudioService singleton needs window — use @ap/audio-presets alias to SoundGenerator.ts for test compatibilityTest infra pattern for any web-audio module

Technical Debt

ItemPriorityNotes
stock-art-collector cross-language dependencyHighAssetManager requires Python REST API on port 3070 — build asset features last; graceful degradation when service unavailable
MadLibs content regressionMedium3 templates vs 20+ in iOS source — target 10+ templates to match original content depth
Ghost Writer features not portedMediumDexie persistence, TemplateGenerator, IdeaEvolver not ported — re-evaluate after core UI is built
Hash dedup is simplisticLowDJB2 string hash on URLs — adequate for MVP; replace with true perceptual hashing if quality issues arise

Tech Stack

LayerTechnologyVersion
RuntimeNode.js>=18.0.0
LanguageTypeScript^5.6.0
FrameworkReact^19.0.0
BuildVite^7.3.1
TestVitest^4.0.18

Internal Dependencies

PackagePurpose
@ap/narrative-engineInteractive story graph building and preview
@ap/audioSoundscape layer presets (SOUND_PRESETS)

Source Apps

AppContribution
gwIdea Catcher, Outline Builder, Template Generator, MadLibs, Idea Evolver
SoundBoardADSR synthesis presets for soundscapes
stock-art-collectorSourceAdapter circuit breaker + rate limiter patterns
MadLibsTemplate-based creative writing
Quest-ForgeInteractive narrative building
djgFeedback component patterns

Status Snapshot (2026-02-15)

  • CI/CD: N/A (not yet deployed)
  • Test coverage: 100% (36/36 tests passing)
  • Port: 3170 (registered in ops-core)
  • Next: Wire stock-art-collector REST API, add IndexedDB persistence, expand MadLibs templates