@genex-ai/cli-demo 0.48.0-dev.78 → 0.48.0-dev.80

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@genex-ai/cli-demo",
3
- "version": "0.48.0-dev.78",
3
+ "version": "0.48.0-dev.80",
4
4
  "description": "Set up your ~/.claude workspace, authorize, create a game project, generate AI assets, and publish (genex CLI).",
5
5
  "type": "module",
6
6
  "bin": {
@@ -28,6 +28,34 @@ ring) that no hand-written CSS can fake.
28
28
  the CSS placeholder, finished to `$genex-threejs-game-ui`'s Tier-1 floor,
29
29
  ships as the HUD.
30
30
 
31
+ ## Three layers — plates are DOM, chrome is sprites, data is DOM
32
+
33
+ - **Plate (DOM).** The backing surface behind a widget is built in CSS — in
34
+ whatever register the brief and concept frame call for: smoked glass
35
+ (`background: rgba(<darkest hue>, 0.35–0.6)` + `backdrop-filter: blur(6–12px)`
36
+ and its `-webkit-` twin) when the style wants translucency, a solid painted
37
+ plate, a subtle gradient — or no plate at all for an outline-led look.
38
+ **Glass is a technique, not a default** — do not reach for translucency
39
+ because this skill mentions it; reach for it when THIS game's brief does.
40
+ What is fixed is WHERE plates are built — the DOM — because
41
+ semi-transparency physically cannot survive sprite extraction: a composited
42
+ panel's pixels are a blend of panel and background, and no cutout can
43
+ un-blend them. Plates are NEVER baked into sprites.
44
+ - **Chrome (sprites — what THIS pipeline generates).** Opaque frames, corner
45
+ brackets, ornaments, emblems, icons, medallions — hard-alpha art laid over
46
+ the glass. The Stage-2 sheet contains ONLY chrome; never a panel with its
47
+ fill or glass surface baked in.
48
+ - **Data (DOM).** Numbers, labels, and bar fills are DOM text and masked
49
+ fills (the fillBox pattern below) — always over the glass, never
50
+ rasterized into art.
51
+ - **Micro-elements are designed, not defaulted.** The sheet excludes
52
+ primitive-only shapes (plain crosshair ticks, dots, pips) because CSS
53
+ renders them crisper — but CSS never means default: the reticle and every
54
+ cue, toast, and counter still get the brief's treatment (stroke weight,
55
+ glow, state changes — hit, low-ammo, empowered). An ornamented,
56
+ identity-bearing reticle (engraved ring, sculpted brackets) is chrome —
57
+ put it on the sheet like any other asset.
58
+
31
59
  ## Framing rules — internalize before prompting
32
60
 
33
61
  The HUD overlays a **live 3D scene**. The pixels between widgets show the game.
@@ -36,6 +64,11 @@ The HUD overlays a **live 3D scene**. The pixels between widgets show the game.
36
64
  fabric, wood board) as part of the HUD. Material aesthetics belong on the
37
65
  widget FRAMES — the HP bar frame is parchment, the minimap ring is leather —
38
66
  never on a screen-filling sprite.
67
+ - **No plates in sprites.** Panel plates in the mockup — translucent or
68
+ solid — are welcome as the LOOK, but the Stage-2 asset list requests only
69
+ their opaque chrome (frame, brackets, ornament); the plate itself is
70
+ rebuilt at runtime in CSS matching the mockup's tint (see the three layers
71
+ above).
39
72
  - **4–7 widgets.** Fewer doesn't read as a HUD; more clutters the screen and
40
73
  burns generations.
41
74
  - **Every widget needs internal contrast** — a panel fill, outline stroke, or
@@ -92,7 +125,10 @@ and [references/stage2-prompt-template.md](references/stage2-prompt-template.md)
92
125
  **Order of work: kick Stage 1 off as your FIRST action after the UI plan
93
126
  gate**, then write the widget layout and wiring code (placement, masked-fill
94
127
  scaffolding, plain-CSS placeholder bars) while it renders — the CSS HUD keeps
95
- the game playable until the sprites land. Generate 2 mockup candidates in one
128
+ the game playable until the sprites land. When the gate produced a concept
129
+ frame, anchor Stage 1 to it — `--edit <concept-url>` holds the game's
130
+ register far better than a text-only prompt; single-sprite regenerations
131
+ anchor the same way. Generate 2 mockup candidates in one
96
132
  call (`--candidates 2`) and pick the better one: a re-roll costs the whole
97
133
  serial chain, a second candidate costs nothing extra in wall-clock.
98
134
 
@@ -15,6 +15,10 @@ Fill `[ASSET_LIST]`, then pass the whole text as the prompt to
15
15
  identity labels);
16
16
  - **states what to REMOVE** (`runtime_static` labels and `runtime_dynamic`
17
17
  values, fills, items);
18
+ - **requests chrome only** — never a panel's plate/backing surface,
19
+ translucent or solid: plates are rebuilt at runtime in CSS (rgba,
20
+ backdrop-filter, or a solid fill — whatever matches the mockup), so ask
21
+ for the panel's frame/brackets/ornament, not the panel surface itself;
18
22
  - **requests the annotated duplicate** for every bar/meter frame (the
19
23
  template's progress block below covers the mechanics — your item just says
20
24
  "output the clean frame + annotated duplicate pair").
@@ -61,7 +65,7 @@ DO NOT include in the output sheet:
61
65
  - Simple dot indicators, status pips, blip markers
62
66
  - Fills inside bars, items inside slots, map terrain inside minimap rings (these are added at runtime by CSS / game code)
63
67
 
64
- Those excluded elements will be recreated by runtime code (CSS shapes and DOM text) — much crisper than a downsampled PNG.
68
+ Those excluded elements will be recreated by runtime code (CSS shapes and DOM text) — much crisper than a downsampled PNG. Recreated does NOT mean default-styled: reticles, pips, and cues still follow the style brief (stroke weight, glow, state colors). An ornamented, identity-bearing reticle — an engraved ring, sculpted brackets — is NOT a simple primitive; include it in the asset list like any other chrome.
65
69
 
66
70
  Pure white #ffffff background everywhere except where the actual UI assets sit.
67
71
  ```
@@ -48,6 +48,14 @@ might suggest. Two hard rules for the frame prompt:
48
48
  perches", "fog drifts left then back right", "candle flames flicker".
49
49
  Bad: "camera dollies forward into the gate" (one-way motion fights the
50
50
  identical endpoints and produces a visible hitch).
51
+ **The seam is YOUR job, not the model's:** in practice the clip lands
52
+ *near* frame 0, not exactly on it, and a bare `video.loop = true` shows a
53
+ visible hitch every cycle. Always wire the video with the DOM crossfade
54
+ below, and watch one full cycle before calling the menu done. (Do not
55
+ reach for `--loop` here: it routes to a different model with a first-class
56
+ loop param but NO frame conditioning — the video won't match your key art —
57
+ and server-side `--frame` overrides `--loop` anyway, so passing both does
58
+ nothing.)
51
59
  - **Two-frame** (`--first-frame` + `--last-frame`) only when the menu
52
60
  genuinely needs a state change (rain starts and persists, a figure walks in
53
61
  and stays). The loop will have a visible seam where the last frame snaps
@@ -71,6 +79,44 @@ npx genex wait <gen-id>
71
79
  # -> https://assets.genex.technology/generations/<gen-id>/video-mp4
72
80
  ```
73
81
 
82
+ ## Seamless in the DOM — the loop crossfade (mandatory wiring)
83
+
84
+ Never wire the clip as a bare `<video loop>` — the residual seam shows every
85
+ cycle. Two stacked `<video>` elements with the same src crossfade at the
86
+ cycle end; any seam disappears deterministically, no regeneration lottery:
87
+
88
+ ```ts
89
+ /** Deterministic seamless loop: two stacked <video>s crossfade at cycle end. */
90
+ export function seamlessLoop(holder: HTMLElement, url: string, fade = 0.6): void {
91
+ const mk = (): HTMLVideoElement => {
92
+ const v = document.createElement("video");
93
+ v.src = url; v.muted = true; v.playsInline = true; v.preload = "auto";
94
+ holder.appendChild(v);
95
+ return v;
96
+ };
97
+ let front = mk(), back = mk();
98
+ front.style.opacity = "1";
99
+ void front.play();
100
+ const tick = (): void => {
101
+ if (front.duration > 0 && front.currentTime >= front.duration - fade && back.paused) {
102
+ back.currentTime = 0;
103
+ void back.play();
104
+ front.style.transition = back.style.transition = `opacity ${fade}s linear`;
105
+ back.style.opacity = "1";
106
+ front.style.opacity = "0";
107
+ const old = front; front = back; back = old;
108
+ window.setTimeout(() => back.pause(), fade * 1000 + 50);
109
+ }
110
+ requestAnimationFrame(tick);
111
+ };
112
+ requestAnimationFrame(tick);
113
+ }
114
+ ```
115
+
116
+ Pause both videos when the menu phase hides (they're decode work), and
117
+ resume the front one when it returns. Watch ONE full cycle in the browser
118
+ before calling the menu done — that's the seam check.
119
+
74
120
  **Work async — the menu must never block the game.** Generate the frame right
75
121
  after the UI plan gate, enqueue the video with `--no-wait`, ship the CSS menu
76
122
  (buttons + title over the frame IMAGE as a static backdrop), and swap the
@@ -89,9 +135,8 @@ copy-pasteable example:
89
135
  ```html
90
136
  <div id="ui">
91
137
  <div id="screen-menu" class="screen" data-phase="menu">
92
- <video class="menu-bg"
93
- src="https://assets.genex.technology/generations/<id>/video-mp4"
94
- autoplay muted loop playsinline></video>
138
+ <!-- seamlessLoop() (above) injects two crossfading <video>s here -->
139
+ <div class="menu-bg" id="menu-bg"></div>
95
140
  <div class="menu-title stagger" style="--i: 0">EMBERFALL</div>
96
141
  <button class="menu-btn stagger" id="menu-play" style="--i: 1; left: 38%; top: 52%; width: 24%; height: 8%;">PLAY</button>
97
142
  <button class="menu-btn stagger" id="menu-options" style="--i: 2; left: 38%; top: 63%; width: 24%; height: 8%;">OPTIONS</button>
@@ -104,7 +149,9 @@ copy-pasteable example:
104
149
 
105
150
  ```css
106
151
  #screen-menu { position: absolute; inset: 0; overflow: hidden; background: #000; }
107
- .menu-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
152
+ .menu-bg { position: absolute; inset: 0; }
153
+ .menu-bg video { position: absolute; inset: 0; width: 100%; height: 100%;
154
+ object-fit: cover; opacity: 0; }
108
155
  .menu-title {
109
156
  position: absolute; left: 0; right: 0; top: 14%; text-align: center;
110
157
  font-family: "Cinzel", serif; font-size: 9vh; color: #f4e3b8;
@@ -39,6 +39,15 @@ backdrop), not an afterthought `<div>`. When the menu decision is a reasoned
39
39
  "no", every "menu backdrop" row above (pause, fail, win, lobby) grades over
40
40
  the loader's key art instead.
41
41
 
42
+ The table lists screens; **elements are inventoried separately**. Walk the
43
+ whole loop in your head — loader → menu → spawn → action → pickup → damage →
44
+ death → retry → win — and write down EVERY on-screen element the player will
45
+ ever see: the reticle and each of its states, aim/interact cues, toasts,
46
+ damage numbers, kill feeds, timers, countdowns, pickup popups… Each element
47
+ gets a treatment from the brief. **Nothing ships looking like default
48
+ browser CSS** — an element styled like a bare `<div>` or a system button is
49
+ a bug wherever it appears, listed or not.
50
+
42
51
  **2. One shared style brief — for the WHOLE game, not just the UI.** Write it
43
52
  once — 4–5 named hues, materials, one display + one body font, mood — and
44
53
  store it as a comment block near the UI code. `$genex-ai-menu`,
@@ -58,6 +67,13 @@ AAA games of the genre, and state in one line which structural conventions
58
67
  you're borrowing. The bar is what those games ship, not "good enough for a
59
68
  demo". Conventions only — never logos, exact layouts, or trade dress. The
60
69
  same 2–3 names carry into the router's visual-direction gate for the scene.
70
+ Then turn references + brief into ONE **concept frame** — a single generated
71
+ image of what THIS game should look like mid-play (scene, mood, lighting;
72
+ a UI impression is welcome but optional):
73
+ `npx genex image "<one-sentence game look from the brief>" --aspect 16:9 --quality high --no-wait`,
74
+ enqueued FIRST of all art. Its URL goes into the style-brief comment as the
75
+ game's north star: every later 2D generation that accepts `--edit` anchors
76
+ to it, and the scene's lighting/grading is judged against it.
61
77
 
62
78
  **4. Ask only when genuinely ambiguous.** If the concept pins the mood (a
63
79
  "gothic horror dungeon crawler" pins it), decide and state the plan in one
@@ -70,12 +86,21 @@ it derives from the game type.
70
86
  are examples, not defaults. Do not default to neon/cyberpunk/synthwave — or
71
87
  any other single register — unless the concept calls for it.
72
88
 
73
- **6. Close the gate out loud — plan + queued generations.** The gate's output
74
- is one short visible message in chat: the screen list with tiers, the style
75
- brief (hues + font pair), the named references, and the generation IDs of the
76
- Tier-2 jobs just enqueued the `$genex-ai-hud` Stage-1 mockup (every game)
77
- and the `$genex-ai-menu` video (when the menu decision is yes). No visible
78
- plan or no queued IDs means the gate did not run — go back and run it.
89
+ **6. Close the gate out loud — a fixed-format plan message.** Post this
90
+ message in chat, translated to the user's language, filling every line —
91
+ this exact structure, not a paraphrase (the scaffold's keep-it-short talk
92
+ rule explicitly does not apply to this one message):
93
+
94
+ ```
95
+ UI plan
96
+ • Screens: <list with tiers — loader / menu / pause (Esc) / win/lose / …>
97
+ • Style: <4–5 named hues> · fonts <display> / <body>
98
+ • References: <2–3 AAA games — one line on what's borrowed>
99
+ • Concept frame: <generation id>
100
+ • Queued: HUD chrome <id> · menu video <id or "no menu: reason">
101
+ ```
102
+
103
+ A message missing any line means the gate did not run — go back and run it.
79
104
 
80
105
  ## The tier ladder
81
106
 
@@ -268,6 +293,8 @@ architecture and consume the shared style brief.
268
293
  - No pause screen, or a pause that isn't bound to Escape.
269
294
  - A style brief whose fonts were never actually loaded (a system-stack display
270
295
  font at runtime).
296
+ - A micro-element (reticle, cue, toast, damage number) left as default CSS
297
+ while the panels got the art treatment.
271
298
  - A generic stat dashboard (rows of labels + numbers) instead of a designed
272
299
  HUD — pick the 2–3 numbers that matter and style them by hierarchy.
273
300
  - Hard-cut phase swaps, a menu whose elements just appear, numbers that
@@ -71,7 +71,9 @@ stack this game ships (bloom/AO/grade — at least ONE built render-pass effect
71
71
  for EVERY game, justified by the shared style brief; the UI vignette div or a
72
72
  CSS filter on the canvas does not count, and a plan that "deliberately skips
73
73
  everything" is the stock default, not a look; `$genex-threejs-image-pipeline`
74
- owns ordering when 2+ compose), and the lighting/atmosphere mood from that
74
+ owns ordering when 2+ compose), one named **ambient-motion loop** that keeps
75
+ the scene alive at rest (emissive pulse, shimmer, drifting dust — shader
76
+ work, zero generations), and the lighting/atmosphere mood from that
75
77
  same brief. Planning is not building — effects still land last in the
76
78
  execution order.
77
79
 
@@ -150,8 +152,10 @@ concept-driven — a richer first build beats a grey-box one.
150
152
  floors from the routing-map's acceptance gate: the generated sprite HUD wired in
151
153
  (not the CSS placeholder), pause on Escape, the branded loader with its key-art
152
154
  background, the brief's fonts actually loaded, the renderer baseline + at least one
153
- built render-pass effect, and every placed 2D/media piece screenshot-verified in
154
- situ. These floors gate `npx genex publish` and the final handoff of a session the
155
+ built render-pass effect, every placed 2D/media piece screenshot-verified in
156
+ situ, no UI element left as default browser CSS, and no placeholder primitive
157
+ left where a generated asset was planned. These floors gate `npx genex publish`
158
+ and the final handoff of a session the
155
159
  same way — they do not wait for the word "done" to be said.
156
160
  - Entering an **existing or remixed project**: read before writing — learn the
157
161
  current renderer choice, physics setup, and file conventions first, then
@@ -24,10 +24,12 @@ Three.js release or branch, and do not blindly copy demo architecture.
24
24
  one shared style brief, a tier per screen — stated visibly in chat, never
25
25
  decided silently. Enqueue the Tier-2 UI generations now with `--no-wait`
26
26
  (pick them up later with `npx genex wait <id>`) — they render server-side
27
- while you build the game. The `$genex-ai-hud` Stage-1 mockup is enqueued
28
- here for EVERY game; the `$genex-ai-menu` video whenever the menu decision
29
- is yes (the default for every game "it's only a draft" is not a reason
30
- to decide no). Skipping this enqueue is
27
+ while you build the game. FIRST of all art: the gate's **concept frame** —
28
+ the single image of the finished game's look that every later `--edit`-able
29
+ generation anchors to. Then the `$genex-ai-hud` Stage-1 mockup, enqueued
30
+ here for EVERY game; and the `$genex-ai-menu` video whenever the menu
31
+ decision is yes (the default for every game — "it's only a draft" is not a
32
+ reason to decide no). Skipping this enqueue is
31
33
  the #1 way a finished game ships an ugly HUD — by step 12 there is nothing
32
34
  to swap in.
33
35
  4. Lock the visual direction — the same plan-first logic as the UI gate, in
@@ -47,7 +49,14 @@ Three.js release or branch, and do not blindly copy demo architecture.
47
49
  owns the pass ordering;
48
50
  - **references**: name 2–3 AAA games whose look this game borrows
49
51
  (conventions, lighting mood, palette, post — never trade dress); the
50
- same 2–3 the UI gate named, extended from the interface to the scene;
52
+ same 2–3 the UI gate named, extended from the interface to the scene,
53
+ and embodied in the gate's concept frame — the image the scene is
54
+ judged against;
55
+ - **ambient motion**: name ONE subtle environmental motion loop that keeps
56
+ the scene alive at rest — an emissive pulse along edges, heat shimmer,
57
+ drifting dust, a slowly flowing texture. Shader/procedural, zero
58
+ generations, built with the scene — a world that is perfectly still
59
+ reads as a screenshot, not a place;
51
60
  - **lighting/atmosphere mood** from the SAME shared style brief the UI gate
52
61
  wrote — one art direction across scene and UI.
53
62
  Planning is not building: effects still land LAST (steps 10–11); this step
@@ -61,15 +70,16 @@ Three.js release or branch, and do not blindly copy demo architecture.
61
70
  architecture, planets, water, precipitation, clouds, or VFX. Show the
62
71
  planned loader from the very first asset load — a player must never stare
63
72
  at a black screen; the rest of the UI states come at step 12.
64
- Then dress the world with 2D/media art: walk the scene for image/video
65
- insertion points posters, signs, graffiti, decals, banners, in-world
66
- screens and billboards (`$genex-ai-image`; `$genex-ai-video` for anything
67
- that should move). The visual-direction block names the 2–4 pieces this
68
- world gets (or states in one line why it has none that waiver is valid
69
- only for a world with no authored surfaces at all, pure-abstract geometry
70
- or empty open water/space; a world with buildings, walls, rooms, vehicles,
71
- or props names its pieces); enqueue them with
72
- `--no-wait` alongside the other assets. Every placed piece is
73
+ Then make the world-dressing DECISION a judgment call, not a quota:
74
+ does THIS world's fiction support 2D art (posters, signs, graffiti,
75
+ decals, banners, in-world screens `$genex-ai-image`; `$genex-ai-video`
76
+ for anything that should move)? Say the decision in one line in the
77
+ visual-direction block. Name only the pieces that genuinely belonga
78
+ garage wants grease posters and warning decals; a pristine void wants
79
+ none and anchor their prompts to the concept frame. **Zero is a valid
80
+ answer with a stated reason; art placed just to satisfy this step is the
81
+ failure mode, not skipping it.** Enqueue what you named with `--no-wait`
82
+ alongside the other assets. Every placed piece is
73
83
  screenshot-checked in situ — right scale, not stretched, unlit material
74
84
  where it must glow, readable at gameplay distance
75
85
  (`$genex-threejs-visual-validation` owns the capture discipline).
@@ -89,7 +99,10 @@ Three.js release or branch, and do not blindly copy demo architecture.
89
99
  `$genex-threejs-game-ui` (HUD, pause on Escape, fail/retry, win, and the
90
100
  full loading state grown from the step-6 loader), then `npx genex wait`
91
101
  the step-3 UI generations and wire them in — the sprite HUD replaces the
92
- placeholder CSS, the menu video replaces the still frame. This swap is a
102
+ placeholder CSS, the menu video replaces the still frame (wired with the
103
+ menu skill's loop crossfade), and the scene's planned generated models
104
+ replace their placeholder primitives — a shipped wave of enemies may not
105
+ be untextured boxes. This swap is a
93
106
  completion gate, not an option: a game still on the placeholder CSS HUD,
94
107
  or without a working Escape pause, is not done. Then run a feel pass via
95
108
  `$genex-threejs-game-feel` (input response, camera, impact feedback,
@@ -97,6 +110,33 @@ Three.js release or branch, and do not blindly copy demo architecture.
97
110
  13. Validate in a real browser with fixed seeds, captures, interaction checks,
98
111
  and performance evidence.
99
112
 
113
+ ## Parallelize with subagents (when the environment has them)
114
+
115
+ Generations already render server-side in parallel — the wall-clock savings
116
+ live in the ATTENDED chains. When the coding agent supports background
117
+ subagents (e.g. Claude Code's Agent tool), split these off; in environments
118
+ without them (Cursor), the same order simply runs sequentially and the
119
+ `--no-wait` pattern still hides most generation latency.
120
+
121
+ - **HUD chain worker.** The moment the Stage-1 mockup lands, hand the whole
122
+ `$genex-ai-hud` chain to one subagent: pick the better candidate → Stage-2
123
+ sheet → clean → extract → masks → write the sprite wiring. Its prompt must
124
+ be self-contained — the style brief, concept-frame and mockup URLs, the
125
+ output dir, and exactly which files it owns.
126
+ - **Asset shepherd.** One subagent runs `npx genex wait` on every queued ID
127
+ and wires each asset in as it lands (skybox, models, menu video, dressing),
128
+ swapping placeholders out and reporting each swap.
129
+ - **Verification runner.** Browser evidence — screenshots, control presses,
130
+ the menu loop-seam watch, in-situ checks of placed art — can run in a
131
+ subagent while the main agent keeps building.
132
+
133
+ Hard rules: **one writer per file** — each subagent owns a disjoint file set
134
+ (the HUD worker owns the hud modules and `public/assets/hud/`, the shepherd
135
+ owns asset-wiring modules), and the main agent stays the only writer of
136
+ gameplay/netcode. Merge points are explicit: a subagent reports what it
137
+ changed, the main agent reconciles. Never put two writers on the same
138
+ module — a corrupted entry point costs more than the minutes saved.
139
+
100
140
  ## Acceptance gate
101
141
 
102
142
  **Game fast path:** for a game task that loaded no procedural/visual-system skill,
@@ -107,7 +147,9 @@ sprite HUD wired in — not the CSS placeholder — pause on Escape, the branded
107
147
  loader with its key-art background, the brief's font pair actually loaded)
108
148
  and the look floor (the step-4 renderer baseline + named post stack actually
109
149
  built; every placed 2D/media piece — decals, posters, in-world screens —
110
- screenshot-verified in situ)**. These floors gate `npx genex publish` and the
150
+ screenshot-verified in situ; no UI element left as default browser CSS; no
151
+ placeholder primitive left where a generated asset was
152
+ planned)**. These floors gate `npx genex publish` and the
111
153
  final handoff of a session the same way — "I never said it was done" is not
112
154
  an exemption. The list below applies to routed *visual-system* scenes, and each
113
155
  system-specific item (debug views, seed manifests, tier knobs) applies only when