@idle-screens/schema 0.1.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/validate.ts","../src/simulate.ts","../src/compile.ts","../src/examples.ts"],"sourcesContent":["/**\n * Declarative, agent-authorable saver format. A `SaverSpec` describes a saver as DATA\n * (no code), which `compileSaver` turns into a seeded, deterministic, flash-safe\n * SaverPlugin. It models the \"drifting sprite field\" family that covers most classic\n * savers (fish, toasters, DVD, rain, messages): a static background plus one or more\n * layers of entities that move.\n *\n * SAFETY INVARIANT: there is deliberately NO full-field strobe/flash primitive — the\n * background is static and entities are bounded sprites — so a compiled spec cannot\n * produce photosensitive flashing by construction (proven by sampling a compiled spec\n * through @idle-screens/validator).\n */\nexport const SCHEMA_VERSION = 1 as const;\n\nexport interface SaverSpec {\n schemaVersion: 1;\n id: string;\n label: string;\n /** Deterministic seed; falls back to the host's SaverContext.seed. */\n seed?: number;\n background?: BackgroundSpec;\n layers: LayerSpec[];\n motionIntensity?: 'calm' | 'moderate' | 'energetic';\n}\n\nexport type BackgroundSpec =\n | { type: 'solid'; color: string }\n | { type: 'gradient'; stops: GradientStop[]; band?: BandSpec };\n\n/** A vertical gradient stop (`at` 0 = top, 1 = bottom). */\nexport interface GradientStop {\n at: number;\n color: string;\n}\n\n/** An optional solid band at the bottom (e.g. an aquarium seafloor). */\nexport interface BandSpec {\n color: string;\n /** Band height in px. */\n height: number;\n}\n\nexport interface LayerSpec {\n count: number;\n sprite: SpriteSpec;\n /** Sprite size range in px (font size for emoji/text; ignored for circle). */\n size?: [number, number];\n motion: MotionSpec;\n /** Wrap around the opposite edge when leaving the viewport. Default true. */\n wrap?: boolean;\n /** Flip the sprite horizontally to face its heading. Default false. */\n flip?: boolean;\n}\n\nexport type SpriteSpec =\n | { kind: 'emoji'; glyphs: string[] }\n | { kind: 'text'; strings: string[]; color?: string; font?: string }\n | { kind: 'circle'; radius: [number, number]; color: string };\n\nexport type MotionSpec =\n /**\n * Drift at a per-entity speed picked from `speed` (px/sec) along `angle` degrees\n * (0 = right, 90 = down; default 0). `bidirectional` randomly flips horizontal\n * direction per entity (e.g. fish swimming both ways); `bob` adds a small vertical\n * wobble amplitude (px). Covers horizontal fields, diagonals (toasters) and rain\n * (angle 90).\n */\n | { type: 'drift'; speed: [number, number]; angle?: number; bidirectional?: boolean; bob?: number }\n /** Rise upward (px/sec) with an optional horizontal sway amplitude (px) — bubbles. */\n | { type: 'rise'; speed: [number, number]; sway?: number }\n /** Bounce diagonally at a per-entity speed, reflecting off the edges (px/sec). */\n | { type: 'bounce'; speed: [number, number] };\n\n/** A validation problem, pointing at a JSON path within the spec. */\nexport interface SpecError {\n path: string;\n message: string;\n}\n\nexport interface ValidationResult {\n valid: boolean;\n errors: SpecError[];\n}\n\n/** Perf/safety caps enforced by `validateSpec`. */\nexport const LIMITS = {\n maxPerLayer: 400,\n maxTotal: 800,\n maxLayers: 8,\n maxSpeed: 4000, // px/sec — bounds motion so nothing teleports\n} as const;\n","import { LIMITS, SCHEMA_VERSION, type SaverSpec, type SpecError, type ValidationResult } from './types';\n\nconst HEX = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;\nconst isObj = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);\nconst isStr = (v: unknown): v is string => typeof v === 'string';\nconst isNum = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v);\nconst isRange = (v: unknown): v is [number, number] =>\n Array.isArray(v) && v.length === 2 && isNum(v[0]) && isNum(v[1]) && v[0] <= v[1];\n\n/**\n * Validate an untrusted (agent- or JSON-authored) spec structurally + semantically.\n * Returns typed errors; never throws. `compileSaver` refuses to run an invalid spec.\n */\nexport function validateSpec(spec: unknown): ValidationResult {\n const errors: SpecError[] = [];\n const err = (path: string, message: string): void => void errors.push({ path, message });\n\n if (!isObj(spec)) return { valid: false, errors: [{ path: '', message: 'spec must be an object' }] };\n\n if (spec.schemaVersion !== SCHEMA_VERSION) err('schemaVersion', `must be ${SCHEMA_VERSION}`);\n if (!isStr(spec.id) || spec.id.trim() === '') err('id', 'must be a non-empty string');\n if (!isStr(spec.label) || spec.label.trim() === '') err('label', 'must be a non-empty string');\n if (spec.seed !== undefined && !isNum(spec.seed)) err('seed', 'must be a number');\n if (spec.motionIntensity !== undefined && !['calm', 'moderate', 'energetic'].includes(spec.motionIntensity as string)) {\n err('motionIntensity', 'must be calm | moderate | energetic');\n }\n\n if (spec.background !== undefined) validateBackground(spec.background, err);\n\n if (!Array.isArray(spec.layers) || spec.layers.length === 0) {\n err('layers', 'must be a non-empty array');\n } else {\n if (spec.layers.length > LIMITS.maxLayers) err('layers', `at most ${LIMITS.maxLayers} layers`);\n let total = 0;\n spec.layers.forEach((layer, i) => {\n total += isObj(layer) && isNum(layer.count) ? layer.count : 0;\n validateLayer(layer, `layers[${i}]`, err);\n });\n if (total > LIMITS.maxTotal) err('layers', `total entities ${total} exceeds cap ${LIMITS.maxTotal}`);\n }\n\n return { valid: errors.length === 0, errors };\n}\n\nfunction color(v: unknown, path: string, err: (p: string, m: string) => void): void {\n if (!isStr(v) || !HEX.test(v)) err(path, 'must be a hex colour like #0a3a52');\n}\n\nfunction validateBackground(bg: unknown, err: (p: string, m: string) => void): void {\n if (!isObj(bg)) return err('background', 'must be an object');\n if (bg.type === 'solid') {\n color(bg.color, 'background.color', err);\n } else if (bg.type === 'gradient') {\n if (!Array.isArray(bg.stops) || bg.stops.length < 2) {\n err('background.stops', 'gradient needs at least 2 stops');\n } else {\n bg.stops.forEach((s, i) => {\n if (!isObj(s) || !isNum(s.at) || s.at < 0 || s.at > 1) err(`background.stops[${i}].at`, 'must be 0..1');\n color(isObj(s) ? s.color : undefined, `background.stops[${i}].color`, err);\n });\n }\n if (bg.band !== undefined) {\n if (!isObj(bg.band)) err('background.band', 'must be an object');\n else {\n color(bg.band.color, 'background.band.color', err);\n if (!isNum(bg.band.height) || bg.band.height <= 0) err('background.band.height', 'must be > 0');\n }\n }\n } else {\n err('background.type', 'must be solid | gradient');\n }\n}\n\nfunction validateLayer(layer: unknown, path: string, err: (p: string, m: string) => void): void {\n if (!isObj(layer)) return err(path, 'must be an object');\n if (!isNum(layer.count) || !Number.isInteger(layer.count) || layer.count < 1) {\n err(`${path}.count`, 'must be a positive integer');\n } else if (layer.count > LIMITS.maxPerLayer) {\n err(`${path}.count`, `at most ${LIMITS.maxPerLayer} per layer`);\n }\n if (layer.size !== undefined && (!isRange(layer.size) || layer.size[0] <= 0)) {\n err(`${path}.size`, 'must be a [min,max] range of positive px');\n }\n if (layer.wrap !== undefined && typeof layer.wrap !== 'boolean') err(`${path}.wrap`, 'must be a boolean');\n if (layer.flip !== undefined && typeof layer.flip !== 'boolean') err(`${path}.flip`, 'must be a boolean');\n\n validateSprite(layer.sprite, `${path}.sprite`, err);\n validateMotion(layer.motion, `${path}.motion`, err);\n}\n\nfunction validateSprite(sprite: unknown, path: string, err: (p: string, m: string) => void): void {\n if (!isObj(sprite)) return err(path, 'must be an object');\n if (sprite.kind === 'emoji') {\n if (!Array.isArray(sprite.glyphs) || sprite.glyphs.length === 0 || !sprite.glyphs.every(isStr)) {\n err(`${path}.glyphs`, 'must be a non-empty array of strings');\n }\n } else if (sprite.kind === 'text') {\n if (!Array.isArray(sprite.strings) || sprite.strings.length === 0 || !sprite.strings.every(isStr)) {\n err(`${path}.strings`, 'must be a non-empty array of strings');\n }\n if (sprite.color !== undefined) color(sprite.color, `${path}.color`, err);\n } else if (sprite.kind === 'circle') {\n if (!isRange(sprite.radius) || sprite.radius[0] <= 0) err(`${path}.radius`, 'must be a [min,max] range of positive px');\n color(sprite.color, `${path}.color`, err);\n } else {\n err(`${path}.kind`, 'must be emoji | text | circle');\n }\n}\n\nfunction validateMotion(motion: unknown, path: string, err: (p: string, m: string) => void): void {\n if (!isObj(motion)) return err(path, 'must be an object');\n const speedOk = (v: unknown, p: string): void => {\n if (!isRange(v)) err(p, 'must be a [min,max] range');\n else if (v[1] > LIMITS.maxSpeed) err(p, `speed exceeds cap ${LIMITS.maxSpeed} px/sec`);\n };\n if (motion.type === 'drift') {\n speedOk(motion.speed, `${path}.speed`);\n if (motion.angle !== undefined && !isNum(motion.angle)) err(`${path}.angle`, 'must be a number (degrees)');\n if (motion.bidirectional !== undefined && typeof motion.bidirectional !== 'boolean') err(`${path}.bidirectional`, 'must be a boolean');\n if (motion.bob !== undefined && !isNum(motion.bob)) err(`${path}.bob`, 'must be a number');\n } else if (motion.type === 'rise') {\n speedOk(motion.speed, `${path}.speed`);\n if (motion.sway !== undefined && !isNum(motion.sway)) err(`${path}.sway`, 'must be a number');\n } else if (motion.type === 'bounce') {\n speedOk(motion.speed, `${path}.speed`);\n } else {\n err(`${path}.type`, 'must be drift | rise | bounce');\n }\n}\n\n/** Narrowing helper: validate + cast. Throws with a joined message when invalid. */\nexport function assertValidSpec(spec: unknown): SaverSpec {\n const r = validateSpec(spec);\n if (!r.valid) {\n throw new Error(`invalid saver spec:\\n${r.errors.map((e) => ` ${e.path || '<root>'}: ${e.message}`).join('\\n')}`);\n }\n return spec as SaverSpec;\n}\n","import type { Rng } from '@idle-screens/core';\nimport type { LayerSpec, SpriteSpec } from './types';\n\n/** A seeded entity: initial state + resolved velocity. `positionAt` is a pure function\n * of this + time, so the rAF loop and renderFrame(t) produce identical results. */\nexport interface Entity {\n x0: number;\n y0: number;\n size: number;\n spriteIndex: number;\n phase: number;\n vx: number; // px/sec\n vy: number; // px/sec\n bob: number; // vertical bob / horizontal sway amplitude (px)\n motion: 'drift' | 'rise' | 'bounce';\n headingLeft: boolean;\n}\n\nexport interface Placed {\n x: number;\n y: number;\n flip: boolean;\n}\n\nexport function spriteVariants(sprite: SpriteSpec): number {\n if (sprite.kind === 'emoji') return sprite.glyphs.length;\n if (sprite.kind === 'text') return sprite.strings.length;\n return 1;\n}\n\n/** Deterministically place a layer's entities using the seeded RNG (never Math.random). */\nexport function buildEntities(layer: LayerSpec, rng: Rng, w: number, h: number): Entity[] {\n const [smin, smax] = layer.size ?? [20, 40];\n const variants = spriteVariants(layer.sprite);\n const out: Entity[] = [];\n for (let i = 0; i < layer.count; i++) {\n const size =\n layer.sprite.kind === 'circle'\n ? rng.range(layer.sprite.radius[0], layer.sprite.radius[1]) * 2\n : rng.range(smin, smax);\n\n let vx = 0;\n let vy = 0;\n let bob = 0;\n let motion: Entity['motion'] = 'drift';\n const m = layer.motion;\n if (m.type === 'drift') {\n const s = rng.range(m.speed[0], m.speed[1]);\n let angle = ((m.angle ?? 0) * Math.PI) / 180;\n if (m.bidirectional && rng.next() < 0.5) angle = Math.PI - angle;\n vx = s * Math.cos(angle);\n vy = s * Math.sin(angle);\n bob = m.bob ?? 0;\n } else if (m.type === 'rise') {\n motion = 'rise';\n vy = -rng.range(m.speed[0], m.speed[1]); // upward\n bob = m.sway ?? 0;\n } else {\n motion = 'bounce';\n const s = rng.range(m.speed[0], m.speed[1]);\n const a = rng.range(0, Math.PI * 2);\n vx = s * Math.cos(a);\n vy = s * Math.sin(a);\n }\n\n out.push({\n x0: rng.range(0, w),\n y0: rng.range(0, h),\n size,\n spriteIndex: variants > 1 ? rng.int(0, variants - 1) : 0,\n phase: rng.range(0, Math.PI * 2),\n vx,\n vy,\n bob,\n motion,\n headingLeft: vx < 0,\n });\n }\n return out;\n}\n\nfunction wrap(v: number, min: number, max: number): number {\n const range = max - min;\n return ((((v - min) % range) + range) % range) + min;\n}\n\nfunction reflect(v: number, min: number, max: number): number {\n const range = max - min;\n if (range <= 0) return min;\n const period = 2 * range;\n const p = (((v - min) % period) + period) % period;\n return min + (p < range ? p : period - p);\n}\n\n/** Analytic position of an entity at logical time `t` (ms). Pure & deterministic. */\nexport function positionAt(e: Entity, t: number, w: number, h: number): Placed {\n const dt = t / 1000;\n const m = e.size;\n if (e.motion === 'bounce') {\n return {\n x: reflect(e.x0 + e.vx * dt, m / 2, w - m / 2),\n y: reflect(e.y0 + e.vy * dt, m / 2, h - m / 2),\n flip: false,\n };\n }\n if (e.motion === 'rise') {\n return {\n x: e.x0 + (e.bob ? e.bob * Math.sin(t / 700 + e.phase) : 0),\n y: wrap(e.y0 + e.vy * dt, -m, h + m),\n flip: false,\n };\n }\n // drift\n const x = wrap(e.x0 + e.vx * dt, -m, w + m);\n let y = e.vy !== 0 ? wrap(e.y0 + e.vy * dt, -m, h + m) : e.y0;\n if (e.bob) y += e.bob * Math.sin(t / 500 + e.phase);\n return { x, y, flip: e.headingLeft };\n}\n","import {\n createRng,\n type SaverContext,\n type SaverInstance,\n type SaverManifest,\n type SaverPlugin,\n} from '@idle-screens/core';\nimport { assertValidSpec } from './validate';\nimport { buildEntities, positionAt, type Entity } from './simulate';\nimport type { LayerSpec, SaverSpec } from './types';\n\n/** Derive a manifest so a compiled spec composes with @idle-screens/capabilities. */\nexport function manifestFor(spec: SaverSpec): SaverManifest {\n const total = spec.layers.reduce((n, l) => n + l.count, 0);\n const costTier = total < 30 ? 'idle' : total < 150 ? 'low' : total < 400 ? 'medium' : 'high';\n return {\n id: spec.id,\n label: spec.label,\n passthrough: false,\n minBackend: 'canvas2d',\n costTier,\n motionIntensity: spec.motionIntensity ?? 'moderate',\n reducedMotionFallback: 'static',\n // Flash-safe by construction: static background + bounded sprites, no strobe\n // primitive. Proven by sampling a compiled spec through @idle-screens/validator.\n a11y: { flashSafe: true },\n };\n}\n\ninterface Built {\n layer: LayerSpec;\n entities: Entity[];\n}\n\nclass SpecInstance implements SaverInstance {\n private readonly canvas: HTMLCanvasElement;\n private readonly ctx: CanvasRenderingContext2D;\n private readonly seed: number;\n private w: number;\n private h: number;\n private layers: Built[] = [];\n private frameId: number | null = null;\n private paused = false;\n private startT = 0;\n\n constructor(\n private readonly spec: SaverSpec,\n ctx: SaverContext,\n ) {\n this.seed = ((spec.seed ?? ctx.seed) >>> 0) || 1;\n const canvas = document.createElement('canvas');\n canvas.style.cssText = 'display:block;width:100%;height:100%';\n canvas.setAttribute('aria-hidden', 'true');\n ctx.host.appendChild(canvas);\n this.canvas = canvas;\n const c2d = canvas.getContext('2d', { alpha: false });\n if (!c2d) throw new Error('schema saver: no 2d context');\n this.ctx = c2d;\n\n this.w = ctx.width;\n this.h = ctx.height;\n this.sizeCanvas();\n this.rebuild();\n\n this.paused = ctx.reducedMotion;\n if (this.paused) this.renderFrame(0, this.seed);\n else this.start();\n }\n\n private sizeCanvas(): void {\n const dpr = Math.min(typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1, 2);\n this.canvas.width = Math.max(1, Math.round(this.w * dpr));\n this.canvas.height = Math.max(1, Math.round(this.h * dpr));\n this.ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n }\n\n /** (Re)seed and place all entities — deterministic for the seed + size. */\n private rebuild(): void {\n const rng = createRng(this.seed);\n this.layers = this.spec.layers.map((layer) => ({ layer, entities: buildEntities(layer, rng, this.w, this.h) }));\n }\n\n private start(): void {\n if (this.frameId !== null || typeof requestAnimationFrame === 'undefined') return;\n this.startT = 0;\n this.frameId = requestAnimationFrame((now) => this.loop(now));\n }\n\n private stop(): void {\n if (this.frameId !== null) {\n cancelAnimationFrame(this.frameId);\n this.frameId = null;\n }\n }\n\n private loop(now: number): void {\n this.frameId = requestAnimationFrame((n) => this.loop(n));\n if (this.startT === 0) this.startT = now;\n this.renderFrame(now - this.startT, this.seed);\n }\n\n private drawBackground(): void {\n const { ctx, w, h } = this;\n const bg = this.spec.background;\n if (!bg || bg.type === 'solid') {\n ctx.fillStyle = bg?.color ?? '#05050a';\n ctx.fillRect(0, 0, w, h);\n return;\n }\n const g = ctx.createLinearGradient(0, 0, 0, h);\n for (const s of bg.stops) g.addColorStop(Math.max(0, Math.min(1, s.at)), s.color);\n ctx.fillStyle = g;\n ctx.fillRect(0, 0, w, h);\n if (bg.band) {\n ctx.fillStyle = bg.band.color;\n ctx.fillRect(0, h - bg.band.height, w, bg.band.height);\n }\n }\n\n private drawEntity(built: Built, e: Entity, t: number): void {\n const { ctx } = this;\n const p = positionAt(e, t, this.w, this.h);\n const sprite = built.layer.sprite;\n if (sprite.kind === 'circle') {\n ctx.fillStyle = sprite.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, e.size / 2, 0, Math.PI * 2);\n ctx.fill();\n return;\n }\n ctx.save();\n ctx.translate(p.x, p.y);\n if (p.flip && built.layer.flip) ctx.scale(-1, 1);\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n if (sprite.kind === 'emoji') {\n ctx.font = `${e.size}px serif`;\n ctx.fillText(sprite.glyphs[e.spriteIndex] ?? sprite.glyphs[0]!, 0, 0);\n } else {\n ctx.font = sprite.font ?? `${e.size}px system-ui, sans-serif`;\n ctx.fillStyle = sprite.color ?? '#e6e8ef';\n ctx.fillText(sprite.strings[e.spriteIndex] ?? sprite.strings[0]!, 0, 0);\n }\n ctx.restore();\n }\n\n /** Deterministic, frame-addressable render (shared by the rAF loop). */\n renderFrame(t: number, _seed: number): void {\n this.drawBackground();\n for (const built of this.layers) {\n for (const e of built.entities) this.drawEntity(built, e, t);\n }\n }\n\n setPaused(paused: boolean): void {\n this.paused = paused;\n if (paused) {\n this.stop();\n } else {\n this.start();\n }\n }\n\n resize(width: number, height: number): void {\n this.w = width;\n this.h = height;\n this.sizeCanvas();\n this.rebuild();\n if (this.paused) this.renderFrame(0, this.seed);\n }\n\n dispose(): void {\n this.stop();\n this.canvas.remove();\n }\n}\n\n/**\n * Compile a declarative spec into a runnable SaverPlugin. Throws if the spec is invalid\n * (so an agent-authored spec is validated before it can run). The result is seeded,\n * deterministic, `renderFrame(t,seed)`-addressable, and flash-safe by construction.\n */\nexport function compileSaver(spec: unknown): SaverPlugin {\n const valid = assertValidSpec(spec);\n return {\n manifest: manifestFor(valid),\n mount: (ctx: SaverContext) => new SpecInstance(valid, ctx),\n };\n}\n","import type { SaverSpec } from './types';\n\n/**\n * Reproduces the hand-coded Fish Aquarium saver as pure DATA — the discriminating test\n * that the schema is actually expressive: two layers (fish drifting both ways at varied\n * speeds with a bob + flip, over a gradient with a seafloor band; bubbles rising with sway).\n */\nexport const AQUARIUM_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'aquarium',\n label: 'Aquarium (declarative)',\n seed: 42,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#0a3a52' },\n { at: 0.6, color: '#062534' },\n { at: 1, color: '#02141d' },\n ],\n band: { color: '#0b1a12', height: 24 },\n },\n layers: [\n {\n count: 14,\n sprite: { kind: 'emoji', glyphs: ['🐟', '🐠', '🐡', '🦈', '🐙'] },\n size: [34, 72],\n motion: { type: 'drift', speed: [30, 110], bidirectional: true, bob: 6 },\n flip: true,\n },\n {\n count: 22,\n sprite: { kind: 'circle', radius: [2, 7], color: '#c8ebff' },\n motion: { type: 'rise', speed: [24, 78], sway: 8 },\n },\n ],\n};\n\n/** Rain: dense text streaks falling straight down over a near-black sky. */\nexport const RAIN_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'rain',\n label: 'Rain (declarative)',\n seed: 7,\n motionIntensity: 'moderate',\n background: { type: 'solid', color: '#05070a' },\n layers: [\n {\n count: 140,\n sprite: { kind: 'text', strings: ['│'], color: '#9fd0ff' },\n size: [12, 26],\n motion: { type: 'drift', angle: 90, speed: [520, 900] },\n },\n ],\n};\n\nexport const EXAMPLE_SPECS: SaverSpec[] = [AQUARIUM_SPEC, RAIN_SPEC];\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/types.ts","../src/validate.ts","../src/simulate.ts","../src/compile.ts","../src/examples.ts"],"sourcesContent":["/**\n * Declarative, agent-authorable saver format. A `SaverSpec` describes a saver as DATA\n * (no code), which `compileSaver` turns into a seeded, deterministic, flash-safe\n * SaverPlugin. It models the \"drifting sprite field\" family that covers most classic\n * savers (fish, toasters, DVD, rain, messages): a static background plus one or more\n * layers of entities that move.\n *\n * SAFETY INVARIANT: there is deliberately NO full-field strobe/flash primitive — the\n * background is static and entities are bounded sprites — so a compiled spec cannot\n * produce photosensitive flashing by construction (proven by sampling a compiled spec\n * through @idle-screens/validator).\n */\nexport const SCHEMA_VERSION = 1 as const;\n\nexport interface SaverSpec {\n schemaVersion: 1;\n id: string;\n label: string;\n /** Deterministic seed; falls back to the host's SaverContext.seed. */\n seed?: number;\n background?: BackgroundSpec;\n layers: LayerSpec[];\n motionIntensity?: 'calm' | 'moderate' | 'energetic';\n}\n\nexport type BackgroundSpec =\n | { type: 'solid'; color: string }\n | { type: 'gradient'; stops: GradientStop[]; band?: BandSpec };\n\n/** A vertical gradient stop (`at` 0 = top, 1 = bottom). */\nexport interface GradientStop {\n at: number;\n color: string;\n}\n\n/** An optional solid band at the bottom (e.g. an aquarium seafloor). */\nexport interface BandSpec {\n color: string;\n /** Band height in px. */\n height: number;\n}\n\nexport interface LayerSpec {\n count: number;\n sprite: SpriteSpec;\n /** Sprite size range in px (font size for emoji/text; ignored for circle). */\n size?: [number, number];\n motion: MotionSpec;\n /** Wrap around the opposite edge when leaving the viewport. Default true. */\n wrap?: boolean;\n /** Flip the sprite horizontally to face its heading. Default false. */\n flip?: boolean;\n /** Per-entity opacity range, both 0..1. Default [1,1]. */\n alpha?: [number, number];\n /** Compositing for this layer. 'lighter' = additive (glow stacking). Default source-over. */\n blend?: 'lighter';\n /**\n * Fractional spawn window (0 = left/top, 1 = right/bottom). Constrains where\n * entities are PLACED, not where they may travel. Default full viewport.\n */\n region?: { x?: [number, number]; y?: [number, number] };\n /**\n * Sinusoidal opacity breathing. SAFETY: amp is capped (LIMITS.maxPulseAmp),\n * period has a floor (LIMITS.minPulsePeriod — max 2 Hz), and every entity gets\n * its own seeded phase, so a layer can never strobe in unison. Effective alpha\n * is clamped to 0..1.\n */\n pulse?: { amp: number; period: number };\n /**\n * Addressable name for this layer. Enables `setParam` to use `key.field` paths\n * instead of `layers.N.field` indices. Also makes specs self-documenting.\n */\n key?: string;\n /**\n * Exact fractional position {x, y} for a single entity (0 = left/top, 1 = right/bottom).\n * Only valid when `count` is 1. Overrides `region` scatter placement.\n */\n position?: { x: number; y: number };\n}\n\nexport type SpriteSpec =\n | { kind: 'emoji'; glyphs: string[] }\n | {\n kind: 'text';\n strings: string[];\n color?: string;\n font?: string;\n align?: 'left' | 'center' | 'right';\n baseline?: 'top' | 'middle' | 'bottom';\n maxWidth?: number;\n }\n /** `soft` renders a radial falloff (glow orb) instead of a hard disc. */\n | { kind: 'circle'; radius: [number, number]; color: string; soft?: boolean };\n\nexport type MotionSpec =\n /**\n * Drift at a per-entity speed picked from `speed` (px/sec) along `angle` degrees\n * (0 = right, 90 = down; default 0). `bidirectional` randomly flips horizontal\n * direction per entity (e.g. fish swimming both ways); `bob` adds a small vertical\n * wobble amplitude (px). Covers horizontal fields, diagonals (toasters) and rain\n * (angle 90).\n */\n | { type: 'drift'; speed: [number, number]; angle?: number; bidirectional?: boolean; bob?: number }\n /** Rise upward (px/sec) with an optional horizontal sway amplitude (px) — bubbles. */\n | { type: 'rise'; speed: [number, number]; sway?: number }\n /** Bounce diagonally at a per-entity speed, reflecting off the edges (px/sec). */\n | { type: 'bounce'; speed: [number, number] }\n /** Entity stays exactly where placed. No movement. Use with `position` for pinned elements. */\n | { type: 'static' };\n\n/** A validation problem, pointing at a JSON path within the spec. */\nexport interface SpecError {\n path: string;\n message: string;\n}\n\nexport interface ValidationResult {\n valid: boolean;\n errors: SpecError[];\n}\n\n/** Perf/safety caps enforced by `validateSpec`. */\nexport const LIMITS = {\n maxPerLayer: 400,\n maxTotal: 800,\n maxLayers: 36,\n maxSpeed: 4000, // px/sec — bounds motion so nothing teleports\n maxPulseAmp: 0.5, // opacity breathing amplitude cap\n minPulsePeriod: 500, // ms — caps pulse at 2 Hz (WCAG flash threshold is 3 Hz)\n} as const;\n","import { LIMITS, SCHEMA_VERSION, type SaverSpec, type SpecError, type ValidationResult } from './types';\n\nconst HEX = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;\nconst isObj = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);\nconst isStr = (v: unknown): v is string => typeof v === 'string';\nconst isNum = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v);\nconst isRange = (v: unknown): v is [number, number] =>\n Array.isArray(v) && v.length === 2 && isNum(v[0]) && isNum(v[1]) && v[0] <= v[1];\n\n/**\n * Validate an untrusted (agent- or JSON-authored) spec structurally + semantically.\n * Returns typed errors; never throws. `compileSaver` refuses to run an invalid spec.\n */\nexport function validateSpec(spec: unknown): ValidationResult {\n const errors: SpecError[] = [];\n const err = (path: string, message: string): void => void errors.push({ path, message });\n\n if (!isObj(spec)) return { valid: false, errors: [{ path: '', message: 'spec must be an object' }] };\n\n if (spec.schemaVersion !== SCHEMA_VERSION) err('schemaVersion', `must be ${SCHEMA_VERSION}`);\n if (!isStr(spec.id) || spec.id.trim() === '') err('id', 'must be a non-empty string');\n if (!isStr(spec.label) || spec.label.trim() === '') err('label', 'must be a non-empty string');\n if (spec.seed !== undefined && !isNum(spec.seed)) err('seed', 'must be a number');\n if (spec.motionIntensity !== undefined && !['calm', 'moderate', 'energetic'].includes(spec.motionIntensity as string)) {\n err('motionIntensity', 'must be calm | moderate | energetic');\n }\n\n if (spec.background !== undefined) validateBackground(spec.background, err);\n\n if (!Array.isArray(spec.layers) || spec.layers.length === 0) {\n err('layers', 'must be a non-empty array');\n } else {\n if (spec.layers.length > LIMITS.maxLayers) err('layers', `at most ${LIMITS.maxLayers} layers`);\n let total = 0;\n spec.layers.forEach((layer, i) => {\n total += isObj(layer) && isNum(layer.count) ? layer.count : 0;\n validateLayer(layer, `layers[${i}]`, err);\n });\n if (total > LIMITS.maxTotal) err('layers', `total entities ${total} exceeds cap ${LIMITS.maxTotal}`);\n }\n\n return { valid: errors.length === 0, errors };\n}\n\nfunction color(v: unknown, path: string, err: (p: string, m: string) => void): void {\n if (!isStr(v) || !HEX.test(v)) err(path, 'must be a hex colour like #0a3a52');\n}\n\nfunction validateBackground(bg: unknown, err: (p: string, m: string) => void): void {\n if (!isObj(bg)) return err('background', 'must be an object');\n if (bg.type === 'solid') {\n color(bg.color, 'background.color', err);\n } else if (bg.type === 'gradient') {\n if (!Array.isArray(bg.stops) || bg.stops.length < 2) {\n err('background.stops', 'gradient needs at least 2 stops');\n } else {\n bg.stops.forEach((s, i) => {\n if (!isObj(s) || !isNum(s.at) || s.at < 0 || s.at > 1) err(`background.stops[${i}].at`, 'must be 0..1');\n color(isObj(s) ? s.color : undefined, `background.stops[${i}].color`, err);\n });\n }\n if (bg.band !== undefined) {\n if (!isObj(bg.band)) err('background.band', 'must be an object');\n else {\n color(bg.band.color, 'background.band.color', err);\n if (!isNum(bg.band.height) || bg.band.height <= 0) err('background.band.height', 'must be > 0');\n }\n }\n } else {\n err('background.type', 'must be solid | gradient');\n }\n}\n\nfunction validateLayer(layer: unknown, path: string, err: (p: string, m: string) => void): void {\n if (!isObj(layer)) return err(path, 'must be an object');\n if (!isNum(layer.count) || !Number.isInteger(layer.count) || layer.count < 1) {\n err(`${path}.count`, 'must be a positive integer');\n } else if (layer.count > LIMITS.maxPerLayer) {\n err(`${path}.count`, `at most ${LIMITS.maxPerLayer} per layer`);\n }\n if (layer.size !== undefined && (!isRange(layer.size) || layer.size[0] <= 0)) {\n err(`${path}.size`, 'must be a [min,max] range of positive px');\n }\n if (layer.wrap !== undefined && typeof layer.wrap !== 'boolean') err(`${path}.wrap`, 'must be a boolean');\n if (layer.flip !== undefined && typeof layer.flip !== 'boolean') err(`${path}.flip`, 'must be a boolean');\n\n if (layer.alpha !== undefined && (!isRange(layer.alpha) || layer.alpha[0] < 0 || layer.alpha[1] > 1)) {\n err(`${path}.alpha`, 'must be a [min,max] range within 0..1');\n }\n if (layer.blend !== undefined && layer.blend !== 'lighter') err(`${path}.blend`, \"must be 'lighter' when set\");\n if (layer.key !== undefined && (!isStr(layer.key) || layer.key.trim() === '')) {\n err(`${path}.key`, 'must be a non-empty string');\n }\n if (layer.position !== undefined) {\n if (!isObj(layer.position) || !isNum(layer.position.x) || !isNum(layer.position.y)) {\n err(`${path}.position`, 'must be {x, y} with numbers 0..1');\n } else {\n if (layer.position.x < 0 || layer.position.x > 1) err(`${path}.position.x`, 'must be 0..1');\n if (layer.position.y < 0 || layer.position.y > 1) err(`${path}.position.y`, 'must be 0..1');\n if (isNum(layer.count) && layer.count !== 1) err(`${path}.position`, 'position requires count: 1');\n }\n }\n if (layer.region !== undefined) {\n if (!isObj(layer.region)) err(`${path}.region`, 'must be an object');\n else {\n for (const axis of ['x', 'y'] as const) {\n const r = layer.region[axis];\n if (r !== undefined && (!isRange(r) || r[0] < 0 || r[1] > 1)) {\n err(`${path}.region.${axis}`, 'must be a [min,max] range within 0..1');\n }\n }\n }\n }\n if (layer.pulse !== undefined) {\n if (!isObj(layer.pulse)) err(`${path}.pulse`, 'must be an object');\n else {\n if (!isNum(layer.pulse.amp) || layer.pulse.amp <= 0 || layer.pulse.amp > LIMITS.maxPulseAmp) {\n err(`${path}.pulse.amp`, `must be within 0..${LIMITS.maxPulseAmp}`);\n }\n if (!isNum(layer.pulse.period) || layer.pulse.period < LIMITS.minPulsePeriod) {\n err(`${path}.pulse.period`, `must be >= ${LIMITS.minPulsePeriod} ms (flash-safety floor)`);\n }\n }\n }\n\n validateSprite(layer.sprite, `${path}.sprite`, err);\n validateMotion(layer.motion, `${path}.motion`, err);\n}\n\nfunction validateSprite(sprite: unknown, path: string, err: (p: string, m: string) => void): void {\n if (!isObj(sprite)) return err(path, 'must be an object');\n if (sprite.kind === 'emoji') {\n if (!Array.isArray(sprite.glyphs) || sprite.glyphs.length === 0 || !sprite.glyphs.every(isStr)) {\n err(`${path}.glyphs`, 'must be a non-empty array of strings');\n }\n } else if (sprite.kind === 'text') {\n if (!Array.isArray(sprite.strings) || sprite.strings.length === 0 || !sprite.strings.every(isStr)) {\n err(`${path}.strings`, 'must be a non-empty array of strings');\n }\n if (sprite.color !== undefined) color(sprite.color, `${path}.color`, err);\n if (sprite.align !== undefined && !['left', 'center', 'right'].includes(sprite.align as string)) {\n err(`${path}.align`, 'must be left | center | right');\n }\n if (sprite.baseline !== undefined && !['top', 'middle', 'bottom'].includes(sprite.baseline as string)) {\n err(`${path}.baseline`, 'must be top | middle | bottom');\n }\n if (sprite.maxWidth !== undefined && (!isNum(sprite.maxWidth) || sprite.maxWidth <= 0)) {\n err(`${path}.maxWidth`, 'must be a positive number');\n }\n } else if (sprite.kind === 'circle') {\n if (!isRange(sprite.radius) || sprite.radius[0] <= 0) err(`${path}.radius`, 'must be a [min,max] range of positive px');\n color(sprite.color, `${path}.color`, err);\n if (sprite.soft !== undefined && typeof sprite.soft !== 'boolean') err(`${path}.soft`, 'must be a boolean');\n } else {\n err(`${path}.kind`, 'must be emoji | text | circle');\n }\n}\n\nfunction validateMotion(motion: unknown, path: string, err: (p: string, m: string) => void): void {\n if (!isObj(motion)) return err(path, 'must be an object');\n const speedOk = (v: unknown, p: string): void => {\n if (!isRange(v)) err(p, 'must be a [min,max] range');\n else if (v[1] > LIMITS.maxSpeed) err(p, `speed exceeds cap ${LIMITS.maxSpeed} px/sec`);\n };\n if (motion.type === 'drift') {\n speedOk(motion.speed, `${path}.speed`);\n if (motion.angle !== undefined && !isNum(motion.angle)) err(`${path}.angle`, 'must be a number (degrees)');\n if (motion.bidirectional !== undefined && typeof motion.bidirectional !== 'boolean') err(`${path}.bidirectional`, 'must be a boolean');\n if (motion.bob !== undefined && !isNum(motion.bob)) err(`${path}.bob`, 'must be a number');\n } else if (motion.type === 'rise') {\n speedOk(motion.speed, `${path}.speed`);\n if (motion.sway !== undefined && !isNum(motion.sway)) err(`${path}.sway`, 'must be a number');\n } else if (motion.type === 'bounce') {\n speedOk(motion.speed, `${path}.speed`);\n } else if (motion.type === 'static') {\n // No fields to validate — static motion has no parameters.\n } else {\n err(`${path}.type`, 'must be drift | rise | bounce | static');\n }\n}\n\n/** Narrowing helper: validate + cast. Throws with a joined message when invalid. */\nexport function assertValidSpec(spec: unknown): SaverSpec {\n const r = validateSpec(spec);\n if (!r.valid) {\n throw new Error(`invalid saver spec:\\n${r.errors.map((e) => ` ${e.path || '<root>'}: ${e.message}`).join('\\n')}`);\n }\n return spec as SaverSpec;\n}\n","import type { Rng } from '@idle-screens/core';\nimport type { LayerSpec, SpriteSpec } from './types';\n\n/** A seeded entity: initial state + resolved velocity. `positionAt` is a pure function\n * of this + time, so the rAF loop and renderFrame(t) produce identical results. */\nexport interface Entity {\n x0: number;\n y0: number;\n size: number;\n spriteIndex: number;\n phase: number;\n vx: number; // px/sec\n vy: number; // px/sec\n bob: number; // vertical bob / horizontal sway amplitude (px)\n motion: 'drift' | 'rise' | 'bounce' | 'static';\n headingLeft: boolean;\n alpha: number; // resolved base opacity (default 1)\n pulseAmp: number; // opacity breathing amplitude (0 = none)\n pulsePeriod: number; // ms\n pulsePhase: number;\n}\n\nexport interface Placed {\n x: number;\n y: number;\n flip: boolean;\n}\n\nexport function spriteVariants(sprite: SpriteSpec): number {\n if (sprite.kind === 'emoji') return sprite.glyphs.length;\n if (sprite.kind === 'text') return sprite.strings.length;\n return 1;\n}\n\n/** Deterministically place a layer's entities using the seeded RNG (never Math.random). */\nexport function buildEntities(layer: LayerSpec, rng: Rng, w: number, h: number): Entity[] {\n const [smin, smax] = layer.size ?? [20, 40];\n const variants = spriteVariants(layer.sprite);\n const out: Entity[] = [];\n for (let i = 0; i < layer.count; i++) {\n const size =\n layer.sprite.kind === 'circle'\n ? rng.range(layer.sprite.radius[0], layer.sprite.radius[1]) * 2\n : rng.range(smin, smax);\n\n let vx = 0;\n let vy = 0;\n let bob = 0;\n let motion: Entity['motion'] = 'drift';\n const m = layer.motion;\n if (m.type === 'static') {\n motion = 'static';\n } else if (m.type === 'drift') {\n const s = rng.range(m.speed[0], m.speed[1]);\n let angle = ((m.angle ?? 0) * Math.PI) / 180;\n if (m.bidirectional && rng.next() < 0.5) angle = Math.PI - angle;\n vx = s * Math.cos(angle);\n vy = s * Math.sin(angle);\n bob = m.bob ?? 0;\n } else if (m.type === 'rise') {\n motion = 'rise';\n vy = -rng.range(m.speed[0], m.speed[1]); // upward\n bob = m.sway ?? 0;\n } else {\n motion = 'bounce';\n const s = rng.range(m.speed[0], m.speed[1]);\n const a = rng.range(0, Math.PI * 2);\n vx = s * Math.cos(a);\n vy = s * Math.sin(a);\n }\n\n let x0: number;\n let y0: number;\n if (layer.position && layer.count === 1) {\n x0 = layer.position.x * w;\n y0 = layer.position.y * h;\n } else {\n // Spawn window defaults to the full viewport. IMPORTANT (determinism/compat):\n // optional features must only consume EXTRA rng draws when declared, so specs\n // written before a feature existed keep bit-identical entity streams.\n const [rx0, rx1] = layer.region?.x ?? [0, 1];\n const [ry0, ry1] = layer.region?.y ?? [0, 1];\n x0 = rng.range(rx0 * w, rx1 * w);\n y0 = rng.range(ry0 * h, ry1 * h);\n }\n\n out.push({\n x0,\n y0,\n size,\n spriteIndex: variants > 1 ? rng.int(0, variants - 1) : 0,\n phase: rng.range(0, Math.PI * 2),\n vx,\n vy,\n bob,\n motion,\n headingLeft: vx < 0,\n alpha: layer.alpha ? rng.range(layer.alpha[0], layer.alpha[1]) : 1,\n pulseAmp: layer.pulse?.amp ?? 0,\n pulsePeriod: layer.pulse?.period ?? 1000,\n pulsePhase: layer.pulse ? rng.range(0, Math.PI * 2) : 0,\n });\n }\n return out;\n}\n\n/** Analytic opacity of an entity at logical time `t` (ms). Pure, clamped to 0..1. */\nexport function alphaAt(e: Entity, t: number): number {\n if (!e.pulseAmp) return e.alpha;\n const a = e.alpha + e.pulseAmp * Math.sin((t * 2 * Math.PI) / e.pulsePeriod + e.pulsePhase);\n return a < 0 ? 0 : a > 1 ? 1 : a;\n}\n\nfunction wrap(v: number, min: number, max: number): number {\n const range = max - min;\n return ((((v - min) % range) + range) % range) + min;\n}\n\nfunction reflect(v: number, min: number, max: number): number {\n const range = max - min;\n if (range <= 0) return min;\n const period = 2 * range;\n const p = (((v - min) % period) + period) % period;\n return min + (p < range ? p : period - p);\n}\n\n/** Analytic position of an entity at logical time `t` (ms). Pure & deterministic. */\nexport function positionAt(e: Entity, t: number, w: number, h: number): Placed {\n if (e.motion === 'static') return { x: e.x0, y: e.y0, flip: false };\n const dt = t / 1000;\n const m = e.size;\n if (e.motion === 'bounce') {\n return {\n x: reflect(e.x0 + e.vx * dt, m / 2, w - m / 2),\n y: reflect(e.y0 + e.vy * dt, m / 2, h - m / 2),\n flip: false,\n };\n }\n if (e.motion === 'rise') {\n return {\n x: e.x0 + (e.bob ? e.bob * Math.sin(t / 700 + e.phase) : 0),\n y: wrap(e.y0 + e.vy * dt, -m, h + m),\n flip: false,\n };\n }\n // drift\n const x = wrap(e.x0 + e.vx * dt, -m, w + m);\n let y = e.vy !== 0 ? wrap(e.y0 + e.vy * dt, -m, h + m) : e.y0;\n if (e.bob) y += e.bob * Math.sin(t / 500 + e.phase);\n return { x, y, flip: e.headingLeft };\n}\n","import {\n createRng,\n type SaverContext,\n type SaverInstance,\n type SaverManifest,\n type SaverPlugin,\n} from '@idle-screens/core';\nimport { assertValidSpec } from './validate';\nimport { alphaAt, buildEntities, positionAt, type Entity } from './simulate';\nimport type { LayerSpec, SaverSpec } from './types';\n\n/** Expand #rgb/#rrggbb to an rgba() string — needed for gradient stops with alpha. */\nfunction hexToRgba(hex: string, alpha: number): string {\n const h = hex.length === 4 ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}` : hex;\n const n = parseInt(h.slice(1), 16);\n return `rgba(${(n >> 16) & 255},${(n >> 8) & 255},${n & 255},${alpha})`;\n}\n\n/** Derive a manifest so a compiled spec composes with @idle-screens/capabilities. */\nexport function manifestFor(spec: SaverSpec): SaverManifest {\n const total = spec.layers.reduce((n, l) => n + l.count, 0);\n const costTier = total < 30 ? 'idle' : total < 150 ? 'low' : total < 400 ? 'medium' : 'high';\n return {\n id: spec.id,\n label: spec.label,\n passthrough: false,\n minBackend: 'canvas2d',\n costTier,\n motionIntensity: spec.motionIntensity ?? 'moderate',\n reducedMotionFallback: 'static',\n // Flash-safe by construction: static background + bounded sprites, no strobe\n // primitive. Proven by sampling a compiled spec through @idle-screens/validator.\n a11y: { flashSafe: true },\n };\n}\n\ninterface Built {\n layer: LayerSpec;\n entities: Entity[];\n}\n\nclass SpecInstance implements SaverInstance {\n private readonly canvas: HTMLCanvasElement | OffscreenCanvas;\n private readonly ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;\n private readonly saverCtx: SaverContext;\n private readonly seed: number;\n private w: number;\n private h: number;\n private layers: Built[] = [];\n private frameId: number | null = null;\n private paused = false;\n private startT = 0;\n private baseT = 0; // elapsed logical time carried across pause/resume\n private lastT = 0;\n\n constructor(\n private readonly spec: SaverSpec,\n ctx: SaverContext,\n ) {\n this.saverCtx = ctx;\n this.seed = ((spec.seed ?? ctx.seed) >>> 0) || 1;\n let canvas: HTMLCanvasElement | OffscreenCanvas;\n if (ctx.surface) {\n canvas = ctx.surface;\n } else {\n const el = document.createElement('canvas');\n el.style.cssText = 'display:block;width:100%;height:100%';\n el.setAttribute('aria-hidden', 'true');\n ctx.host.appendChild(el);\n canvas = el;\n }\n this.canvas = canvas;\n const c2d = canvas.getContext('2d', { alpha: false }) as CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D | null;\n if (!c2d) throw new Error('schema saver: no 2d context');\n this.ctx = c2d;\n\n this.w = ctx.width;\n this.h = ctx.height;\n this.sizeCanvas();\n this.rebuild();\n\n this.paused = ctx.reducedMotion;\n if (this.paused) this.renderFrame(0, this.seed);\n else this.start();\n }\n\n private sizeCanvas(): void {\n const dpr = Math.min(this.saverCtx.dpr, 2);\n this.canvas.width = Math.max(1, Math.round(this.w * dpr));\n this.canvas.height = Math.max(1, Math.round(this.h * dpr));\n this.ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n }\n\n /** (Re)seed and place all entities — deterministic for the seed + size. */\n private rebuild(): void {\n const rng = createRng(this.seed);\n this.layers = this.spec.layers.map((layer) => ({ layer, entities: buildEntities(layer, rng, this.w, this.h) }));\n }\n\n private start(): void {\n if (this.frameId !== null || typeof requestAnimationFrame === 'undefined') return;\n this.startT = 0;\n this.frameId = requestAnimationFrame((now) => this.loop(now));\n }\n\n private stop(): void {\n if (this.frameId !== null) {\n cancelAnimationFrame(this.frameId);\n this.frameId = null;\n }\n // Freeze elapsed time so resume continues the scene instead of restarting at t=0.\n this.baseT = this.lastT;\n }\n\n private loop(now: number): void {\n this.frameId = requestAnimationFrame((n) => this.loop(n));\n if (this.startT === 0) this.startT = now;\n this.lastT = now - this.startT + this.baseT;\n this.renderFrame(this.lastT, this.seed);\n }\n\n private drawBackground(): void {\n const { ctx, w, h } = this;\n const bg = this.spec.background;\n if (!bg || bg.type === 'solid') {\n ctx.fillStyle = bg?.color ?? '#05050a';\n ctx.fillRect(0, 0, w, h);\n return;\n }\n const g = ctx.createLinearGradient(0, 0, 0, h);\n for (const s of bg.stops) g.addColorStop(Math.max(0, Math.min(1, s.at)), s.color);\n ctx.fillStyle = g;\n ctx.fillRect(0, 0, w, h);\n if (bg.band) {\n ctx.fillStyle = bg.band.color;\n ctx.fillRect(0, h - bg.band.height, w, bg.band.height);\n }\n }\n\n private drawEntity(built: Built, e: Entity, t: number): void {\n const { ctx } = this;\n const p = positionAt(e, t, this.w, this.h);\n const sprite = built.layer.sprite;\n ctx.globalAlpha = alphaAt(e, t);\n if (sprite.kind === 'circle') {\n const r = e.size / 2;\n if (sprite.soft) {\n // Glow orb: solid core fading radially to transparent (pairs with blend:'lighter').\n const g = ctx.createRadialGradient(p.x, p.y, 0, p.x, p.y, r);\n g.addColorStop(0, sprite.color);\n g.addColorStop(0.35, hexToRgba(sprite.color, 0.75));\n g.addColorStop(1, hexToRgba(sprite.color, 0));\n ctx.fillStyle = g;\n } else {\n ctx.fillStyle = sprite.color;\n }\n ctx.beginPath();\n ctx.arc(p.x, p.y, r, 0, Math.PI * 2);\n ctx.fill();\n return;\n }\n ctx.save();\n ctx.translate(p.x, p.y);\n if (p.flip && built.layer.flip) ctx.scale(-1, 1);\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n if (sprite.kind === 'emoji') {\n ctx.font = `${e.size}px serif`;\n ctx.fillText(sprite.glyphs[e.spriteIndex] ?? sprite.glyphs[0]!, 0, 0);\n } else {\n ctx.textAlign = sprite.align ?? 'center';\n ctx.textBaseline = sprite.baseline ?? 'middle';\n ctx.font = sprite.font ?? `${e.size}px system-ui, sans-serif`;\n ctx.fillStyle = sprite.color ?? '#e6e8ef';\n const text = sprite.strings[e.spriteIndex] ?? sprite.strings[0]!;\n if (sprite.maxWidth) ctx.fillText(text, 0, 0, sprite.maxWidth);\n else ctx.fillText(text, 0, 0);\n }\n ctx.restore();\n }\n\n /** Deterministic, frame-addressable render (shared by the rAF loop). */\n renderFrame(t: number, _seed: number): void {\n const { ctx } = this;\n ctx.globalAlpha = 1;\n ctx.globalCompositeOperation = 'source-over';\n this.drawBackground();\n for (const built of this.layers) {\n ctx.globalCompositeOperation = built.layer.blend ?? 'source-over';\n for (const e of built.entities) this.drawEntity(built, e, t);\n }\n ctx.globalAlpha = 1;\n ctx.globalCompositeOperation = 'source-over';\n }\n\n setPaused(paused: boolean): void {\n this.paused = paused;\n if (paused) {\n this.stop();\n } else {\n this.start();\n }\n }\n\n resize(width: number, height: number, dpr?: number): void {\n this.w = width;\n this.h = height;\n if (dpr !== undefined) this.saverCtx.dpr = dpr;\n this.sizeCanvas();\n this.rebuild();\n if (this.paused) this.renderFrame(0, this.seed);\n }\n\n dispose(): void {\n this.stop();\n if (typeof HTMLCanvasElement !== 'undefined' && this.canvas instanceof HTMLCanvasElement) this.canvas.remove();\n }\n}\n\n/**\n * Compile a declarative spec into a runnable SaverPlugin. Throws if the spec is invalid\n * (so an agent-authored spec is validated before it can run). The result is seeded,\n * deterministic, `renderFrame(t,seed)`-addressable, and flash-safe by construction.\n */\nexport function compileSaver(spec: unknown): SaverPlugin {\n const valid = assertValidSpec(spec);\n return {\n manifest: manifestFor(valid),\n mount: (ctx: SaverContext) => new SpecInstance(valid, ctx),\n spec: valid,\n };\n}\n","import type { SaverSpec } from './types';\n\n/**\n * Reproduces the hand-coded Fish Aquarium saver as pure DATA — the discriminating test\n * that the schema is actually expressive: two layers (fish drifting both ways at varied\n * speeds with a bob + flip, over a gradient with a seafloor band; bubbles rising with sway).\n */\nexport const AQUARIUM_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'aquarium',\n label: 'Aquarium',\n seed: 42,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#0a3a52' },\n { at: 0.6, color: '#062534' },\n { at: 1, color: '#02141d' },\n ],\n band: { color: '#0b1a12', height: 24 },\n },\n layers: [\n {\n count: 14,\n sprite: { kind: 'emoji', glyphs: ['🐟', '🐠', '🐡', '🦈', '🐙'] },\n size: [34, 72],\n motion: { type: 'drift', speed: [30, 110], bidirectional: true, bob: 6 },\n flip: true,\n },\n {\n count: 22,\n sprite: { kind: 'circle', radius: [2, 7], color: '#c8ebff' },\n motion: { type: 'rise', speed: [24, 78], sway: 8 },\n },\n ],\n};\n\n/** Rain: dense text streaks falling straight down over a near-black sky. */\nexport const RAIN_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'rain',\n label: 'Rain',\n seed: 7,\n motionIntensity: 'moderate',\n background: { type: 'solid', color: '#05070a' },\n layers: [\n {\n count: 140,\n sprite: { kind: 'text', strings: ['│'], color: '#9fd0ff' },\n size: [12, 26],\n motion: { type: 'drift', angle: 90, speed: [520, 900] },\n },\n ],\n};\n\n/** Snowfall: three depth layers of white circles drifting down with horizontal bob. */\nexport const SNOWFALL_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'snowfall',\n label: 'Snowfall',\n seed: 12,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#0a1628' },\n { at: 0.7, color: '#0d1f3c' },\n { at: 1, color: '#121212' },\n ],\n },\n layers: [\n {\n count: 50,\n sprite: { kind: 'circle', radius: [1, 2.5], color: '#8899aa' },\n motion: { type: 'drift', angle: 90, speed: [15, 40], bob: 3 },\n },\n {\n count: 35,\n sprite: { kind: 'circle', radius: [2, 4.5], color: '#c0cdd8' },\n motion: { type: 'drift', angle: 85, speed: [35, 80], bob: 6 },\n },\n {\n count: 15,\n sprite: { kind: 'circle', radius: [3.5, 7], color: '#e8eff5' },\n motion: { type: 'drift', angle: 82, speed: [55, 120], bob: 10 },\n },\n ],\n};\n\n/**\n * Night Lanterns (Yi Peng festival sky): depth from four correlated parallax cues —\n * closer layers are LARGER, FASTER, SWAY WIDER, and glow WARMER/BRIGHTER. v2 of this\n * composition exercises the expressive additions the first draft exposed as missing:\n * soft glow orbs + additive blend (lantern light that sums where it overlaps), bounded\n * alpha pulse with per-entity phases (breathing flames, strobe-proof by construction),\n * and spawn regions (stars only above the horizon; dim ember shimmer kept low near\n * the water line).\n */\nexport const LANTERNS_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'lanterns',\n label: 'Night Lanterns',\n seed: 88,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#04060f' },\n { at: 0.55, color: '#0b1026' },\n { at: 0.85, color: '#251731' },\n { at: 1, color: '#472518' },\n ],\n },\n layers: [\n {\n count: 60,\n sprite: { kind: 'circle', radius: [0.5, 1.4], color: '#8fa0c8' },\n alpha: [0.35, 1],\n region: { y: [0, 0.62] },\n motion: { type: 'drift', speed: [0.5, 2], bob: 1 },\n },\n {\n count: 36,\n sprite: {\n kind: 'circle',\n radius: [1.5, 3],\n color: '#b06a2a',\n soft: true,\n },\n alpha: [0.5, 0.9],\n blend: 'lighter',\n pulse: { amp: 0.18, period: 2800 },\n motion: { type: 'rise', speed: [6, 14], sway: 4 },\n },\n {\n count: 14,\n sprite: {\n kind: 'circle',\n radius: [3.5, 6.5],\n color: '#e08a34',\n soft: true,\n },\n alpha: [0.6, 1],\n blend: 'lighter',\n pulse: { amp: 0.22, period: 3400 },\n motion: { type: 'rise', speed: [16, 28], sway: 7 },\n },\n {\n count: 8,\n sprite: { kind: 'emoji', glyphs: ['🏮'] },\n size: [26, 44],\n alpha: [0.85, 1],\n motion: { type: 'rise', speed: [30, 48], sway: 10 },\n },\n {\n count: 4,\n sprite: { kind: 'emoji', glyphs: ['🏮'] },\n size: [58, 84],\n motion: { type: 'rise', speed: [52, 74], sway: 14 },\n },\n {\n count: 12,\n sprite: { kind: 'circle', radius: [2, 5], color: '#e08a34', soft: true },\n alpha: [0.12, 0.35],\n blend: 'lighter',\n region: { y: [0.93, 1] },\n pulse: { amp: 0.1, period: 2200 },\n motion: { type: 'drift', speed: [2, 6], bob: 2 },\n },\n ],\n};\n\n/**\n * Sakura Drift: cherry-blossom petals carried on a spring twilight breeze. Five\n * correlated-parallax layers build the depth — the far backdrop is a barely-moving\n * field of soft blossom-glow orbs (additive, breathing out of phase), then three\n * petal layers grow LARGER, FASTER, BRIGHTER and FLUTTER WIDER as they approach\n * (the near gust), over a blue-hour gradient with a warm rose horizon and a dark\n * grass band. A final low layer of dim pink glow settles at the grass line — fallen\n * petals catching the last light. Wind direction is consistent (down-left) across\n * every moving layer; petals differ from snowfall by glyph, colour, palette and the\n * diagonal breeze, and from lanterns by falling rather than rising.\n */\nexport const SAKURA_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'sakura',\n label: 'Sakura Drift',\n seed: 314,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#1b1d38' },\n { at: 0.45, color: '#3a2645' },\n { at: 0.8, color: '#7d3d4e' },\n { at: 1, color: '#0f140d' },\n ],\n band: { color: '#0c140d', height: 44 },\n },\n layers: [\n {\n count: 60,\n sprite: { kind: 'circle', radius: [0.6, 1.6], color: '#ffe3ec', soft: true },\n alpha: [0.3, 0.9],\n blend: 'lighter',\n region: { y: [0, 0.72] },\n pulse: { amp: 0.22, period: 3000 },\n motion: { type: 'drift', speed: [0.3, 1.2], bob: 1 },\n },\n {\n count: 28,\n sprite: { kind: 'emoji', glyphs: ['🌸'] },\n size: [13, 20],\n alpha: [0.5, 0.8],\n motion: { type: 'drift', speed: [12, 26], angle: 100, bob: 3 },\n },\n {\n count: 18,\n sprite: { kind: 'emoji', glyphs: ['🌸'] },\n size: [20, 32],\n alpha: [0.7, 0.95],\n motion: { type: 'drift', speed: [24, 44], angle: 100, bob: 6 },\n },\n {\n count: 10,\n sprite: { kind: 'emoji', glyphs: ['🌸'] },\n size: [34, 54],\n alpha: [0.85, 1],\n motion: { type: 'drift', speed: [42, 68], angle: 100, bob: 11 },\n },\n {\n count: 16,\n sprite: { kind: 'circle', radius: [1.5, 4], color: '#ff9bb5', soft: true },\n alpha: [0.1, 0.3],\n blend: 'lighter',\n region: { y: [0.9, 1] },\n pulse: { amp: 0.15, period: 2600 },\n motion: { type: 'drift', speed: [0.3, 1.5], angle: 180, bob: 1 },\n },\n ],\n};\n\n/**\n * Dev Dashboard: a dense ops-style HUD exercising static positioning, keyed layers,\n * and text alignment at scale. Two ambient particle layers provide depth behind 28\n * pinned text elements arranged in a three-column layout with header, metrics,\n * file list, and scrolling event log.\n */\nexport const DASHBOARD_SPEC: SaverSpec = {\n schemaVersion: 1,\n id: 'dev-dashboard',\n label: 'Dev Dashboard',\n seed: 256,\n motionIntensity: 'calm',\n background: {\n type: 'gradient',\n stops: [\n { at: 0, color: '#06060c' },\n { at: 0.5, color: '#0a0a14' },\n { at: 1, color: '#0c0c18' },\n ],\n },\n layers: [\n // --- ambient depth ---\n {\n count: 50,\n sprite: { kind: 'circle', radius: [0.2, 0.8], color: '#1a2538' },\n alpha: [0.1, 0.25],\n motion: { type: 'drift', speed: [0.3, 1.2], bob: 0.3 },\n },\n {\n count: 12,\n sprite: { kind: 'circle', radius: [1, 2.5], color: '#1a3050', soft: true },\n alpha: [0.08, 0.18],\n blend: 'lighter',\n pulse: { amp: 0.08, period: 4000 },\n motion: { type: 'drift', speed: [0.5, 1.5], bob: 0.5 },\n },\n // --- header ---\n {\n key: 'title', count: 1,\n position: { x: 0.5, y: 0.04 },\n sprite: { kind: 'text', strings: ['DEV PULSE'], color: '#556677',\n font: \"600 13px 'SF Mono', monospace\", align: 'center' },\n motion: { type: 'static' },\n },\n {\n key: 'status', count: 1,\n position: { x: 0.92, y: 0.04 },\n sprite: { kind: 'text', strings: ['● ACTIVE'], color: '#44cc66',\n font: \"bold 10px monospace\", align: 'right' },\n motion: { type: 'static' },\n },\n {\n key: 'uptime', count: 1,\n position: { x: 0.08, y: 0.04 },\n sprite: { kind: 'text', strings: ['up 2h 14m'], color: '#445566',\n font: \"10px monospace\", align: 'left' },\n motion: { type: 'static' },\n },\n // --- left column: metrics ---\n {\n key: 'tools-label', count: 1,\n position: { x: 0.06, y: 0.12 },\n sprite: { kind: 'text', strings: ['TOOL CALLS'], color: '#445566',\n font: '9px monospace', align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n },\n {\n key: 'tools-value', count: 1,\n position: { x: 0.06, y: 0.16 },\n sprite: { kind: 'text', strings: ['147'], color: '#44aaff',\n font: 'bold 28px monospace', align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n },\n {\n key: 'reads-label', count: 1,\n position: { x: 0.06, y: 0.26 },\n sprite: { kind: 'text', strings: ['READS'], color: '#445566',\n font: '9px monospace', align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n },\n {\n key: 'reads-value', count: 1,\n position: { x: 0.06, y: 0.30 },\n sprite: { kind: 'text', strings: ['89'], color: '#44ddcc',\n font: 'bold 28px monospace', align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n },\n {\n key: 'edits-label', count: 1,\n position: { x: 0.06, y: 0.40 },\n sprite: { kind: 'text', strings: ['EDITS'], color: '#445566',\n font: '9px monospace', align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n },\n {\n key: 'edits-value', count: 1,\n position: { x: 0.06, y: 0.44 },\n sprite: { kind: 'text', strings: ['34'], color: '#ff8844',\n font: 'bold 28px monospace', align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n },\n {\n key: 'errors-label', count: 1,\n position: { x: 0.06, y: 0.54 },\n sprite: { kind: 'text', strings: ['ERRORS'], color: '#445566',\n font: '9px monospace', align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n },\n {\n key: 'errors-value', count: 1,\n position: { x: 0.06, y: 0.58 },\n sprite: { kind: 'text', strings: ['2'], color: '#ff4455',\n font: 'bold 28px monospace', align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n },\n // --- center column: system gauges ---\n {\n key: 'cpu-label', count: 1,\n position: { x: 0.38, y: 0.12 },\n sprite: { kind: 'text', strings: ['CPU'], color: '#445566',\n font: '9px monospace', align: 'center' },\n motion: { type: 'static' },\n },\n {\n key: 'cpu-value', count: 1,\n position: { x: 0.38, y: 0.22 },\n sprite: { kind: 'text', strings: ['73%'], color: '#44ff88',\n font: 'bold 36px monospace', align: 'center' },\n motion: { type: 'static' },\n },\n {\n key: 'mem-label', count: 1,\n position: { x: 0.38, y: 0.36 },\n sprite: { kind: 'text', strings: ['MEMORY'], color: '#445566',\n font: '9px monospace', align: 'center' },\n motion: { type: 'static' },\n },\n {\n key: 'mem-value', count: 1,\n position: { x: 0.38, y: 0.46 },\n sprite: { kind: 'text', strings: ['4.2 GB'], color: '#ddcc44',\n font: 'bold 36px monospace', align: 'center' },\n motion: { type: 'static' },\n },\n {\n key: 'tokens-label', count: 1,\n position: { x: 0.38, y: 0.58 },\n sprite: { kind: 'text', strings: ['TOKENS'], color: '#445566',\n font: '9px monospace', align: 'center' },\n motion: { type: 'static' },\n },\n {\n key: 'tokens-value', count: 1,\n position: { x: 0.38, y: 0.66 },\n sprite: { kind: 'text', strings: ['128k'], color: '#aa88ff',\n font: 'bold 28px monospace', align: 'center' },\n motion: { type: 'static' },\n },\n // --- right column: recent files ---\n {\n key: 'files-label', count: 1,\n position: { x: 0.62, y: 0.12 },\n sprite: { kind: 'text', strings: ['RECENT FILES'], color: '#445566',\n font: '9px monospace', align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n },\n {\n key: 'file-1', count: 1,\n position: { x: 0.62, y: 0.17 },\n sprite: { kind: 'text', strings: ['src/worker.ts'], color: '#8899aa',\n font: '11px monospace', align: 'left', baseline: 'top', maxWidth: 280 },\n motion: { type: 'static' },\n },\n {\n key: 'file-2', count: 1,\n position: { x: 0.62, y: 0.21 },\n sprite: { kind: 'text', strings: ['site/src/App.tsx'], color: '#778899',\n font: '11px monospace', align: 'left', baseline: 'top', maxWidth: 280 },\n motion: { type: 'static' },\n },\n {\n key: 'file-3', count: 1,\n position: { x: 0.62, y: 0.25 },\n sprite: { kind: 'text', strings: ['packages/schema/compile.ts'], color: '#667788',\n font: '11px monospace', align: 'left', baseline: 'top', maxWidth: 280 },\n motion: { type: 'static' },\n },\n {\n key: 'file-4', count: 1,\n position: { x: 0.62, y: 0.29 },\n sprite: { kind: 'text', strings: ['docs/dashboard-spec.md'], color: '#556677',\n font: '11px monospace', align: 'left', baseline: 'top', maxWidth: 280 },\n motion: { type: 'static' },\n },\n {\n key: 'file-5', count: 1,\n position: { x: 0.62, y: 0.33 },\n sprite: { kind: 'text', strings: ['packages/core/types.ts'], color: '#445566',\n font: '11px monospace', align: 'left', baseline: 'top', maxWidth: 280 },\n motion: { type: 'static' },\n },\n // --- right column: session info ---\n {\n key: 'session-label', count: 1,\n position: { x: 0.62, y: 0.42 },\n sprite: { kind: 'text', strings: ['SESSION'], color: '#445566',\n font: '9px monospace', align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n },\n {\n key: 'session-model', count: 1,\n position: { x: 0.62, y: 0.47 },\n sprite: { kind: 'text', strings: ['claude-opus-4-6'], color: '#8888aa',\n font: '11px monospace', align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n },\n {\n key: 'session-cost', count: 1,\n position: { x: 0.62, y: 0.51 },\n sprite: { kind: 'text', strings: ['$2.47 this session'], color: '#667788',\n font: '11px monospace', align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n },\n // --- bottom: event log ---\n {\n key: 'log-label', count: 1,\n position: { x: 0.06, y: 0.76 },\n sprite: { kind: 'text', strings: ['EVENT LOG'], color: '#445566',\n font: '9px monospace', align: 'left', baseline: 'top' },\n motion: { type: 'static' },\n },\n {\n key: 'log-1', count: 1,\n position: { x: 0.06, y: 0.80 },\n sprite: { kind: 'text', strings: ['14:07 Edit compile.ts +18 -3'], color: '#667766',\n font: '10px monospace', align: 'left', baseline: 'top', maxWidth: 600 },\n motion: { type: 'static' },\n },\n {\n key: 'log-2', count: 1,\n position: { x: 0.06, y: 0.84 },\n sprite: { kind: 'text', strings: ['14:06 Bash pnpm test ✓ 125 passed'], color: '#556655',\n font: '10px monospace', align: 'left', baseline: 'top', maxWidth: 600 },\n motion: { type: 'static' },\n },\n {\n key: 'log-3', count: 1,\n position: { x: 0.06, y: 0.88 },\n sprite: { kind: 'text', strings: ['14:05 Read types.ts (121 lines)'], color: '#4d5e4d',\n font: '10px monospace', align: 'left', baseline: 'top', maxWidth: 600 },\n motion: { type: 'static' },\n },\n {\n key: 'log-4', count: 1,\n position: { x: 0.06, y: 0.92 },\n sprite: { kind: 'text', strings: ['14:03 Edit examples.ts +84 -1'], color: '#445544',\n font: '10px monospace', align: 'left', baseline: 'top', maxWidth: 600 },\n motion: { type: 'static' },\n },\n {\n key: 'log-5', count: 1,\n position: { x: 0.06, y: 0.96 },\n sprite: { kind: 'text', strings: ['14:01 Bash pnpm build ✓ 6 packages'], color: '#3d4e3d',\n font: '10px monospace', align: 'left', baseline: 'top', maxWidth: 600 },\n motion: { type: 'static' },\n },\n ],\n};\n\nexport const EXAMPLE_SPECS: SaverSpec[] = [\n AQUARIUM_SPEC,\n RAIN_SPEC,\n SNOWFALL_SPEC,\n LANTERNS_SPEC,\n SAKURA_SPEC,\n DASHBOARD_SPEC,\n];\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@idle-screens/schema",
3
- "version": "0.1.0",
3
+ "version": "1.0.0",
4
4
  "description": "Declarative, agent-authorable saver format for idle-screens: validate a data spec, then compile it into a runnable, seeded, flash-safe SaverPlugin.",
5
5
  "license": "MIT",
6
6
  "author": "Shawn Partridge",
@@ -39,10 +39,10 @@
39
39
  "dist"
40
40
  ],
41
41
  "peerDependencies": {
42
- "@idle-screens/core": "0.1.0"
42
+ "@idle-screens/core": "0.2.0"
43
43
  },
44
44
  "devDependencies": {
45
- "@idle-screens/core": "0.1.0"
45
+ "@idle-screens/core": "0.2.0"
46
46
  },
47
47
  "scripts": {
48
48
  "build": "tsup",