@playcraft/cli 0.0.41 → 0.0.42

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.
Files changed (49) hide show
  1. package/dist/commands/tools-generation.js +2 -4
  2. package/dist/commands/tools-utils.js +19 -0
  3. package/dist/utils/version-checker.js +8 -11
  4. package/package.json +3 -3
  5. package/project-template/.claude/agents/designer.md +12 -8
  6. package/project-template/.claude/agents/developer.md +53 -62
  7. package/project-template/.claude/agents/refs/README.md +21 -15
  8. package/project-template/.claude/agents/refs/designer-deliverable-spec.md +24 -0
  9. package/project-template/.claude/agents/refs/designer-master-composite-recipes.md +20 -28
  10. package/project-template/.claude/agents/refs/developer-phase1-flow.md +81 -156
  11. package/project-template/.claude/agents/refs/pm-workflow-detail.md +6 -0
  12. package/project-template/.claude/agents/refs/reviewer-convergence-eval.md +130 -0
  13. package/project-template/.claude/agents/refs/reviewer-six-dimension-eval.md +4 -284
  14. package/project-template/.claude/agents/refs/ta-atlas-deliverable-standard.md +27 -6
  15. package/project-template/.claude/agents/refs/ta-pipeline-cookbook.md +433 -24
  16. package/project-template/.claude/agents/reviewer.md +62 -38
  17. package/project-template/.claude/agents/technical-artist.md +36 -25
  18. package/project-template/.claude/hooks/README.md +9 -1
  19. package/project-template/.claude/hooks/validate-workflow-stop.mjs +86 -1
  20. package/project-template/.claude/settings.json +4 -0
  21. package/project-template/.claude/skills/playcraft-image-generation/SKILL.md +65 -15
  22. package/project-template/.claude/skills/playcraft-storyboard/SKILL.md +26 -7
  23. package/project-template/.claude/skills/playcraft-workflow/SKILL.md +104 -15
  24. package/project-template/.claude/skills/playwright-cli/SKILL.md +390 -0
  25. package/project-template/.claude/skills/playwright-cli/references/element-attributes.md +23 -0
  26. package/project-template/.claude/skills/playwright-cli/references/playwright-tests.md +39 -0
  27. package/project-template/.claude/skills/playwright-cli/references/request-mocking.md +87 -0
  28. package/project-template/.claude/skills/playwright-cli/references/running-code.md +240 -0
  29. package/project-template/.claude/skills/playwright-cli/references/session-management.md +226 -0
  30. package/project-template/.claude/skills/playwright-cli/references/spec-driven-testing.md +312 -0
  31. package/project-template/.claude/skills/playwright-cli/references/storage-state.md +275 -0
  32. package/project-template/.claude/skills/playwright-cli/references/test-generation.md +138 -0
  33. package/project-template/.claude/skills/playwright-cli/references/tracing.md +142 -0
  34. package/project-template/.claude/skills/playwright-cli/references/video-recording.md +157 -0
  35. package/project-template/.cursor/rules/playcraft-orchestrator.mdc +74 -24
  36. package/project-template/.cursor/rules/playcraft-subagent-boundary.mdc +1 -1
  37. package/project-template/CLAUDE.md +99 -59
  38. package/project-template/docs/team/agent-conduct.md +42 -26
  39. package/project-template/docs/team/atom-plan-format.md +33 -2
  40. package/project-template/docs/team/collaboration.md +57 -48
  41. package/project-template/docs/team/workflow-changelog.md +28 -14
  42. package/project-template/docs/team/workflow-consistency-checklist.md +12 -0
  43. package/project-template/templates/atom-plan.template.md +35 -3
  44. package/project-template/templates/designer-log.template.md +16 -0
  45. package/project-template/templates/developer-log.template.md +95 -101
  46. package/project-template/templates/layout-spec.template.md +14 -0
  47. package/project-template/templates/project-state.template.md +51 -33
  48. package/project-template/templates/review-report.template.md +76 -151
  49. package/project-template/templates/ta-log.template.md +138 -0
@@ -2,7 +2,7 @@ import { writeFileSync, mkdirSync } from 'fs';
2
2
  import { dirname, parse, join } from 'path';
3
3
  import sharp from 'sharp';
4
4
  import { AgentApiClient } from '../utils/agent-api-client.js';
5
- import { MAX_REFERENCE_IMAGES, collectReferenceImagePaths, collectReferenceImagePayloads, sniffImageExtension, extensionForImageMime, resolveImageOutputPath, handleError, } from './tools-utils.js';
5
+ import { MAX_REFERENCE_IMAGES, collectReferenceImagePaths, collectReferenceImagePayloads, sniffImageExtension, extensionForImageMime, resolveImageOutputPath, handleError, raceWithTimeout, } from './tools-utils.js';
6
6
  function isMasterCompositeStripRequest(opts) {
7
7
  if (opts.aspectRatio === '45:16')
8
8
  return true;
@@ -176,8 +176,6 @@ export function registerGenerationCommands(tools) {
176
176
  }
177
177
  const referenceImages = await collectReferenceImagePayloads(paths);
178
178
  const client = new AgentApiClient();
179
- const timeoutMs = opts.timeout * 1000;
180
- const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error(`Request timed out after ${opts.timeout}s. The backend task may still be running — check admin panel before re-running.`)), timeoutMs));
181
179
  const imageCount = Math.min(Math.max(1, opts.count ?? 1), 10);
182
180
  const requestPromise = client.post('/generate-image', {
183
181
  prompt: opts.prompt,
@@ -188,7 +186,7 @@ export function registerGenerationCommands(tools) {
188
186
  ...(modelRef ? { imageModelRef: modelRef } : {}),
189
187
  ...(imageCount > 1 ? { imageCount } : {}),
190
188
  });
191
- return Promise.race([requestPromise, timeoutPromise]);
189
+ return raceWithTimeout(requestPromise, opts.timeout * 1000, `Request timed out after ${opts.timeout}s. The backend task may still be running — check admin panel before re-running.`);
192
190
  };
193
191
  const enrichError = (err, modelRef) => {
194
192
  const msg = err instanceof Error ? err.message : String(err);
@@ -20,6 +20,25 @@ export function handleError(err) {
20
20
  console.error(`Error: ${msg}`);
21
21
  process.exit(1);
22
22
  }
23
+ /**
24
+ * Race a promise against a timeout. Clears the timer when the promise settles so
25
+ * short-lived CLI processes exit immediately (uncleared timers keep Node alive).
26
+ */
27
+ export async function raceWithTimeout(promise, timeoutMs, timeoutMessage) {
28
+ if (timeoutMs <= 0)
29
+ return promise;
30
+ let timeoutId;
31
+ const timeoutPromise = new Promise((_, reject) => {
32
+ timeoutId = setTimeout(() => reject(new Error(timeoutMessage)), timeoutMs);
33
+ });
34
+ try {
35
+ return await Promise.race([promise, timeoutPromise]);
36
+ }
37
+ finally {
38
+ if (timeoutId !== undefined)
39
+ clearTimeout(timeoutId);
40
+ }
41
+ }
23
42
  /** Fallback extension from API mime when magic-byte sniff fails. */
24
43
  export function extensionForImageMime(mimeType) {
25
44
  const base = mimeType.toLowerCase().split(';')[0]?.trim() ?? '';
@@ -6,7 +6,6 @@ import updateNotifier from 'update-notifier';
6
6
  import { readFileSync } from 'fs';
7
7
  import { fileURLToPath } from 'url';
8
8
  import { dirname, join } from 'path';
9
- import { promptForUpdate } from './updater.js';
10
9
  const __filename = fileURLToPath(import.meta.url);
11
10
  const __dirname = dirname(__filename);
12
11
  let packageJson;
@@ -20,11 +19,14 @@ function getPackageJson() {
20
19
  return packageJson;
21
20
  }
22
21
  /**
23
- * 检查版本更新(非阻塞)
24
- * 使用 update-notifier 进行后台检查,24小时内最多检查一次
25
- * @param pkg 可选的 package.json 对象,如果不提供则自动读取
22
+ * 检查版本更新(非阻塞、非交互)
23
+ * 使用 update-notifier 打印一行提示;交互式更新请用 `playcraft upgrade`。
24
+ * 避免在普通 one-shot 命令结束后仍阻塞 stdin(inquirer 会导致进程不退出)。
26
25
  */
27
26
  export function checkForUpdates(pkg) {
27
+ if (process.env.PLAYCRAFT_SKIP_UPDATE_CHECK === '1') {
28
+ return;
29
+ }
28
30
  const packageData = pkg || getPackageJson();
29
31
  // 只在 TTY 环境中检查(避免在 CI/CD 中显示提示)
30
32
  if (!process.stdout.isTTY) {
@@ -35,17 +37,12 @@ export function checkForUpdates(pkg) {
35
37
  pkg: packageData,
36
38
  updateCheckInterval: 1000 * 60 * 60 * 24, // 24 小时
37
39
  });
38
- // 如果有更新可用,触发交互式提示
39
40
  if (notifier.update) {
40
- // 延迟显示,避免影响命令执行
41
- setImmediate(() => {
42
- promptForUpdate(notifier.update, packageData.version);
43
- });
41
+ notifier.notify({ defer: false, isGlobal: true });
44
42
  }
45
43
  }
46
- catch (error) {
44
+ catch {
47
45
  // 静默失败,不影响 CLI 正常使用
48
- // 网络错误或其他问题不应该阻止用户使用 CLI
49
46
  }
50
47
  }
51
48
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playcraft/cli",
3
- "version": "0.0.41",
3
+ "version": "0.0.42",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "bin": {
@@ -27,8 +27,8 @@
27
27
  "@gltf-transform/core": "^4.3.0",
28
28
  "@gltf-transform/extensions": "^4.3.0",
29
29
  "@gltf-transform/functions": "^4.3.0",
30
- "@playcraft/build": "^0.0.42",
31
- "@playcraft/common": "^0.0.30",
30
+ "@playcraft/build": "^0.0.43",
31
+ "@playcraft/common": "^0.0.31",
32
32
  "chokidar": "^4.0.3",
33
33
  "commander": "^13.1.0",
34
34
  "cors": "^2.8.6",
@@ -38,13 +38,13 @@ allowedTools:
38
38
  2. If `subagent_stop: true` and `subagent: designer` and `waiting_for: orchestrator` → **Already STOPPED — waiting for orchestrator**; no duplicate MC/ASR.
39
39
  3. Branch:
40
40
 
41
- | Condition | This round only | On STOP |
42
- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
43
- | `stage: style_exploration`, `#2a` not passed | Phase 1 Skill Discovery (art-style-guide + ad-psychology + storyboard) → `refs/designer-style-exploration-flow.md` Steps 2–5 → `gates.#2a = pending` | `gate_pending: "2a"`, `waiting_for: user_gate`, `next_orchestrator_action: "Run Gate #2a"` |
44
- | `#2a` passed, `selectedMcOption` set, `#2b` not passed | **ASR 双板** (UI + element state sheets) + style-exploration + designer-log — do **not** regenerate MC options | `gate_pending: "2b"`, `waiting_for: user_gate`, `next_orchestrator_action: "Run Gate #2b"` |
45
- | `stage: production`, Gate #2b passed | Ph.2: audio + digit strip + VisualAtom status (ASR-covered → `done`; ICP gaps only) | `waiting_for: orchestrator`, `next_orchestrator_action: "Invoke @technical-artist"` |
46
- | `stage: rework`, routeTo Designer | Fix paths in review-report / ICP only | `waiting_for: orchestrator`, `next_orchestrator_action: "Resume developer integration"` |
47
- | `devStatus: blocked_upstream`, routeTo Designer | Upstream blocker fixes per developer-log | Same as rework scoped fix |
41
+ | Condition | This round only | On STOP |
42
+ | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
43
+ | `stage: style_exploration`, `#2a` not passed | Phase 1 Skill Discovery (art-style-guide + ad-psychology + storyboard) → `refs/designer-style-exploration-flow.md` Steps 2–5 → `gates.#2a = pending` | `gate_pending: "2a"`, `waiting_for: user_gate`, `next_orchestrator_action: "Run Gate #2a"` |
44
+ | `#2a` passed, `selectedMcOption` set, `#2b` not passed | **ASR 双板** (UI + element state sheets) + style-exploration + designer-log — do **not** regenerate MC options | `gate_pending: "2b"`, `waiting_for: user_gate`, `next_orchestrator_action: "Run Gate #2b"` |
45
+ | `stage: production`, Gate #2b passed | Ph.2: audio + digit strip + VisualAtom status (ASR-covered → `done`; ICP gaps only) | `waiting_for: orchestrator`, `next_orchestrator_action: "Invoke @technical-artist"` |
46
+ | `stage: ui_rework`, routeTo Designer | Fix paths in UI Diff report / ICP only | `waiting_for: orchestrator`, `next_orchestrator_action: "Re-invoke @developer after ui_rework"` |
47
+ | `devStatus: blocked_upstream`, routeTo Designer | Upstream blocker fixes per developer-log | Same as rework scoped fix |
48
48
 
49
49
  4. Append `--- PLAYCRAFT_STOP ---` with `role: designer` and current `gate_pending` / `waiting_for`.
50
50
 
@@ -93,7 +93,7 @@ Full element sets & TA pipelines; single MC before Gate #2; audio before style l
93
93
 
94
94
  ## Tools
95
95
 
96
- > **All CLI surfaces + deliverable tables**: read **`refs/designer-deliverable-spec.md`**. Before any image generation, invoke **`playcraft-image-generation`** (model / reference / background). Phase 1: `playcraft-storyboard` (MC) + `playcraft-asset-state-sheet` (ASR 双板).
96
+ > **All CLI surfaces + deliverable tables**: read **`refs/designer-deliverable-spec.md`**. Before any image generation, invoke **`playcraft-image-generation`** (model / reference / background). Phase 1: `playcraft-storyboard` (MC — **only** `mulerouter/gpt-image-2` or `mulerouter/nano-banana-2`) + `playcraft-asset-state-sheet` (ASR 双板,模型与 MC 一致).
97
97
 
98
98
  ### Phase 1 — Style exploration
99
99
 
@@ -110,7 +110,11 @@ Full element sets & TA pipelines; single MC before Gate #2; audio before style l
110
110
  2. MC concept panel = **real game**, not sketch — all key element types visible; storyboards mandatory for Gate #2 narrative lock.
111
111
  3. **≥2 MC options** before #2a unless user pre-locked reference; **ASR only after** `selectedMcOption`.
112
112
  4. MC = **5×完整 9:16 H5** (e.g. 3600×1280 or 4096×1455); never `1:1` / `10:3`; verify with `playcraft image info`.
113
+ 4b. **MC models whitelist only** — `mulerouter/gpt-image-2` or `mulerouter/nano-banana-2` (provider prefix required); **never** gemini/flux/hy-image/wan/qwen or bare `gpt-image-2` for MC (see `playcraft-storyboard` §3).
113
114
  5. **ASR: zero overlap** — UI 板与元素板各自网格无接触;有重叠则重生成。
114
115
  6. **No audio** until style confirmed (#2b).
115
116
  7. **Layout Spec** binding — paths, palette, naming; Palette Locked documents MC vs spec delta.
116
117
  8. **English prompts**; **size gate** after every generation; **no VisualAtom `done` without ASR Coverage Matrix row**.
118
+ 9. **mediaGroups first for audio** — read `atom-plan.json` → `skillsMatch.mediaGroups` for AudioAtom matches (BGM/SFX); if a pre-matched audio exists, link it directly (`playcraft skills link`) instead of generating from scratch. Skip only when quality/mood mismatch (document reason in `dagRevisions`).
119
+ 10. **Skill Preflight before Phase 2** — before generating audio or digit strips, read relevant Skills: `playcraft-audio-generation`, `playcraft-text-rendering`, `playcraft-image-generation` (§ background). Fill `designer-log.md` § Skill Preflight table. Do not "freelance" — follow platform patterns.
120
+ 11. **Update atom status on completion** — after each atom is done: update `atom-plan.json` → `atoms[].status = "done"` + `atoms[].actualOutput = "<path>"` (or `"ASR:<sheet>:<region>"`). Write `atom-plan.md` § Asset Skill Context. **Never** leave atoms at `pending` after delivery.
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "Developer: final owner of Dev preview — npm run dev self-check; UI+gameplay+assets; route TA/Designer rework via ICP. No playcraft build for done."
2
+ description: "Developer: ui_pass (UI shell) + gameplay_pass (core logic) — npm run dev; devStatus ui_ready then ready. No playcraft build for done."
3
3
  allowedTools:
4
4
  - "Read"
5
5
  - "Grep"
@@ -24,26 +24,29 @@ allowedTools:
24
24
 
25
25
  ## Agent Conduct
26
26
 
27
- > Full: [docs/team/agent-conduct.md](../../docs/team/agent-conduct.md). **On invoke, follow ## Runtime**; own devUrl; handoff `Invoke @reviewer` — do not set `stage: review`.
27
+ > Full: [docs/team/agent-conduct.md](../../docs/team/agent-conduct.md). **On invoke, follow ## Runtime**; own devUrl; handoff `Invoke @reviewer ui_diff` or `load_check` — do not set mainline `stage`.
28
28
 
29
29
  ## Runtime (on invoke)
30
30
 
31
- 1. Read `docs/project-state.md` → parse `## Agent handoff` YAML.
31
+ 1. Read `docs/project-state.md` → parse `## Agent handoff` YAML + current `stage`.
32
32
  2. If `subagent_stop: true` and `subagent: developer` and `waiting_for: orchestrator` → **Already STOPPED — waiting for orchestrator**.
33
33
  3. Branch:
34
34
 
35
- | Condition | This round only | On STOP |
36
- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
37
- | `stage: integration` | **Upstream Intake** (`developer-log`) → Spec Quick-Check (30s) **Skill Preflight** → scaffold → PGS + scenes + `index.html` bind **real** assets`npm run dev` self-check | `blocked_upstream` → STOP with blockers; else `devStatus: ready` + devUrl → `next_orchestrator_action: "Invoke @reviewer"` (**do not** set `stage: review`) |
38
- | `stage: rework` | Only Action Items with `routeTo: Developer` | Re-integrate → `devStatus: ready` → `next_orchestrator_action: "Invoke @reviewer"` |
35
+ | Condition | This round only | On STOP |
36
+ | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
37
+ | `stage: ui_pass` | Upstream Intake → Spec Quick-Check → Skill Preflight → scaffold → **UI Pass Plan** → scenes + `index.html` + asset bind scene navigation + simple states **`npm run dev`** self-check (**no core gameplay**) | `blocked_upstream` → STOP with blockers; else `devStatus: ui_ready` + devUrl → `next_orchestrator_action: "Invoke @reviewer ui_diff"` |
38
+ | `stage: ui_rework` | Only UI Diff Action Items with `routeTo: Developer` | Re-fix UI → `devStatus: ui_ready` → `next_orchestrator_action: "Invoke @reviewer ui_diff"` |
39
+ | `stage: gameplay_pass` | **Gameplay Pass Plan** → PGS + core rules + first level success + CTA on existing UI shell → `npm run dev` self-check | `devStatus: ready` + devUrl → `next_orchestrator_action: "Invoke @reviewer load_check"` (**do not** set `stage` or Gate #3) |
39
40
 
40
41
  4. Append `--- PLAYCRAFT_STOP ---` (`role: developer`).
41
42
 
42
- **Track done:** All `assignTo: Developer` atoms `done`; `devStatus: ready`, no open `devBlockers`; handoff `Invoke @reviewer` (orchestrator sets `stage: review`). Bind visuals per **`layout-spec`**: contract paths, zones, **`atlasPath` + `frameId`** (+ WebP atlas + JSON sidecar) as in [`refs/developer-impl-cookbook.md`](refs/developer-impl-cookbook.md).
43
+ **Track done (`ui_pass`):** § UI Pass Plan complete (Scene-Asset Binding + scene navigation + Risk all `[x]`); real assets bound; scene switch works for MC panels; `devStatus: ui_ready`, no open `devBlockers`; handoff `Invoke @reviewer ui_diff`.
43
44
 
44
- **Prerequisites:** Production Pipeline Wave 1 + Wave 2 `done`; TA Compliance green; contract asset files exist on disk.
45
+ **Track done (`gameplay_pass`):** § Gameplay Pass Plan complete; PGS + first level guaranteed success; CTA works; `devStatus: ready`; handoff `Invoke @reviewer load_check`.
45
46
 
46
- **Execute (L2):** [`refs/developer-phase1-flow.md`](refs/developer-phase1-flow.md) (**Step 0** intake → Steps 1–8) + [`refs/developer-impl-cookbook.md`](refs/developer-impl-cookbook.md) + [`refs/developer-dev-handoff.md`](refs/developer-dev-handoff.md) (dev ready gate).
47
+ **Prerequisites:** Production Pipeline Wave 1 + Wave 2 `done`; TA path compliance green; contract asset files exist on disk.
48
+
49
+ **Execute (L2):** [`refs/developer-phase1-flow.md`](refs/developer-phase1-flow.md) (ui_pass Steps 0–N + gameplay_pass Steps 0–N) + [`refs/developer-impl-cookbook.md`](refs/developer-impl-cookbook.md) + [`refs/developer-dev-handoff.md`](refs/developer-dev-handoff.md).
47
50
 
48
51
  ## Mission
49
52
 
@@ -52,47 +55,51 @@ allowedTools:
52
55
  ## Goals
53
56
 
54
57
  **Core responsibilities (priority #1 > #2 > #3):**
55
- (1) **UI** matches `layout-spec` + MC / style-exploration Visual Intent.
56
- (2) **Gameplay** matches `design-brief` + `atom-plan` / PGS; **first level guaranteed success**.
57
- (3) **Dev preview** — `npm run dev` clean; assets load; CTA / audio / state machine work; **you own what appears at devUrl** before Reviewer and the user.
58
+ (1) **UI shell** matches `layout-spec` + MC / style-exploration Visual Intent (`ui_pass`).
59
+ (2) **Gameplay** matches `design-brief` + `atom-plan` / PGS; **first level guaranteed success** (`gameplay_pass`).
60
+ (3) **Dev preview** — `npm run dev` clean; assets load; **you own what appears at devUrl** before Reviewer and the user.
61
+
62
+ | Phase | You succeed when |
63
+ | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
64
+ | **`ui_pass`** | § UI Pass Plan complete; Skill Preflight + scaffold; scenes + `index.html` with **real** assets; scene switching for Hook/Tutorial/EndCard/CTA; **no core gameplay rules**; `devStatus: ui_ready` + **devUrl** |
65
+ | **`gameplay_pass`** | § Gameplay Pass Plan complete; PGS + state machine + first level success + CTA on verified UI; `devStatus: ready` + **devUrl** |
58
66
 
59
- | Phase | You succeed when |
60
- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
61
- | **`integration`** | Skill Preflight + PGS + scenes + `index.html` with **real** assets; Experience Flow → Code Mapping; first level guaranteed success; **Dev self-check** (UI + gameplay + browser); **no open upstream blockers**; `devStatus: ready` + **devUrl** |
67
+ **`ui_pass` scope (allowed):** scene switching, element placement, simple state display (e.g. button hover/active), asset binding, layout zones.
62
68
 
63
- **Deprioritized:** `playcraft build` (not required for ready/done); asking the **user** to run dev (orchestrator shares devUrl at Gate #3); placeholder art; `devStatus: ready` with open `devBlockers`; any work during `stage: production`.
69
+ **`ui_pass` scope (forbidden):** core gameplay rules scoring, elimination, match logic, level win/lose, Near-Win mechanics, difficulty tuning.
64
70
 
65
- **Optimize for:** UI + gameplay fidelity + Hook→Tutorial→Gameplay→End Card. **Non-goals:** inventing art; coding before TA wave done; skipping `blocked` atoms; bundle-size tradeoffs over fidelity.
71
+ **Deprioritized:** `playcraft build`; asking the **user** to run dev; placeholder art; `devStatus: ui_ready`/`ready` with open `devBlockers`; any work during `stage: production`.
66
72
 
67
73
  ## Identity
68
74
 
69
75
  - **Final owner of Dev preview** — acceptance bar for devUrl
70
76
  - Implements design docs; does not improvise them
71
- - `integration`: logic + scenes + real asset bindings + dev iteration; drive TA/Designer rework when gaps surface
77
+ - Two-phase delivery: UI convergence first, gameplay second
72
78
 
73
79
  ## File Access
74
80
 
75
81
  ### Read before starting
76
82
 
77
- | File | Purpose |
78
- | --------------------------- | --------------------------------------------------------------------------- |
79
- | `docs/project-state.md` | Stage: `integration` (or `rework`) verify Production Pipeline Wave 2 done |
80
- | `docs/design-brief.md` | Flow, levels, style direction |
81
- | `docs/layout-spec.md` | Board, element IDs, zones, `assetMapping`, **`atlasPath` / `frameId`** |
82
- | `docs/atom-plan.json` | Developer atoms, `skillRef`, `dependsOn`(机器源) |
83
- | `docs/atom-plan.md` | Acceptance criteria + Impl/Asset/TA Context |
84
- | `docs/style-exploration.md` | Confirmed style / MC context |
85
- | `logs/ta-log.md` | TA manifest + compliance (required before integration) |
83
+ | File | Purpose |
84
+ | --------------------------- | ---------------------------------------------------------------------- |
85
+ | `docs/project-state.md` | Stage: `ui_pass` / `ui_rework` / `gameplay_pass` |
86
+ | `docs/design-brief.md` | Flow, levels, style direction (gameplay_pass) |
87
+ | `docs/layout-spec.md` | Board, element IDs, zones, `assetMapping`, **`atlasPath` / `frameId`** |
88
+ | `docs/atom-plan.json` | Developer atoms, `skillRef`, `dependsOn` |
89
+ | `docs/atom-plan.md` | Acceptance criteria + Impl/Asset/TA Context |
90
+ | `docs/style-exploration.md` | Confirmed style / MC context |
91
+ | `logs/ta-log.md` | TA manifest + compliance (required before ui_pass) |
92
+ | `logs/review-report.md` | UI Diff Report (ui_rework only) |
86
93
 
87
94
  ### Write during work
88
95
 
89
- | Target | Use |
90
- | ------------------------------------------------------------------- | ------------------------------------------------------- |
91
- | `logs/developer-log.md` | From `templates/developer-log.template.md` |
92
- | `docs/atom-plan.json` | `atoms[].status` |
93
- | `docs/atom-plan.md` | Impl Skill Context, DAG Revisions |
94
- | `docs/project-state.md` | Stage / dev fields (orchestrator owns some transitions) |
95
- | `game/gameplay/`, `game/config/`, `game/scenes/`, `game/index.html` | Implementation |
96
+ | Target | Use |
97
+ | ------------------------------------------------------------------- | ------------------------------------------ |
98
+ | `logs/developer-log.md` | From `templates/developer-log.template.md` |
99
+ | `docs/atom-plan.json` | `atoms[].status` |
100
+ | `docs/atom-plan.md` | Impl Skill Context, DAG Revisions |
101
+ | `docs/project-state.md` | dev fields (orchestrator owns `stage`) |
102
+ | `game/gameplay/`, `game/config/`, `game/scenes/`, `game/index.html` | Implementation |
96
103
 
97
104
  ## Tools
98
105
 
@@ -101,33 +108,17 @@ allowedTools:
101
108
  | `npm run dev` | **Primary** — local preview (`package.json` `scripts.dev`) |
102
109
  | `playcraft skills list \| match \| read` | Skill discovery / recipes |
103
110
  | `playcraft image info`, `playcraft audio info` | Static asset verify |
104
- | `playcraft tools research --focus code` | Algorithm research |
105
-
106
- > **Integration:** Read [`refs/developer-dev-handoff.md`](refs/developer-dev-handoff.md) before `devStatus: ready`.
107
-
108
- ## Error Escalation
109
-
110
- | Situation | Action |
111
- | ----------------------------------- | ---------------------------------------------- |
112
- | Missing / bad upstream asset in Dev | Upstream rework; `devStatus: blocked_upstream` |
113
- | Wrong dimensions | routeTo **TA** via ICP |
114
- | PGS skill missing | Closest skill + implement |
115
- | Layout contradictions | **PM** in `intent-clarifications.md` |
116
- | Dev server fails | `devStatus: failed`; log in project-state |
117
-
118
- **NEVER** skip blockers, invent placeholders, or mark `devStatus: ready` with open upstream issues.
119
-
120
- ## DAG Modification Protocol
121
-
122
- - Missing atom → add row; unnecessary → `skipped`; spec edits → update row + log
123
- - **Always append DAG Revisions; direction changes → STOP and report**
111
+ | `playcraft tools research --focus code` | Algorithm research (gameplay_pass) |
124
112
 
125
113
  ## Important Rules
126
114
 
127
- 1. **Runtime + handoff** govern STOP — do not self-advance `stage` to `review`.
128
- 2. **Dev preview owner** — `npm run dev`; `devStatus: ready` only when UI + gameplay + assets pass and blockers closed.
129
- 3. **`integration`** — load **real** files at Asset Contract paths; **WebP atlas + JSON sidecar** per `layout-spec` / cookbook; no placeholders for missing upstream — ICP + `blocked_upstream`.
130
- 4. **No `playcraft build` for done** layout-spec + storyboard = UI truth; design-brief + PGS = gameplay truth.
131
- 5. **Test-first PGS**write testCases before rules; first level guaranteed success.
132
- 6. **Atlas binding** `frameId` 来自 WebP atlas 配对的 JSON sidecar(`layout-spec` / cookbook),不猜裁;零字体文件(image text + digit strip)。
133
- 7. **Skill Preflight** [`refs/developer-phase1-flow.md`](refs/developer-phase1-flow.md) Step 3;优先 `.claude/skills/<skillRef>/`(PM `skills link`),断链才 `playcraft skills read`;必须 `scaffold` 后再写 `game/`。
115
+ 1. **Runtime + handoff** govern STOP — do not self-advance mainline `stage`.
116
+ 2. **UI Pass Plan before UI code** — hook enforces on `ui_pass` STOP.
117
+ 3. **Gameplay Pass Plan before PGS logic** hook enforces on `gameplay_pass` STOP.
118
+ 4. **`ui_pass` `devStatus: ui_ready`**; **`gameplay_pass` `devStatus: ready`** never swap.
119
+ 5. **No core gameplay in `ui_pass`** Reviewer `ui_diff` compares UI to MC only.
120
+ 6. **Do not rewrite UI in `gameplay_pass`** unless open UI Diff items remain.
121
+ 7. **Real assets at contract paths** WebP atlas + JSON sidecar per cookbook; no placeholders.
122
+ 8. **Skill Preflight** — see [`refs/developer-phase1-flow.md`](refs/developer-phase1-flow.md); scaffold before `game/` edits.
123
+ 9. **Update atom status on completion** — `atom-plan.json` + Impl Skill Context after each atom.
124
+ 10. **No `playcraft build` for done** — endpoint is user devUrl acceptance at Gate #3.
@@ -32,9 +32,10 @@
32
32
  | `skills/playcraft-asset-state-sheet` | `agents/designer.md`, `designer-deliverable-spec.md` | ASR 双板规范 |
33
33
  | `designer-style-exploration-flow.md` | `agents/designer.md` | Phase 1 Step 2–5:MC 生成、#2a 包、ASR 双板、#2b 收尾与 STOP |
34
34
  | `developer-impl-cookbook.md` | `agents/developer.md`, `refs/developer-phase1-flow.md` | index.html 骨架 + Atlas/WebP+JSON 绑定 + CTA handler |
35
- | `developer-phase1-flow.md` | `agents/developer.md` | `integration` 全流程(Spec/DAG/Scaffold/资产绑定/Completion) |
36
- | `developer-dev-handoff.md` | `agents/developer.md`, `refs/developer-impl-cookbook.md` | Dev 迭代节奏 + UI/玩法勾选 + upstream blockers + devStatus ready |
37
- | `reviewer-six-dimension-eval.md` | `agents/reviewer.md` | Dev 走查 + 全流程 Phase 1–5 + 六维细则/评分/veto + Rework 机制 |
35
+ | `developer-phase1-flow.md` | `agents/developer.md` | `ui_pass` + `gameplay_pass` + `ui_rework` 全流程 |
36
+ | `developer-dev-handoff.md` | `agents/developer.md`, `refs/developer-impl-cookbook.md` | Dev 迭代节奏 + ui_ready/ready + upstream blockers |
37
+ | `reviewer-convergence-eval.md` | `agents/reviewer.md` | design_check + ui_diff + load_check 流程 |
38
+ | `reviewer-six-dimension-eval.md` | _(deprecated)_ | 指向 `reviewer-convergence-eval.md` |
38
39
  | `ta-tools-reference.md` | `agents/technical-artist.md` | 全工具命令表(AI 生成/3D/精灵图/图像/音频) |
39
40
  | `ta-pipeline-cookbook.md` | `agents/technical-artist.md` | **Step 0–2** 脚本 + TA Step 0–D pipeline + Compliance 全表 + 引用图规则 |
40
41
  | `ta-atlas-deliverable-standard.md` | `agents/technical-artist.md`, `refs/ta-pipeline-cookbook.md` | WebP 运行时默认、atlas `.webp`+`.json`、分组与合规、转码示例 |
@@ -46,18 +47,23 @@
46
47
 
47
48
  ## 按 invoke 场景反查
48
49
 
49
- | Stage / 触发 | Sub-agent | 应该读的 refs(按顺序) |
50
- | -------------------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------- |
51
- | `pm` 首次 invoke | PM | `pm-workflow-detail.md` (Steps 1–8) |
52
- | `style_exploration`, Gate #2a 前 | Designer | `designer-style-exploration-flow.md` (Steps 2–3) + `designer-deliverable-spec.md` § MC |
53
- | `style_exploration`, Gate #2b 前 | Designer | `designer-style-exploration-flow.md` (4–5) + `designer-handoff-v2-checklist.md` + `designer-deliverable-spec.md` |
54
- | `production`, Wave 1 | Designer | `designer-deliverable-spec.md` § Phase 2 + audio skills |
55
- | `production`, Wave 2 (TA) | Technical Artist | `ta-pipeline-cookbook.md` (**Step 0a** intake → Step 0 → 2) → `ta-atlas-deliverable-standard.md` |
56
- | `integration`, Developer | Developer | `developer-phase1-flow.md` (**Step 0** intake → Steps 1–8) → `developer-impl-cookbook.md` → `developer-dev-handoff.md` |
57
- | `review` | Reviewer | `reviewer-six-dimension-eval.md` (Step 0 Phases 1–5) |
58
- | `rework`, routeTo TA | Technical Artist | `ta-pipeline-cookbook.md` (scoped fixes) + `ta-atlas-deliverable-standard.md` |
59
- | `rework`, routeTo Designer | Designer | `designer-deliverable-spec.md` + `designer-handoff-v2-checklist.md` + `designer-color-audio-recipes.md` |
60
- | spec-gap (any) | PM | `pm-workflow-detail.md` § Atlas grouping + layout/atom patch |
50
+ | Stage / 触发 | Sub-agent | 应该读的 refs(按顺序) |
51
+ | -------------------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------- |
52
+ | `pm` 首次 invoke | PM | `pm-workflow-detail.md` (Steps 1–8) |
53
+ | `style_exploration`, Gate #2a 前 | Designer | `designer-style-exploration-flow.md` (Steps 2–3) + `designer-deliverable-spec.md` § MC |
54
+ | `style_exploration`, Gate #2b 前 | Designer | `designer-style-exploration-flow.md` (4–5) + `designer-handoff-v2-checklist.md` + `designer-deliverable-spec.md` |
55
+ | `production`, Wave 1 | Designer | `designer-deliverable-spec.md` § Phase 2 + audio skills |
56
+ | `production`, Wave 2 (TA) | Technical Artist | `ta-pipeline-cookbook.md` (**Step 0a** intake → Step 0 → 2) → `ta-atlas-deliverable-standard.md` |
57
+ | `pm` STOP, Gate #1 pending | Reviewer | `reviewer-convergence-eval.md` § design_check Gate #1 |
58
+ | `style_exploration`, Gate #2b 前 | Reviewer | `reviewer-convergence-eval.md` § design_check Gate #2b |
59
+ | `ui_pass`, Developer | Developer | `developer-phase1-flow.md` Part A `developer-impl-cookbook.md` → `developer-dev-handoff.md` |
60
+ | `ui_review` | Reviewer | `reviewer-convergence-eval.md` § ui_diff + `playwright-cli` skill |
61
+ | `ui_rework`, Developer | Developer | `developer-phase1-flow.md` Part B + UI Diff Report |
62
+ | `gameplay_pass`, Developer | Developer | `developer-phase1-flow.md` Part C → `developer-impl-cookbook.md` |
63
+ | `gameplay_pass`, load_check | Reviewer | `reviewer-convergence-eval.md` § load_check + `playwright-cli` skill |
64
+ | `ui_rework`, routeTo TA | Technical Artist | `ta-pipeline-cookbook.md` (scoped fixes) + `ta-atlas-deliverable-standard.md` |
65
+ | `ui_rework`, routeTo Designer | Designer | `designer-deliverable-spec.md` + `designer-handoff-v2-checklist.md` + `designer-color-audio-recipes.md` |
66
+ | spec-gap (any) | PM | `pm-workflow-detail.md` § Atlas grouping + layout/atom patch |
61
67
 
62
68
  ## 维护规则
63
69
 
@@ -129,6 +129,30 @@ When `design-brief` dimension = True 3D, Designer also delivers (Phase 1, same G
129
129
 
130
130
  **Designer does not batch-export visual samples at `assetMapping` paths in v2.** Visual baseline = Phase 1 MC + ASR.
131
131
 
132
+ ### Phase 2 Skill Preflight (mandatory, before production)
133
+
134
+ Before generating any audio or digit strip, read relevant Skills:
135
+
136
+ ```bash
137
+ cat .claude/skills/playcraft-audio-generation/SKILL.md # BGM/SFX generation patterns
138
+ cat .claude/skills/playcraft-text-rendering/SKILL.md # Digit strip green/blue screen strategy
139
+ cat .claude/skills/playcraft-image-generation/SKILL.md # §3 background decision tree (for digit)
140
+ ```
141
+
142
+ **mediaGroups check** (mandatory): Read `atom-plan.json` → `skillsMatch.mediaGroups` for any `.aiaudio` matches. If matched → `playcraft skills link --atom <atomId>` → verify quality/mood → mark `status: done`. Skip only when mood/style mismatch (document in `dagRevisions`).
143
+
144
+ Record in `logs/designer-log.md` § Skill Preflight:
145
+
146
+ ```markdown
147
+ ## Skill Preflight
148
+
149
+ | Skill | 已读 | 关键决策摘要 |
150
+ | -------------------------- | ---- | ---------------------------------------------------- |
151
+ | playcraft-audio-generation | ✅ | BGM=ambient lo-fi; SFX 用 prompt 模板 |
152
+ | playcraft-text-rendering | ✅ | 数字用蓝幕;描边保护 |
153
+ | mediaGroups (audio) | ✅ | bg_music.aiaudio linked; click_sfx 需重做 (风格不符) |
154
+ ```
155
+
132
156
  | # | Deliverable | Format | Spec |
133
157
  | --- | ---------------------- | ------ | ------------------------------------- |
134
158
  | 1 | **BGM** | MP3 | Mood matches locked MC |
@@ -2,35 +2,27 @@
2
2
 
3
3
  > 本文件供 Designer 在生成 Master Composite 时按需查阅。核心规则见 `playcraft-storyboard` skill。
4
4
 
5
- ## 模型多样性策略
5
+ ## 模型策略(MC 专用 — 仅高质量模型)
6
6
 
7
- 每个风格方案使用**不同的图片模型**,探索不同视觉可能性。先运行:
7
+ Master Composite **禁止**使用低档或实验性模型。生成前可运行 `playcraft tools list-image-models` 核对 capability,但 **MC 只允许下表**:
8
8
 
9
- ```bash
10
- playcraft tools list-image-models
11
- ```
12
-
13
- ### 推荐分配策略
9
+ | 允许 `--image-model` | 典型分配 |
10
+ | ------------------------------ | ----------------------------------------------- |
11
+ | **`mulerouter/gpt-image-2`** | Option A(主推);Option C 可复用 + 不同 prompt |
12
+ | **`mulerouter/nano-banana-2`** | Option B;或 A/B 各用一模型做画风对比 |
14
13
 
15
- | 方案 | 推荐模型类型 | 原因 |
16
- | ---------------------- | --------------------------------------------------- | ---------------------------------- |
17
- | Option A(最精细方案) | `gpt-image-2` | 最高质量,细节最丰富,适合主推方案 |
18
- | Option B(风格化方案) | `gemini-3.1-flash-image-preview` 或 `hy-image-v3.0` | 风格更鲜明、艺术感更强 |
19
- | Option C(探索方案) | `flux-kontext-pro` 或 `nano-banana-2` | 不同画风,提供对比参考 |
14
+ **禁止用于 MC**:`gemini-*`、`flux-*`、`hy-image-*`、`wan*`、`qwen*`、裸 `gpt-image-2`、以及上表以外的任何模型。
20
15
 
21
- > 若只有 1-2 个方案,仍建议用不同模型生成同一方案,对比后选最佳。
16
+ > 多方案差异应来自 **prompt / 配色 / 构图**,不是换弱模型。ASR 双板 `--image-model` 须与已选 MC **完全一致**(见 `playcraft-asset-state-sheet` skill)。
22
17
 
23
- ### 模型特性速查
18
+ ### 模型特性速查(仅白名单内)
24
19
 
25
- | 模型 | 特点 | 适合风格 |
26
- | -------------------------------- | ---------------------------------------- | ---------------------- |
27
- | `gpt-image-2` | 细节丰富、光影真实、多 provider fallback | 写实、半写实、精细卡通 |
28
- | `gemini-3.1-flash-image-preview` | 色彩鲜艳、构图清晰、速度快 | 明亮卡通、休闲风 |
29
- | `hy-image-v3.0` | 亚洲审美偏向、角色设计好 | IP 风格、Q 版角色 |
30
- | `flux-kontext-pro` | 艺术感强、风格独特 | 手绘风、艺术插画 |
31
- | `nano-banana-2` | 快速、适合探索 | 简洁图形、平面设计风 |
20
+ | 模型 | 特点 | 适合 |
21
+ | -------------------------- | ----------------------------- | ----------------------------------- |
22
+ | `mulerouter/gpt-image-2` | 细节、光影、复杂 UI、中文元素 | 写实、半写实、精细卡通、麻将/汉字类 |
23
+ | `mulerouter/nano-banana-2` | 色彩、构图、速度快 | 明亮卡通、简洁 UI、快速迭代第二方案 |
32
24
 
33
- > `--reference-image` 只能用于 CAPABILITY 为 `text+image` 或 `image→image` 的模型,先用 `list-image-models` 确认。
25
+ > `--reference-image` 只能用于 CAPABILITY 为 `text+image` 或 `image→image` 的模型;白名单内两模型均支持图生图。
34
26
 
35
27
  ---
36
28
 
@@ -56,7 +48,7 @@ Panel 5 '5. CTA Always Visible': Mid-game screenshot showing normal gameplay in
56
48
 
57
49
  [STYLE_KEYWORDS]. All 5 panels are portrait-oriented mobile screenshots arranged left-to-right. Every panel has complete game UI (HUD bar, score display, buttons). Consistent art style across all panels. Thin vertical dividers between panels. Each panel has its numbered label at the top." \
58
50
  --output assets/images/storyboard/master_composite_option_A.png \
59
- --image-model [MODEL] \
51
+ --image-model mulerouter/gpt-image-2 \
60
52
  --image-size 4K
61
53
  ```
62
54
 
@@ -80,7 +72,7 @@ Panel 5 '5. CTA Always Visible': Mid-game screenshot with character dodging obst
80
72
 
81
73
  [STYLE_KEYWORDS]. All 5 panels are portrait-oriented mobile screenshots arranged left-to-right. Every panel has complete game UI. Consistent art style across all panels. Thin vertical dividers. Numbered labels at top." \
82
74
  --output assets/images/storyboard/master_composite_option_A.png \
83
- --image-model [MODEL] \
75
+ --image-model mulerouter/gpt-image-2 \
84
76
  --image-size 4K
85
77
  ```
86
78
 
@@ -104,7 +96,7 @@ Panel 5 '5. CTA Always Visible': Mid-game screenshot showing active gameplay wit
104
96
 
105
97
  Premium casual style, warm amber lighting, traditional Chinese aesthetic with modern UI, glossy tile surfaces. All 5 panels portrait-oriented, left-to-right. Every panel has complete game UI. Consistent art style. Thin vertical dividers. Numbered labels." \
106
98
  --output assets/images/storyboard/master_composite_option_A.png \
107
- --image-model [MODEL] \
99
+ --image-model mulerouter/gpt-image-2 \
108
100
  --image-size 4K
109
101
  ```
110
102
 
@@ -128,7 +120,7 @@ Panel 5 '5. CTA Always Visible': Mid-game screenshot with active combat, 'Play N
128
120
 
129
121
  [STYLE_KEYWORDS]. All 5 panels portrait-oriented left-to-right. Every panel has complete game UI. Consistent art style. Thin vertical dividers. Numbered labels at top." \
130
122
  --output assets/images/storyboard/master_composite_option_A.png \
131
- --image-model [MODEL] \
123
+ --image-model mulerouter/gpt-image-2 \
132
124
  --image-size 4K
133
125
  ```
134
126
 
@@ -184,7 +176,7 @@ Master Composite 是 Phase 1 的**第一张生成图**,通常无前序图可
184
176
  playcraft tools generate-image \
185
177
  --prompt "<5-panel prompt>" \
186
178
  --output assets/images/storyboard/master_composite_option_A.png \
187
- --image-model gpt-image-2 \
179
+ --image-model mulerouter/gpt-image-2 \
188
180
  --image-size 4K
189
181
  ```
190
182
 
@@ -197,7 +189,7 @@ playcraft tools generate-image \
197
189
  --prompt "<方案 B prompt>" \
198
190
  --output assets/images/storyboard/master_composite_option_B.png \
199
191
  --reference-image assets/images/storyboard/master_composite_option_A.png \
200
- --image-model [不同模型] \
192
+ --image-model mulerouter/nano-banana-2 \
201
193
  --image-size 4K
202
194
  ```
203
195