@playcraft/cli 0.0.53 → 0.0.56
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/README.md +21 -0
- package/REMIX.md +103 -19
- package/dist/atom-tree/fusion-hints.js +8 -3
- package/dist/atom-tree/fusion-intent.js +62 -0
- package/dist/atom-tree/selection.js +3 -1
- package/dist/commands/create.js +439 -159
- package/dist/commands/image.js +79 -69
- package/dist/commands/levels.js +29 -0
- package/dist/commands/patterns.js +75 -0
- package/dist/commands/remix.js +47 -0
- package/dist/commands/skills.js +48 -17
- package/dist/index.js +13 -6
- package/dist/remix/clone-source.js +208 -0
- package/dist/remix/clone.js +255 -0
- package/dist/scaffold/templates.js +35 -0
- package/dist/utils/agent-api-client.js +10 -3
- package/dist/utils/remix-image-attachments.js +4 -32
- package/dist/utils/sandbox-path.js +20 -0
- package/package.json +3 -3
- package/project-template/.claude/agents/creative-director.md +114 -0
- package/project-template/.claude/agents/developer.md +5 -2
- package/project-template/.claude/agents/game-designer.md +41 -20
- package/project-template/.claude/agents/refs/README.md +8 -0
- package/project-template/.claude/agents/refs/creative-director-guide.md +35 -0
- package/project-template/.claude/agents/refs/creative-director-kickoff-guide.md +52 -0
- package/project-template/.claude/agents/refs/creative-discovery-guide.md +76 -0
- package/project-template/.claude/agents/refs/creative-north-star-examples.md +82 -0
- package/project-template/.claude/agents/refs/developer-dev-handoff.md +1 -1
- package/project-template/.claude/agents/refs/game-designer-fusion-depth-playbook.md +28 -0
- package/project-template/.claude/agents/refs/game-designer-gameplay-sufficiency.md +4 -4
- package/project-template/.claude/agents/reviewer.md +11 -0
- package/project-template/.claude/hooks/README.md +12 -12
- package/project-template/.claude/hooks/block-developer-preflight.mjs +49 -13
- package/project-template/.claude/hooks/block-ring1-tasklist.mjs +1 -1
- package/project-template/.claude/hooks/user-prompt.mjs +3 -13
- package/project-template/.claude/hooks/validate-workflow-stop.mjs +209 -12
- package/project-template/.claude/settings.json +2 -2
- package/project-template/.claude/skills/playcraft-playable-optimization/SKILL.md +20 -20
- package/project-template/.claude/skills/session-analyzer/scripts/resolve-session.mjs +0 -1
- package/project-template/.claude/snapshot.mjs +0 -1
- package/project-template/.codebuddy/settings.json +1 -1
- package/project-template/.cursor/rules/playcraft-orchestrator.mdc +1 -1
- package/project-template/CLAUDE.md +9 -9
- package/project-template/docs/project-state.md +1 -1
- package/project-template/docs/team/agent-conduct.md +18 -18
- package/project-template/docs/team/collaboration.md +19 -7
- package/project-template/docs/team/workflow-changelog.md +15 -0
- package/project-template/fusion-patterns/catalog.json +77 -0
- package/project-template/package.json +2 -0
- package/project-template/skills/_shared/scripts/create-playable.mjs +31 -11
- package/project-template/skills/_shared/scripts/dev-start.mjs +3 -3
- package/project-template/skills/_shared/scripts/disclosure-config.mjs +65 -39
- package/project-template/skills/_shared/scripts/harness-smoke.mjs +3 -1
- package/project-template/skills/_shared/scripts/lib/fusion-intent.mjs +88 -0
- package/project-template/skills/_shared/scripts/lib/skill-fidelity.mjs +185 -0
- package/project-template/skills/_shared/scripts/slice-set.mjs +29 -2
- package/project-template/skills/_shared/scripts/state-get.mjs +124 -7
- package/project-template/skills/_shared/scripts/state-store.mjs +25 -2
- package/project-template/skills/_shared/scripts/validate-level-sketch.mjs +444 -0
- package/project-template/skills/_shared/scripts/verify-design-consistency.mjs +728 -0
- package/project-template/skills/playable-record/scripts/lib/dev-server.mjs +46 -11
- package/project-template/skills/playable-record/scripts/record-playable.mjs +2 -1
- package/project-template/skills/playable-record/scripts/verify-contract.mjs +4 -4
- package/project-template/skills/playable-record/scripts/verify-firstwin.mjs +3 -3
- package/project-template/skills/playable-record/scripts/verify-fusion.mjs +37 -2
- package/project-template/skills/playable-record/scripts/verify-slice.mjs +2 -2
- package/project-template/templates/design-brief.template.md +34 -0
- package/project-template/templates/design-methodology.md +1 -2
- package/project-template/templates/design.template.md +65 -0
- package/project-template/templates/developer-log.template.md +12 -1
- package/project-template/templates/five-axis-framework.md +12 -0
- package/project-template/templates/game-designer-creative-process.template.md +99 -0
- package/project-template/templates/level-sketch.template.json +56 -0
- package/project-template/templates/north-star.template.md +43 -0
- package/project-template/templates/project-state.template.md +1 -1
- package/project-template/vite.config.ts +4 -5
- package/project-templates/phaser/.claude/agents/creative-director.md +114 -0
- package/project-templates/phaser/.claude/agents/game-designer.md +41 -20
- package/project-templates/phaser/.claude/agents/refs/creative-director-guide.md +35 -0
- package/project-templates/phaser/.claude/agents/refs/creative-director-kickoff-guide.md +52 -0
- package/project-templates/phaser/.claude/agents/refs/creative-discovery-guide.md +76 -0
- package/project-templates/phaser/.claude/agents/refs/creative-north-star-examples.md +82 -0
- package/project-templates/phaser/.claude/agents/refs/developer-dev-handoff.md +1 -1
- package/project-templates/phaser/.claude/agents/refs/game-designer-fusion-depth-playbook.md +28 -0
- package/project-templates/phaser/.claude/agents/reviewer.md +11 -0
- package/project-templates/phaser/.claude/hooks/block-ring1-tasklist.mjs +2 -2
- package/project-templates/phaser/.claude/hooks/user-prompt.mjs +17 -18
- package/project-templates/phaser/.claude/hooks/validate-workflow-stop.mjs +209 -12
- package/project-templates/phaser/.claude/skills/playcraft-playable-optimization/SKILL.md +20 -20
- package/project-templates/phaser/.cursor/rules/playcraft-orchestrator.mdc +1 -1
- package/project-templates/phaser/CLAUDE.md +88 -54
- package/project-templates/phaser/docs/DESIGN.md +25 -0
- package/project-templates/phaser/docs/project-state.md +1 -1
- package/project-templates/phaser/docs/team/collaboration.md +19 -7
- package/project-templates/phaser/docs/team/workflow-changelog.md +14 -0
- package/project-templates/phaser/fusion-patterns/catalog.json +77 -0
- package/project-templates/phaser/package.json +3 -1
- package/project-templates/phaser/skills/_shared/scripts/dev-start.mjs +3 -3
- package/project-templates/phaser/skills/_shared/scripts/disclosure-config.mjs +65 -39
- package/project-templates/phaser/skills/_shared/scripts/harness-smoke.mjs +3 -1
- package/project-templates/phaser/skills/_shared/scripts/lib/fusion-intent.mjs +88 -0
- package/project-templates/phaser/skills/_shared/scripts/lib/skill-fidelity.mjs +185 -0
- package/project-templates/phaser/skills/_shared/scripts/state-get.mjs +124 -7
- package/project-templates/phaser/skills/_shared/scripts/state-store.mjs +25 -2
- package/project-templates/phaser/skills/_shared/scripts/validate-level-sketch.mjs +444 -0
- package/project-templates/phaser/skills/_shared/scripts/verify-design-consistency.mjs +728 -0
- package/project-templates/phaser/skills/playable-record/scripts/lib/dev-server.mjs +46 -11
- package/project-templates/phaser/skills/playable-record/scripts/record-playable.mjs +2 -1
- package/project-templates/phaser/skills/playable-record/scripts/verify-contract.mjs +4 -4
- package/project-templates/phaser/skills/playable-record/scripts/verify-firstwin.mjs +3 -3
- package/project-templates/phaser/skills/playable-record/scripts/verify-fusion.mjs +37 -2
- package/project-templates/phaser/skills/playable-record/scripts/verify-slice.mjs +2 -2
- package/project-templates/phaser/templates/design-brief.template.md +42 -11
- package/project-templates/phaser/templates/design-methodology.md +1 -2
- package/project-templates/phaser/templates/design.template.md +77 -0
- package/project-templates/phaser/templates/five-axis-framework.md +50 -1
- package/project-templates/phaser/templates/game-designer-creative-process.template.md +99 -0
- package/project-templates/phaser/templates/level-sketch.template.json +56 -0
- package/project-templates/phaser/templates/north-star.template.md +43 -0
- package/project-templates/phaser/templates/project-state.template.md +1 -1
- package/project-templates/phaser/vite.config.ts +4 -5
- package/project-templates/playable-template-phaser/.playcraftignore +10 -0
- package/project-templates/playable-template-phaser/CLAUDE.md +178 -0
- package/project-templates/playable-template-phaser/PLAYCRAFT-MIGRATION.md +328 -0
- package/project-templates/playable-template-phaser/README.md +381 -0
- package/project-templates/playable-template-phaser/assets/brain.png +0 -0
- package/project-templates/playable-template-phaser/assets/button.png +0 -0
- package/project-templates/playable-template-phaser/assets/interact.png +0 -0
- package/project-templates/playable-template-phaser/assets/logo.webp +0 -0
- package/project-templates/playable-template-phaser/assets/warn_brain.png +0 -0
- package/project-templates/playable-template-phaser/builds.config.js +12 -0
- package/project-templates/playable-template-phaser/globals.d.ts +2 -0
- package/project-templates/playable-template-phaser/index.html +12 -0
- package/project-templates/playable-template-phaser/package.json +45 -0
- package/project-templates/playable-template-phaser/scripts/base64-to-mp3.js +340 -0
- package/project-templates/playable-template-phaser/scripts/convert-to-webp.js +370 -0
- package/project-templates/playable-template-phaser/src/Game.ts +154 -0
- package/project-templates/playable-template-phaser/src/config/LoadingConfig.ts +40 -0
- package/project-templates/playable-template-phaser/src/config/ThemeConfig.ts +81 -0
- package/project-templates/playable-template-phaser/src/index.css +18 -0
- package/project-templates/playable-template-phaser/src/index.html +9 -0
- package/project-templates/playable-template-phaser/src/index.ts +30 -0
- package/project-templates/playable-template-phaser/src/json5.d.ts +4 -0
- package/project-templates/playable-template-phaser/src/managers/AudioManager.ts +559 -0
- package/project-templates/playable-template-phaser/src/scenes/MainScene.ts +301 -0
- package/project-templates/playable-template-phaser/src/scenes/PreloadScene.ts +256 -0
- package/project-templates/playable-template-phaser/src/theme/README.md +194 -0
- package/project-templates/playable-template-phaser/src/theme/blue-theme/assets/.gitkeep +24 -0
- package/project-templates/playable-template-phaser/src/theme/blue-theme/index.ts +27 -0
- package/project-templates/playable-template-phaser/src/theme/blue-theme/theme.data.json5 +19 -0
- package/project-templates/playable-template-phaser/src/theme/green-theme/assets/.gitkeep +3 -0
- package/project-templates/playable-template-phaser/src/theme/green-theme/index.ts +20 -0
- package/project-templates/playable-template-phaser/src/theme/green-theme/theme.data.json5 +19 -0
- package/project-templates/playable-template-phaser/src/theme/index.ts +1 -0
- package/project-templates/playable-template-phaser/src/theme/red-theme/assets/.gitkeep +3 -0
- package/project-templates/playable-template-phaser/src/theme/red-theme/index.ts +20 -0
- package/project-templates/playable-template-phaser/src/theme/red-theme/theme.data.json5 +19 -0
- package/project-templates/playable-template-phaser/src/theme/theme.metadata.md +60 -0
- package/project-templates/playable-template-phaser/src/theme/theme.schema.json5 +149 -0
- package/project-templates/playable-template-phaser/src/ui/BrainAgeUI.ts +681 -0
- package/project-templates/playable-template-phaser/src/ui/CountdownUI.ts +565 -0
- package/project-templates/playable-template-phaser/src/ui/PlayButton.ts +51 -0
- package/project-templates/playable-template-phaser/src/ui/ScoreUI.ts +207 -0
- package/project-templates/playable-template-phaser/src/ui/SuccessUI.ts +43 -0
- package/project-templates/playable-template-phaser/src/ui/index.ts +15 -0
- package/project-templates/playable-template-phaser/tsconfig.json +26 -0
- package/project-templates/playable-template-phaser/vite.config.ts +64 -0
- package/project-templates/playable-template-phaser//346/226/260/346/211/213/345/274/200/345/217/221/346/214/207/345/215/227.md +209 -0
- package/project-templates/playable-template-three/README.md +795 -0
- package/project-templates/playable-template-three/assets/Stork.glb +0 -0
- package/project-templates/playable-template-three/assets/button.png +0 -0
- package/project-templates/playable-template-three/assets/logo.webp +0 -0
- package/project-templates/playable-template-three/build.json +7 -0
- package/project-templates/playable-template-three/builds.config.example.js +151 -0
- package/project-templates/playable-template-three/builds.config.js +158 -0
- package/project-templates/playable-template-three/package.json +36 -0
- package/project-templates/playable-template-three/scripts/convert-to-webp.js +370 -0
- package/project-templates/playable-template-three/scripts/theme-builds.js +514 -0
- package/project-templates/playable-template-three/src/Game.ts +215 -0
- package/project-templates/playable-template-three/src/config/LoadingConfig.ts +27 -0
- package/project-templates/playable-template-three/src/config/ThemeConfig.ts +36 -0
- package/project-templates/playable-template-three/src/global.d.ts +108 -0
- package/project-templates/playable-template-three/src/index.css +18 -0
- package/project-templates/playable-template-three/src/index.html +9 -0
- package/project-templates/playable-template-three/src/index.ts +20 -0
- package/project-templates/playable-template-three/src/managers/AudioManager.ts +538 -0
- package/project-templates/playable-template-three/src/scenes/PreloadScene.ts +305 -0
- package/project-templates/playable-template-three/src/theme/README.md +225 -0
- package/project-templates/playable-template-three/src/theme/blue-theme/assets/.gitkeep +28 -0
- package/project-templates/playable-template-three/src/theme/blue-theme/index.ts +45 -0
- package/project-templates/playable-template-three/src/theme/current.ts +12 -0
- package/project-templates/playable-template-three/src/theme/green-theme/assets/.gitkeep +3 -0
- package/project-templates/playable-template-three/src/theme/green-theme/index.ts +34 -0
- package/project-templates/playable-template-three/src/theme/red-theme/assets/.gitkeep +3 -0
- package/project-templates/playable-template-three/src/theme/red-theme/index.ts +34 -0
- package/project-templates/playable-template-three/tsconfig.json +24 -0
- package/project-templates/threejs/.claude/agents/creative-director.md +114 -0
- package/project-templates/threejs/.claude/agents/game-designer.md +41 -20
- package/project-templates/threejs/.claude/agents/refs/creative-director-guide.md +35 -0
- package/project-templates/threejs/.claude/agents/refs/creative-director-kickoff-guide.md +52 -0
- package/project-templates/threejs/.claude/agents/refs/creative-discovery-guide.md +76 -0
- package/project-templates/threejs/.claude/agents/refs/creative-north-star-examples.md +82 -0
- package/project-templates/threejs/.claude/agents/refs/developer-dev-handoff.md +1 -1
- package/project-templates/threejs/.claude/agents/refs/game-designer-fusion-depth-playbook.md +28 -0
- package/project-templates/threejs/.claude/agents/reviewer.md +11 -0
- package/project-templates/threejs/.claude/hooks/block-ring1-tasklist.mjs +2 -2
- package/project-templates/threejs/.claude/hooks/user-prompt.mjs +17 -18
- package/project-templates/threejs/.claude/hooks/validate-workflow-stop.mjs +209 -12
- package/project-templates/threejs/.claude/skills/playcraft-playable-optimization/SKILL.md +20 -20
- package/project-templates/threejs/.cursor/rules/playcraft-orchestrator.mdc +1 -1
- package/project-templates/threejs/CLAUDE.md +88 -54
- package/project-templates/threejs/docs/DESIGN.md +25 -0
- package/project-templates/threejs/docs/project-state.md +1 -1
- package/project-templates/threejs/docs/team/collaboration.md +19 -7
- package/project-templates/threejs/docs/team/workflow-changelog.md +14 -0
- package/project-templates/threejs/fusion-patterns/catalog.json +77 -0
- package/project-templates/threejs/package.json +3 -1
- package/project-templates/threejs/skills/_shared/scripts/dev-start.mjs +3 -3
- package/project-templates/threejs/skills/_shared/scripts/disclosure-config.mjs +65 -39
- package/project-templates/threejs/skills/_shared/scripts/harness-smoke.mjs +3 -1
- package/project-templates/threejs/skills/_shared/scripts/lib/fusion-intent.mjs +88 -0
- package/project-templates/threejs/skills/_shared/scripts/lib/skill-fidelity.mjs +185 -0
- package/project-templates/threejs/skills/_shared/scripts/state-get.mjs +124 -7
- package/project-templates/threejs/skills/_shared/scripts/state-store.mjs +25 -2
- package/project-templates/threejs/skills/_shared/scripts/validate-level-sketch.mjs +444 -0
- package/project-templates/threejs/skills/_shared/scripts/verify-design-consistency.mjs +728 -0
- package/project-templates/threejs/skills/playable-record/scripts/lib/dev-server.mjs +46 -11
- package/project-templates/threejs/skills/playable-record/scripts/record-playable.mjs +2 -1
- package/project-templates/threejs/skills/playable-record/scripts/verify-contract.mjs +4 -4
- package/project-templates/threejs/skills/playable-record/scripts/verify-firstwin.mjs +3 -3
- package/project-templates/threejs/skills/playable-record/scripts/verify-fusion.mjs +37 -2
- package/project-templates/threejs/skills/playable-record/scripts/verify-slice.mjs +2 -2
- package/project-templates/threejs/templates/design-brief.template.md +42 -11
- package/project-templates/threejs/templates/design-methodology.md +1 -2
- package/project-templates/threejs/templates/design.template.md +77 -0
- package/project-templates/threejs/templates/five-axis-framework.md +50 -1
- package/project-templates/threejs/templates/game-designer-creative-process.template.md +99 -0
- package/project-templates/threejs/templates/level-sketch.template.json +56 -0
- package/project-templates/threejs/templates/north-star.template.md +43 -0
- package/project-templates/threejs/templates/project-state.template.md +1 -1
- package/project-templates/threejs/vite.config.ts +4 -5
- package/project-template/docs/DESIGN.md +0 -65
|
@@ -21,6 +21,12 @@
|
|
|
21
21
|
|
|
22
22
|
| 文件 | 引用来源 | 内容摘要 |
|
|
23
23
|
| ------------------------------------ | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
|
|
24
|
+
| `creative-discovery-guide.md` | `agents/creative-director.md` | Ring 1 creative: Micro-Story Spine + MDA reverse + five-phase process |
|
|
25
|
+
| `creative-north-star-examples.md` | `state:get` → `referenceReads` | Bronze/Silver/Gold North Star examples + genre table |
|
|
26
|
+
| `creative-director-kickoff-guide.md` | orchestrator only (not CD) | Orchestrator spawn template for @creative-director |
|
|
27
|
+
| `creative-director-guide.md` | `agents/creative-director.md` | Short index → creative-discovery-guide |
|
|
28
|
+
| `templates/five-axis-framework.md` | `state:get` → `referenceReads` (CD + GD) | Narrative Level (Axis 4) + Emotional Arc (Axis 5) — **disclosure single channel** |
|
|
29
|
+
| `templates/design-methodology.md` | `state:get` → `referenceReads` (CD + GD) | MDA + JTBD foundations — **disclosure single channel** |
|
|
24
30
|
| `game-designer-workflow-detail.md` | `agents/game-designer.md` workflow interface | Game Designer 在 ring 1 `loop: clarify` 主设计任务下的执行流程 |
|
|
25
31
|
| `skill-selector-guide.md` | `docs/team/atom-tree-format.md` | temporary ref-flow atom-selection subagent 产出 `atom-tree` 双文件时使用的速查式选择指南 |
|
|
26
32
|
| `docs/team/atom-tree-format.md` | `atom-tree.template.md`, future atom workflow docs | atom-tree JSON 主 + markdown skill/reference companion |
|
|
@@ -51,6 +57,8 @@
|
|
|
51
57
|
|
|
52
58
|
| iteration / loop / 触发 | Sub-agent | 应该读的 refs(按顺序) |
|
|
53
59
|
| ------------------------------------ | --------------------------- | ---------------------------------------------------------------------------------------------------------- |
|
|
60
|
+
| ring 1 `loop: clarify`(creative) | `@creative-director` | `creative-discovery-guide.md` + `referenceReads` (five-axis, methodology, examples) |
|
|
61
|
+
| ring 1 `loop: clarify`(spec) | Game Designer (spec mode) | `game-designer-workflow-detail.md` + `referenceReads` |
|
|
54
62
|
| ring 1 `loop: clarify` | Game Designer | `game-designer-workflow-detail.md` |
|
|
55
63
|
| ring 1 `loop: clarify`(atom-tree) | temporary ref-flow subagent | `skill-selector-guide.md` + `docs/team/atom-tree-format.md` |
|
|
56
64
|
| ring 2+ `loop: clarify`(atom-tree) | ref-flow subagent | `skill-selector-guide.md` + `docs/team/atom-tree-format.md` |
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Creative Director Guide
|
|
2
|
+
|
|
3
|
+
> **Superseded for execution:** use [creative-discovery-guide.md](./creative-discovery-guide.md) — this file remains a short index.
|
|
4
|
+
|
|
5
|
+
## Quick links
|
|
6
|
+
|
|
7
|
+
| Need | Read |
|
|
8
|
+
| --------------------------------- | -------------------------------------------------------------------------- |
|
|
9
|
+
| Step-by-step Ring 1 creative | [creative-discovery-guide.md](./creative-discovery-guide.md) |
|
|
10
|
+
| Good/bad North Star examples | [creative-north-star-examples.md](./creative-north-star-examples.md) |
|
|
11
|
+
| Narrative Level + Emotional Arc | `templates/five-axis-framework.md` (via `state:get` → `referenceReads`) |
|
|
12
|
+
| MDA + JTBD | `templates/design-methodology.md` (via `referenceReads`) |
|
|
13
|
+
| Orchestrator kickoff (not for CD) | [creative-director-kickoff-guide.md](./creative-director-kickoff-guide.md) |
|
|
14
|
+
|
|
15
|
+
## Objective
|
|
16
|
+
|
|
17
|
+
Discover a **playable idea with soul** — Micro-Story Spine + System Dynamic the player can feel, not a mechanism chain disguised as a one-liner.
|
|
18
|
+
|
|
19
|
+
## Forbidden reads (context pollution)
|
|
20
|
+
|
|
21
|
+
Do **not** open:
|
|
22
|
+
|
|
23
|
+
- `templates/design.template.md`
|
|
24
|
+
- `skills/_shared/scripts/verify-design-consistency.mjs`
|
|
25
|
+
- `.claude/agents/refs/skill-selector-guide.md`
|
|
26
|
+
- `docs/team/atom-tree-format.md`
|
|
27
|
+
- `docs/DESIGN.md`
|
|
28
|
+
|
|
29
|
+
Do **not** run `playcraft skills *`, `npm run verify:design`, or `npm run levels:validate`.
|
|
30
|
+
|
|
31
|
+
## STOP contract
|
|
32
|
+
|
|
33
|
+
- Write `handoffContext.northStarSummary` (≤80 words) via `npm run state:set`.
|
|
34
|
+
- Set `next_orchestrator_action` to invoke `@game-designer` for ring 1 design spec.
|
|
35
|
+
- Do **not** seed `sliceState`, write `DESIGN.md`, or run verifiers.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Creative Director Kickoff Guide — Orchestrator Only
|
|
2
|
+
|
|
3
|
+
> **Audience**: Orchestrator when spawning `@creative-director` for Ring 1 `loop: clarify` (`1:creative`).
|
|
4
|
+
> **Prerequisite**: `@game-designer` mechanism lock STOP — `handoffContext.primaryGameplaySkill` + `docs/atom-tree.json` `meta.skillsMatch`.
|
|
5
|
+
> **Not for CD**: the subagent reads `creative-discovery-guide.md` instead.
|
|
6
|
+
|
|
7
|
+
## Before spawn
|
|
8
|
+
|
|
9
|
+
1. Run `npm run state:get` — confirm `nextRole: creative-director`.
|
|
10
|
+
2. Read this guide.
|
|
11
|
+
3. **Do not** forward the user's mechanism spec verbatim as the only prompt.
|
|
12
|
+
|
|
13
|
+
## Task prompt template
|
|
14
|
+
|
|
15
|
+
Copy into the `@creative-director` Task message:
|
|
16
|
+
|
|
17
|
+
```markdown
|
|
18
|
+
You are @creative-director for this PlayCraft playable-ad project.
|
|
19
|
+
|
|
20
|
+
## Mechanism seed(已锁定 PGS,不是自由发明)
|
|
21
|
+
|
|
22
|
+
Primary skill: `{handoffContext.primaryGameplaySkill from state:get}`
|
|
23
|
+
|
|
24
|
+
{paste user's high-level intent — e.g. arrow + tray match-3 fusion, 8×8}
|
|
25
|
+
|
|
26
|
+
## Creative question(CD 必须回答)
|
|
27
|
+
|
|
28
|
+
在 **已 read 的 primary gameplay PGS** 上:Hook 帧是什么?压力在玩家世界里意味着什么?Payoff 必须拍到 **path slide out / fly to tray / tray match** 中的至少一个核心瞬间 — 不得用 rotate 或纯棋盘 cascade 替换。
|
|
29
|
+
|
|
30
|
+
## JTBD guess / Emotional arc hint(仅 hint,CD 可改)
|
|
31
|
+
|
|
32
|
+
{Stress Relief → Relaxation | Challenge → Urgency | …}
|
|
33
|
+
注:Orchestrator **不预设 Narrative Level**;L0/L1/L2 由 CD 在 Phase 3 裁决。
|
|
34
|
+
若用户明确要求「纯机制 / 不要故事」,在此原文标注,供 CD 走 L0。
|
|
35
|
+
|
|
36
|
+
## Deliverables
|
|
37
|
+
|
|
38
|
+
docs/north-star.md(含 Micro-Story Spine)+ docs/creative-process.md
|
|
39
|
+
|
|
40
|
+
## Read on start
|
|
41
|
+
|
|
42
|
+
.claude/agents/refs/creative-discovery-guide.md
|
|
43
|
+
npm run state:get -- --json referenceReads contextPacket
|
|
44
|
+
playcraft skills read {primaryGameplaySkill}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Rules
|
|
48
|
+
|
|
49
|
+
- Translate user intent into a **Creative question** grounded in the **read PGS** — never spawn CD with only "build arrow match-3 on 8×8".
|
|
50
|
+
- Optional: write `handoffContext.creativeBrief` via `state:set` (hint for GD spec phase).
|
|
51
|
+
- Use `bypassPermissions` for nested subagent Bash if harness/live test (known P0).
|
|
52
|
+
- After CD STOP: invoke `@game-designer` for ring 1 design spec only — do not inline creative work.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Creative Discovery Guide
|
|
2
|
+
|
|
3
|
+
> Purpose: step-by-step execution for `@creative-director` — produce **`docs/north-star.md`** (with Micro-Story Spine) + **`docs/creative-process.md`** before any spec work.
|
|
4
|
+
>
|
|
5
|
+
> Scope: creative discovery only. Does not define skills match, level-sketch, atom-tree, or DESIGN.md mechanics tables.
|
|
6
|
+
|
|
7
|
+
## Step 0 — Read state + methodology
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm run state:get -- --json dispatchPacket contextPacket referenceReads
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
1. Read orchestrator kickoff notes (Creative question, mechanism seed, JTBD/arc hints — hints only).
|
|
14
|
+
2. Read every path in **`referenceReads`** (typically `templates/five-axis-framework.md` §4–§5, `templates/design-methodology.md` §A–B, `.claude/agents/refs/creative-north-star-examples.md`).
|
|
15
|
+
3. Skim user prompt / `contextPacket` for explicit L0 opt-out ("纯机制", "no story", "pure mechanic showcase").
|
|
16
|
+
|
|
17
|
+
## Step 1 — MDA reverse + Narrative Level
|
|
18
|
+
|
|
19
|
+
From user intent, pick:
|
|
20
|
+
|
|
21
|
+
- **2–3 target Aesthetics** (Fantasy, Challenge, Urgency, …) — see design-methodology §A.
|
|
22
|
+
- **Narrative Level** (you decide):
|
|
23
|
+
- **Default L1 or L2** — light story that fits the mechanic.
|
|
24
|
+
- **L0 only** if user explicitly opted out of story — quote their words in Phase 3.
|
|
25
|
+
- **Never L3** — downgrade to L2 if tempted.
|
|
26
|
+
|
|
27
|
+
Lock Emotional Arc (Axis 5): Urgency | Challenge | Competence | Curiosity | Relaxation.
|
|
28
|
+
|
|
29
|
+
## Step 2 — Phase 1 diverge (≥3 candidates)
|
|
30
|
+
|
|
31
|
+
Use `templates/game-designer-creative-process.template.md`. Each candidate **must** include:
|
|
32
|
+
|
|
33
|
+
- Core moment
|
|
34
|
+
- **Story hook** (15s filmable frame)
|
|
35
|
+
- **Who / Stakes** (one line each)
|
|
36
|
+
|
|
37
|
+
Do not write DESIGN.md yet.
|
|
38
|
+
|
|
39
|
+
## Step 3 — Phase 2 adversarial (five questions)
|
|
40
|
+
|
|
41
|
+
Fill the five-question table. Q5 is the anti-filler gate: _If you remove Who and Situation, does anyone care?_
|
|
42
|
+
|
|
43
|
+
Produce ≥2 falsifiable vulnerability bullets.
|
|
44
|
+
|
|
45
|
+
## Step 4 — Phase 3 commitment
|
|
46
|
+
|
|
47
|
+
- Pick one candidate.
|
|
48
|
+
- Record **Narrative level** + reason (L0: paste user's opt-out quote).
|
|
49
|
+
- Write patch promises addressing vulnerabilities.
|
|
50
|
+
|
|
51
|
+
## Step 5 — Write north-star + creative-process
|
|
52
|
+
|
|
53
|
+
**`docs/north-star.md`** from `templates/north-star.template.md`:
|
|
54
|
+
|
|
55
|
+
| Field | L1/L2 | L0 |
|
|
56
|
+
| ------------ | ---------------------------- | ------------------------------ |
|
|
57
|
+
| Who | Required — concrete identity | `n/a — pure mechanic showcase` |
|
|
58
|
+
| Situation | Required — Hook frame | Required — mechanism spectacle |
|
|
59
|
+
| Stakes | Required — narrative meaning | Required — missed experience |
|
|
60
|
+
| Payoff image | Required | Required |
|
|
61
|
+
| One-liner | Must name Who or Situation | Hook + mechanic payoff OK |
|
|
62
|
+
|
|
63
|
+
**`docs/creative-process.md`:** Phases 1–3 complete + Phase 4 Design Intent line (= One-liner verbatim).
|
|
64
|
+
|
|
65
|
+
## Step 6 — Self-check before STOP
|
|
66
|
+
|
|
67
|
+
1. Can you describe the Hook frame in one breath?
|
|
68
|
+
2. Does removing Who/Situation kill the pitch? (L1/L2 must survive Q5.)
|
|
69
|
+
3. Is the story **fitted to the mechanic**, not a generic mascot pasted on?
|
|
70
|
+
4. Design Intent === One-liner character-for-character?
|
|
71
|
+
5. Compare against Bronze/Silver/Gold in `creative-north-star-examples.md` — are you at least Silver?
|
|
72
|
+
|
|
73
|
+
## STOP handoff
|
|
74
|
+
|
|
75
|
+
- `handoffContext.northStarSummary` ≤80 words (include Who + Hook).
|
|
76
|
+
- `next_orchestrator_action`: Invoke @game-designer — ring 1 design spec.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Creative North Star — Examples (Micro-Story Spine)
|
|
2
|
+
|
|
3
|
+
> **Used by**: `@creative-director` via `referenceReads` on `state:get`.
|
|
4
|
+
> **Narrative Level** terms align with `templates/five-axis-framework.md` Axis 4 (L0–L2 only; L3 forbidden).
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Tier guide
|
|
9
|
+
|
|
10
|
+
| Tier | Meaning |
|
|
11
|
+
| ---------- | ---------------------------------------------- |
|
|
12
|
+
| **Bronze** | Passes tension-word lint but no filmable story |
|
|
13
|
+
| **Silver** | Strong metaphor but missing Who/Situation |
|
|
14
|
+
| **Gold** | Complete Micro-Story Spine — target for L1/L2 |
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Bronze — Arrow Debt Tray (live smoke v1)
|
|
19
|
+
|
|
20
|
+
**Narrative level**: L1 (claimed) — **incomplete**
|
|
21
|
+
|
|
22
|
+
| Field | Content |
|
|
23
|
+
| --------- | --------------------------------------------------------------------------------------------------------------------------- |
|
|
24
|
+
| Who | _(missing)_ |
|
|
25
|
+
| Situation | _(missing)_ |
|
|
26
|
+
| Stakes | Abstract "debt / burst" |
|
|
27
|
+
| Payoff | Abstract "cash in match-3" |
|
|
28
|
+
| One-liner | "Play the nerve of opening one-way escape routes while the tray's growing debt dares you to cash in just before it bursts." |
|
|
29
|
+
|
|
30
|
+
**Why Bronze:** tension vocabulary without a story object. Player cannot answer "who am I" or "what am I escaping."
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Silver — Arrow Elim Fusion (fixture)
|
|
35
|
+
|
|
36
|
+
**Narrative level**: L1 — **incomplete**
|
|
37
|
+
|
|
38
|
+
| Field | Content |
|
|
39
|
+
| --------- | -------------------------------------------------------------------------- |
|
|
40
|
+
| Who | _(missing)_ |
|
|
41
|
+
| Situation | _(missing)_ |
|
|
42
|
+
| Stakes | "颜色是债务" metaphor |
|
|
43
|
+
| Payoff | "走钢丝上排雷" |
|
|
44
|
+
| One-liner | "颜色是债务——每推一条箭头进托盘,都在为未来的自己挖坑,像在走钢丝上排雷。" |
|
|
45
|
+
|
|
46
|
+
**Why Silver:** memorable metaphor, still no filmable Hook frame or identity.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Gold — Night-Shift Cargo Gate (arrow + tray fusion, L2)
|
|
51
|
+
|
|
52
|
+
**Narrative level**: L2
|
|
53
|
+
|
|
54
|
+
| Field | Content |
|
|
55
|
+
| ------------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
|
56
|
+
| Who | Night-shift warehouse loader |
|
|
57
|
+
| Situation | One-way chutes jammed with color-coded crates; bay lights flash amber — gate closes in minutes |
|
|
58
|
+
| Stakes | Bay locks when staging slots fill — next truck and the loader are stuck inside |
|
|
59
|
+
| Payoff image | Third matching crate slides in, bay door hisses open, chute clears with a satisfying rush |
|
|
60
|
+
| Emotional arc | Urgency |
|
|
61
|
+
| One-liner | "Help the night loader beat the closing gate — every crate you push buys seconds until three matching colors pop the bay open." |
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Genre table (L1/L2 patterns)
|
|
66
|
+
|
|
67
|
+
| Genre | Narrative level | Who | Situation | Stakes | Payoff |
|
|
68
|
+
| ------------------------------ | --------------- | ------------------ | -------------------------------- | -------------------------- | ------------------------- |
|
|
69
|
+
| Arrow + tray fusion | L2 | Night-shift loader | Chutes jammed, bay nearly full | Gate locks, loader trapped | Triple match, door opens |
|
|
70
|
+
| Screw puzzle | L2 | Repair hand | Board pins reward corner peeking | Mechanism never clears | Last panel drops |
|
|
71
|
+
| Pure match-3 (L0 opt-out only) | L0 | n/a | Board one move from huge clear | Miss the "almost" cascade | Full-board chain reaction |
|
|
72
|
+
| Chase / runner | L2 | Fugitive | Pursuer visible behind | Caught at the gap | Narrow squeeze through |
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Anti-patterns (do not ship)
|
|
77
|
+
|
|
78
|
+
- **Generic mascot:** "Help the cute hamster" with no tie to mechanic pressure.
|
|
79
|
+
- **Abstract tension only:** debt / bet / burst / nerve without Who or Situation.
|
|
80
|
+
- **Mechanism chain one-liner:** "Tap arrow → tray → match three → win."
|
|
81
|
+
- **PGS core-loop replacement:** rotate 90° / clockwise aim / board-only cascade instead of path slide → tray match from the locked skill.
|
|
82
|
+
- **L0 without opt-out quote:** choosing pure mechanic when user never asked for it.
|
|
@@ -12,7 +12,7 @@ npm run dev:start # starts persistent dev server + records the real devUrl
|
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
- **Not** `playcraft start`, and **not** a bare `npm run dev`. `dev:start` wraps the project's `scripts.dev` and additionally:
|
|
15
|
-
- detects the actual listening port from Vite output (handles port drift when
|
|
15
|
+
- detects the actual listening port from Vite output (handles port drift when 5173 is taken),
|
|
16
16
|
- appends `?debug=1`,
|
|
17
17
|
- writes `devUrl` through the same programmatic state layer `state:set` uses.
|
|
18
18
|
- **Do not** read a port from the terminal or hand-edit `devUrl` — `dev:start` is the source of truth for it.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Game Designer — Fusion Depth Playbook
|
|
2
|
+
|
|
3
|
+
Lightweight narrative templates for Ring 1 fusion designs. Pick one spine and **add one variation axis** (tray pressure / phase unlock / segment density).
|
|
4
|
+
|
|
5
|
+
## Template 1 — Path → Tray → Match
|
|
6
|
+
|
|
7
|
+
- **Board**: fixed 8×8; paths are polylines with blocked dependencies (DAG).
|
|
8
|
+
- **Gesture**: tap path head → slide_out along direction → fly_to_tray.
|
|
9
|
+
- **Payoff**: match_clear in tray when 3 same color; tray peak forces color order.
|
|
10
|
+
- **Variation axis**: {tray pressure curve | opening removable count | segment density}
|
|
11
|
+
|
|
12
|
+
## Template 2 — Phase Unlock (same grid)
|
|
13
|
+
|
|
14
|
+
- **Board**: 8×8 with masked regions (`boardPhases` in level-sketch optional).
|
|
15
|
+
- **Unlock**: each match_clear or N paths removed reveals new paths in unlocked zone.
|
|
16
|
+
- **Variation axis**: unlock cadence vs tray pressure — not board resize.
|
|
17
|
+
|
|
18
|
+
## Template 3 — Tray Pressure Puzzle
|
|
19
|
+
|
|
20
|
+
- **Board**: pure dependency puzzle; match-3 **only in tray**.
|
|
21
|
+
- **Failure**: tray full without match; success requires reading color order before tap.
|
|
22
|
+
- **Variation axis**: dependency depth (≥2 waves) + max opening removable (1–2).
|
|
23
|
+
|
|
24
|
+
## Anti-patterns (do not ship)
|
|
25
|
+
|
|
26
|
+
- 8×8 with ≤4 paths or all-free opening
|
|
27
|
+
- Board swap match-3 + path tap without interaction contract
|
|
28
|
+
- DESIGN lists two parent skills with no **interaction contract**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Gameplay Sufficiency Self-Check
|
|
2
2
|
|
|
3
|
-
> **When to read**:
|
|
3
|
+
> **When to read**: `@game-designer` during Ring 1 clarify/spec when the living brief is structurally complete. This is a **blocking gate** — do not proceed to skills match / DESIGN seed until all angles pass.
|
|
4
4
|
>
|
|
5
5
|
> **Pattern**: Modeled on Flow B's "玩法核心充分性 Review" — 8 angles covering MDA, Game Feel, visual readability, and Playable Ad flow completeness.
|
|
6
6
|
|
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
## Purpose
|
|
10
10
|
|
|
11
|
-
Verify that the design-brief contains enough gameplay depth to support module selection, five-axis
|
|
11
|
+
Verify that the design-brief contains enough gameplay depth to support module selection, five-axis choices (see `referenceReads`), and downstream production. This check prevents the common failure mode of "proceeding with a technically complete but experientially shallow brief."
|
|
12
12
|
|
|
13
|
-
**Why before
|
|
13
|
+
**Why before spec construction**: Narrative Level and Style Direction must serve the core gameplay. If the gameplay itself is underspecified, five-axis choices become disconnected from player experience.
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
@@ -56,7 +56,7 @@ Write self-check results in internal notes or briefly in design-brief appendix:
|
|
|
56
56
|
|
|
57
57
|
## Decision
|
|
58
58
|
|
|
59
|
-
- **All 8 ✅** → Proceed to
|
|
59
|
+
- **All 8 ✅** → Proceed to skills match + DESIGN seed (Ring 1 spec construction)
|
|
60
60
|
- **Any ❌** → Return to Step 1 with specific angle as the brainstorm target. Ask user only about the gap (not re-do entire brainstorm).
|
|
61
61
|
|
|
62
62
|
---
|
|
@@ -109,6 +109,17 @@ You must not:
|
|
|
109
109
|
- set user acceptance state
|
|
110
110
|
- ask the user directly from a subagent
|
|
111
111
|
|
|
112
|
+
## Ring 1 Design Adversarial (harness A2 / A3 only)
|
|
113
|
+
|
|
114
|
+
When `dispatchPacket.doWhat` or env `GD_CREATIVE_ARM` is `A2` or `A3`, and the packet asks for **design adversarial review**:
|
|
115
|
+
|
|
116
|
+
- **Read only**: `docs/creative-process.md` (phase 1 draft), `docs/design-brief.md`, optional partial `docs/DESIGN.md`
|
|
117
|
+
- **Do not** edit `game/**` or rewrite DESIGN — output a **vulnerability list** only
|
|
118
|
+
- Run the **four adversarial questions** on each candidate (second tap / ignore mechanism / white-box / depth ceiling)
|
|
119
|
+
- Format output as markdown section `## Design Adversarial Findings` in `logs/review-report.md` or append to `docs/creative-process.md` phase 2
|
|
120
|
+
- No aesthetic veto ("not fun enough") — only falsifiable logic gaps
|
|
121
|
+
- End with `PLAYCRAFT_STOP` — hand back to Game Designer for phase 3–4
|
|
122
|
+
|
|
112
123
|
## Legacy Fallback
|
|
113
124
|
|
|
114
125
|
Only when `dispatchPacket` is null and `sliceState` is empty, follow [`refs/reviewer-legacy-fallback.md`](refs/reviewer-legacy-fallback.md).
|
|
@@ -4,16 +4,16 @@ Hooks for **Claude Code** (`.claude/settings.json`), also shared with **Cursor**
|
|
|
4
4
|
|
|
5
5
|
## Hook inventory
|
|
6
6
|
|
|
7
|
-
| Hook | Event | When | What
|
|
8
|
-
| ---------------------------------- | ---------------------------- | ------------------------------------------------------------------- |
|
|
9
|
-
| `validate-atom-tree-selection.mjs` | `PostToolUse` | atom-tree.json written/edited | Validates selected atoms and skill references
|
|
10
|
-
| `gate-runner.mjs` | manual / `npm run ring:gate` | Before Ring Gate per iteration | Runs objective DoD verifiers, writes `ringDoD` + Ring Gate Runner verdict
|
|
11
|
-
| `gate-dispatcher.mjs` | `PostToolUse` | AskUserQuestion called | Identifies gate confirmations, dispatches to `gate.mjs`
|
|
12
|
-
| `gate.mjs` | (called by dispatcher) | Ring Gate confirmed by user | Runs snapshot, writes gate log, and advances state when accepted
|
|
13
|
-
| `user-prompt.mjs` | `UserPromptSubmit` | Every user prompt | Increments turn counter, snapshots project, writes prompt log; **iteration 1** injects Ring 1 Dispatch Path (orchestrator → subagents)
|
|
14
|
-
| `block-ring1-tasklist.mjs` | `PreToolUse` | TaskCreate/Update/List/Get/Output/Stop | Blocks internal Task lists during iteration 1; **Task / @game-designer / temporary ref-flow / @developer spawn still allowed**
|
|
15
|
-
| `validate-workflow-stop.mjs` | `SubagentStop` | TA/Developer/Artist/Reviewer/Game Designer/temporary ref-flow stops | Validates logs, handoff, and ring docs before subagent may stop
|
|
16
|
-
| `snapshot-milestone.mjs` | `SubagentStop` | Subagent stops | Detects milestone events (gate passed, dev ready) and snapshots
|
|
7
|
+
| Hook | Event | When | What |
|
|
8
|
+
| ---------------------------------- | ---------------------------- | ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
9
|
+
| `validate-atom-tree-selection.mjs` | `PostToolUse` | atom-tree.json written/edited | Validates selected atoms and skill references |
|
|
10
|
+
| `gate-runner.mjs` | manual / `npm run ring:gate` | Before Ring Gate per iteration | Runs objective DoD verifiers, writes `ringDoD` + Ring Gate Runner verdict |
|
|
11
|
+
| `gate-dispatcher.mjs` | `PostToolUse` | AskUserQuestion called | Identifies gate confirmations, dispatches to `gate.mjs` |
|
|
12
|
+
| `gate.mjs` | (called by dispatcher) | Ring Gate confirmed by user | Runs snapshot, writes gate log, and advances state when accepted |
|
|
13
|
+
| `user-prompt.mjs` | `UserPromptSubmit` | Every user prompt | Increments turn counter, snapshots project, writes prompt log; **iteration 1** injects Ring 1 Dispatch Path (orchestrator → subagents) |
|
|
14
|
+
| `block-ring1-tasklist.mjs` | `PreToolUse` | TaskCreate/Update/List/Get/Output/Stop | Blocks internal Task lists during iteration 1; **Task / @creative-director / @game-designer / temporary ref-flow / @developer spawn still allowed** |
|
|
15
|
+
| `validate-workflow-stop.mjs` | `SubagentStop` | TA/Developer/Artist/Reviewer/Game Designer/temporary ref-flow stops | Validates logs, handoff, and ring docs before subagent may stop |
|
|
16
|
+
| `snapshot-milestone.mjs` | `SubagentStop` | Subagent stops | Detects milestone events (gate passed, dev ready) and snapshots |
|
|
17
17
|
|
|
18
18
|
## `validate-atom-tree-selection.mjs`
|
|
19
19
|
|
|
@@ -84,7 +84,7 @@ Triggered **on every `UserPromptSubmit`**. Actions:
|
|
|
84
84
|
1. **Increment turn counter** — stored in `.claude/logs/session.json`
|
|
85
85
|
2. **Snapshot project** — calls `../snapshot.mjs` with a sanitized prompt prefix as name
|
|
86
86
|
3. **Write prompt log** — appends to `logs/hook.log` with timestamp, turn number, and prompt preview
|
|
87
|
-
4. **Ring 1 dispatch injection** — when `iteration: 1` in state, emits `hookSpecificOutput.additionalContext` with orchestrator dispatch recipe (invoke `@game-designer` / temporary ref-flow / `@developer`; no inline role-play; no internal Task lists)
|
|
87
|
+
4. **Ring 1 dispatch injection** — when `iteration: 1` in state, emits `hookSpecificOutput.additionalContext` with orchestrator dispatch recipe (invoke `@creative-director` → `@game-designer` / temporary ref-flow / `@developer`; no inline role-play; no internal Task lists)
|
|
88
88
|
|
|
89
89
|
Non-blocking — snapshot failures are logged but never prevent the prompt from being processed.
|
|
90
90
|
|
|
@@ -92,7 +92,7 @@ Non-blocking — snapshot failures are logged but never prevent the prompt from
|
|
|
92
92
|
|
|
93
93
|
Triggered **before `TaskCreate` / `TaskUpdate` / `TaskList` / `TaskGet` / `TaskOutput` / `TaskStop`** when `iteration: 1`.
|
|
94
94
|
|
|
95
|
-
- Denies the tool call with `permissionDecision: deny` and points the agent to dispatch subagents via `Task` / `@game-designer` / temporary ref-flow / `@developer`
|
|
95
|
+
- Denies the tool call with `permissionDecision: deny` and points the agent to dispatch subagents via `Task` / `@creative-director` / `@game-designer` / temporary ref-flow / `@developer`
|
|
96
96
|
- Ring 2+ passes through unchanged
|
|
97
97
|
|
|
98
98
|
On deny: exit `2` + JSON `hookSpecificOutput.permissionDecision: deny`
|
|
@@ -44,20 +44,28 @@ function readIteration(projectDir) {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
/** Selected atoms that should be linked into .claude/skills/ (excludes bundled playcraft-* skills). */
|
|
47
|
-
function
|
|
47
|
+
function readAtomTree(projectDir) {
|
|
48
48
|
const jsonPath = path.join(projectDir, 'docs', 'atom-tree.json');
|
|
49
|
-
if (!fs.existsSync(jsonPath)) return [];
|
|
49
|
+
if (!fs.existsSync(jsonPath)) return { exists: false, parseError: false, atoms: [] };
|
|
50
50
|
try {
|
|
51
51
|
const tree = JSON.parse(fs.readFileSync(jsonPath, 'utf8'));
|
|
52
52
|
const atoms = Array.isArray(tree?.meta?.selectedAtoms) ? tree.meta.selectedAtoms : [];
|
|
53
|
-
return
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
return {
|
|
54
|
+
exists: true,
|
|
55
|
+
parseError: false,
|
|
56
|
+
atoms: atoms
|
|
57
|
+
.map((a) => (typeof a === 'string' ? a.trim() : ''))
|
|
58
|
+
.filter((a) => a && !a.startsWith('{{') && !a.startsWith('playcraft-')),
|
|
59
|
+
};
|
|
56
60
|
} catch {
|
|
57
|
-
return [];
|
|
61
|
+
return { exists: true, parseError: true, atoms: [] };
|
|
58
62
|
}
|
|
59
63
|
}
|
|
60
64
|
|
|
65
|
+
function readSelectedAtoms(projectDir) {
|
|
66
|
+
return readAtomTree(projectDir).atoms;
|
|
67
|
+
}
|
|
68
|
+
|
|
61
69
|
/** Atoms with no linked dir under .claude/skills/. */
|
|
62
70
|
function missingLinks(projectDir, atoms) {
|
|
63
71
|
const skillsDir = path.join(projectDir, '.claude', 'skills');
|
|
@@ -87,13 +95,28 @@ function countFilledRows(section) {
|
|
|
87
95
|
return count;
|
|
88
96
|
}
|
|
89
97
|
|
|
90
|
-
function
|
|
98
|
+
function missingPreflightEvidence(projectDir, atoms) {
|
|
91
99
|
const logPath = path.join(projectDir, 'logs', 'developer-log.md');
|
|
92
|
-
if (!fs.existsSync(logPath)) return
|
|
100
|
+
if (!fs.existsSync(logPath)) return ['logs/developer-log.md missing'];
|
|
93
101
|
const content = fs.readFileSync(logPath, 'utf8');
|
|
102
|
+
const missing = [];
|
|
103
|
+
if (!content.includes('docs/atom-tree.json')) missing.push('docs/atom-tree.json');
|
|
94
104
|
const section = extractSection(content, '## Skill Preflight');
|
|
95
|
-
if (!section)
|
|
96
|
-
|
|
105
|
+
if (!section) {
|
|
106
|
+
missing.push('logs/developer-log.md § Skill Preflight');
|
|
107
|
+
return missing;
|
|
108
|
+
}
|
|
109
|
+
for (const atom of atoms) {
|
|
110
|
+
const skillPath = `.claude/skills/${atom}/SKILL.md`;
|
|
111
|
+
if (!section.includes(atom) || !section.includes(skillPath)) missing.push(skillPath);
|
|
112
|
+
}
|
|
113
|
+
if (atoms.length === 0 && countFilledRows(section) < 1) missing.push('one non-template Skill Preflight row');
|
|
114
|
+
return missing;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function isSkillPreflightFilled(projectDir, atomCount) {
|
|
118
|
+
const atoms = readSelectedAtoms(projectDir);
|
|
119
|
+
return missingPreflightEvidence(projectDir, atoms).length === 0 && atoms.length >= atomCount;
|
|
97
120
|
}
|
|
98
121
|
|
|
99
122
|
function isGameSourcePath(filePath, projectDir) {
|
|
@@ -158,7 +181,18 @@ async function main() {
|
|
|
158
181
|
const iteration = readIteration(projectDir);
|
|
159
182
|
if (iteration < 1 || iteration > 3) process.exit(0);
|
|
160
183
|
|
|
161
|
-
const
|
|
184
|
+
const atomTree = readAtomTree(projectDir);
|
|
185
|
+
if (!atomTree.exists) {
|
|
186
|
+
emitDeny(
|
|
187
|
+
'Developer preflight gate: missing docs/atom-tree.json. '
|
|
188
|
+
+ 'Run the atom-tree selection/scaffold path before editing game/ so dispatchPacket.requiredContext can disclose selected atom Skills.',
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
if (atomTree.parseError) {
|
|
192
|
+
emitDeny('Developer preflight gate: docs/atom-tree.json is not valid JSON; fix it before editing game/.');
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const atoms = atomTree.atoms;
|
|
162
196
|
|
|
163
197
|
const unlinked = missingLinks(projectDir, atoms);
|
|
164
198
|
if (unlinked.length > 0) {
|
|
@@ -168,10 +202,12 @@ async function main() {
|
|
|
168
202
|
);
|
|
169
203
|
}
|
|
170
204
|
|
|
171
|
-
|
|
205
|
+
const missingEvidence = missingPreflightEvidence(projectDir, atoms);
|
|
206
|
+
if (missingEvidence.length > 0) {
|
|
172
207
|
emitDeny(
|
|
173
208
|
'Developer preflight gate: logs/developer-log.md § Skill Preflight is not filled. '
|
|
174
|
-
+
|
|
209
|
+
+ `Missing required reading evidence: ${missingEvidence.join(', ')}. `
|
|
210
|
+
+ 'Before editing game/, read docs/atom-tree.json and .claude/skills/<atom>/SKILL.md for each selected atom, then fill one exact-path row per atom (what it provides + how you use it). '
|
|
175
211
|
+ 'Then generate placeholders (npm run placeholder:gen) and resume coding.',
|
|
176
212
|
);
|
|
177
213
|
}
|
|
@@ -85,7 +85,7 @@ async function main() {
|
|
|
85
85
|
|
|
86
86
|
emitDeny(
|
|
87
87
|
`Ring 1 Dispatch Path: internal Task lists are blocked during iteration 1 (${toolName}). `
|
|
88
|
-
+ `Use Task / @game-designer / temporary ref-flow atom-selection subagent / @developer spawn instead. Run npm run state:get and follow
|
|
88
|
+
+ `Use Task / @creative-director / @game-designer / temporary ref-flow atom-selection subagent / @developer spawn instead. Run npm run state:get and follow docs/team/collaboration.md § Ring 1 engine scaffold.`,
|
|
89
89
|
);
|
|
90
90
|
}
|
|
91
91
|
|
|
@@ -14,11 +14,6 @@ import fs from 'node:fs';
|
|
|
14
14
|
import path from 'node:path';
|
|
15
15
|
import { fileURLToPath } from 'node:url';
|
|
16
16
|
import { spawnSync } from 'node:child_process';
|
|
17
|
-
import {
|
|
18
|
-
parseHandoffBlock,
|
|
19
|
-
parseHandoffYaml,
|
|
20
|
-
resolveProjectStatePath,
|
|
21
|
-
} from '../../skills/_shared/scripts/state-handoff.mjs';
|
|
22
17
|
|
|
23
18
|
const __filename = fileURLToPath(import.meta.url);
|
|
24
19
|
const __dirname = path.dirname(__filename);
|
|
@@ -123,7 +118,7 @@ function ring1DirectPathContext(projectDir) {
|
|
|
123
118
|
|
|
124
119
|
const loopGuides = {
|
|
125
120
|
clarify:
|
|
126
|
-
'- loop=clarify: Invoke @game-designer for
|
|
121
|
+
'- loop=clarify (split default): Read creative-director-kickoff-guide.md; translate user intent → Creative question (do not forward mechanism spec verbatim). Invoke @creative-director for Micro-Story Spine + north-star + creative-process, then @game-designer for design spec. After GD STOP, spawn temporary ref-flow atom-selection subagent. Do NOT write docs/DESIGN.md or docs/atom-tree.json as orchestrator.',
|
|
127
122
|
build:
|
|
128
123
|
'- loop=build: If scaffold not done, ensure the temporary atom-selection subagent has stopped, then run validate-atom-tree-selection → init-template → verify:contract → verify:lifecycle. Then Invoke @developer for ring 1 build.',
|
|
129
124
|
verify:
|
|
@@ -134,12 +129,12 @@ function ring1DirectPathContext(projectDir) {
|
|
|
134
129
|
return `[PlayCraft Ring 1 Dispatch Path — harness auto-injected]
|
|
135
130
|
iteration=1 loop=${loop}: you are the orchestrator — dispatch role subagents, do NOT inline Designer/Developer work.
|
|
136
131
|
- Do NOT create internal Task lists (TaskCreate / TaskUpdate / TaskList / TaskGet / TaskOutput / TaskStop).
|
|
137
|
-
- Task / @game-designer / temporary ref-flow atom-selection subagent / @developer spawn IS required when the table below says invoke.
|
|
132
|
+
- Task / @creative-director / @game-designer / temporary ref-flow atom-selection subagent / @developer spawn IS required when the table below says invoke.
|
|
138
133
|
- First command: npm run state:get — use next_orchestrator_action + summary; do NOT open docs/project-state.md in full.
|
|
139
134
|
${loopGuide}
|
|
140
135
|
- Game Designer owns docs/DESIGN.md. The temporary atom-selection subagent owns compact docs/atom-tree.json. Developer owns game/ + verifiers on STOP.
|
|
141
136
|
- No Ring 2+ docs, no Reviewer / Artist / TA, no record:mp4 in ring 1.
|
|
142
|
-
See
|
|
137
|
+
See docs/team/collaboration.md § Ring 1 engine scaffold and .cursor/rules/playcraft-orchestrator.mdc.`;
|
|
143
138
|
}
|
|
144
139
|
|
|
145
140
|
function emitAdditionalContext(text) {
|
|
@@ -181,11 +176,6 @@ async function main() {
|
|
|
181
176
|
];
|
|
182
177
|
writeHookLog(projectDir, lines.join('\n'));
|
|
183
178
|
|
|
184
|
-
const { iteration } = readHandoffState(projectDir);
|
|
185
|
-
if (iteration === 1) {
|
|
186
|
-
emitAdditionalContext(ring1DirectPathContext(projectDir));
|
|
187
|
-
}
|
|
188
|
-
|
|
189
179
|
console.error(`prompt #${state.turns} logged`);
|
|
190
180
|
saveState(projectDir, state);
|
|
191
181
|
}
|