@playcraft/cli 0.0.56 → 0.0.58

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 (228) hide show
  1. package/README.md +41 -26
  2. package/REMIX.md +17 -5
  3. package/dist/cli-root-help.js +1 -0
  4. package/dist/commands/build-all.js +10 -9
  5. package/dist/commands/build.js +13 -12
  6. package/dist/commands/create.js +26 -33
  7. package/dist/commands/platform-skills.generated.js +19 -0
  8. package/dist/commands/remix.js +48 -2
  9. package/dist/commands/skills.js +2 -0
  10. package/dist/commands/tools-generation.js +1 -1
  11. package/dist/commands/workspace-runtime.js +54 -0
  12. package/dist/index.js +3 -1
  13. package/dist/project-skills/commands.js +72 -0
  14. package/dist/project-skills/lifecycle.js +28 -0
  15. package/dist/project-skills/local-run.js +112 -0
  16. package/dist/project-skills/local-store.js +149 -0
  17. package/dist/project-skills/messages.js +72 -0
  18. package/dist/project-skills/reconcile.js +62 -0
  19. package/dist/project-skills/remote-cache.js +51 -0
  20. package/dist/project-skills/validation.js +19 -0
  21. package/dist/remix/clone.js +4 -1
  22. package/dist/remix/init-template.js +2 -0
  23. package/dist/remix/local-git.js +56 -0
  24. package/dist/remix/pull.js +66 -0
  25. package/dist/remix/push.js +90 -0
  26. package/dist/utils/agent-api-client.js +54 -17
  27. package/dist/utils/tool-operation-journal.js +54 -0
  28. package/dist/workspace-runtime/codex/app-server.js +395 -0
  29. package/dist/workspace-runtime/codex/config-toml.js +25 -0
  30. package/dist/workspace-runtime/codex/jsonrpc-stdio.js +106 -0
  31. package/dist/workspace-runtime/codex/loopback.js +59 -0
  32. package/dist/workspace-runtime/codex/native-adapter.js +3 -0
  33. package/dist/workspace-runtime/main.js +10 -0
  34. package/dist/workspace-runtime/persistence/journal.js +350 -0
  35. package/dist/workspace-runtime/processes/managed-writes.js +69 -0
  36. package/dist/workspace-runtime/serve.js +111 -0
  37. package/dist/workspace-runtime/server/auth.js +21 -0
  38. package/dist/workspace-runtime/server/dispatch.js +861 -0
  39. package/dist/workspace-runtime/server/execution-group.js +88 -0
  40. package/dist/workspace-runtime/server/http.js +561 -0
  41. package/dist/workspace-runtime/server/lock.js +53 -0
  42. package/dist/workspace-runtime/server/types.js +1 -0
  43. package/dist/workspace-runtime/workspaces/context-error.js +2 -0
  44. package/dist/workspace-runtime/workspaces/file-snapshot.js +213 -0
  45. package/dist/workspace-runtime/workspaces/files.js +143 -0
  46. package/dist/workspace-runtime/workspaces/git.js +242 -0
  47. package/dist/workspace-runtime/workspaces/json5-edit.js +170 -0
  48. package/dist/workspace-runtime/workspaces/parameters.js +272 -0
  49. package/dist/workspace-runtime/workspaces/prepare.js +364 -0
  50. package/dist/workspace-runtime/workspaces/registry.js +107 -0
  51. package/dist/workspace-runtime/workspaces/revisions.js +31 -0
  52. package/package.json +6 -3
  53. package/project-template-v2/.claude/agents/artist.md +82 -0
  54. package/project-template-v2/.claude/agents/developer.md +153 -0
  55. package/project-template-v2/.claude/agents/game-designer.md +264 -0
  56. package/project-template-v2/.claude/agents/refs/artist-art-style-catalog.md +533 -0
  57. package/project-template-v2/.claude/agents/refs/artist-color-audio-recipes.md +153 -0
  58. package/project-template-v2/.claude/agents/refs/artist-dimension-axis.md +27 -0
  59. package/project-template-v2/.claude/agents/refs/artist-master-composite-recipes.md +208 -0
  60. package/project-template-v2/.claude/agents/refs/atom-skill-library.md +81 -0
  61. package/project-template-v2/.claude/agents/refs/developer-impl-cookbook.md +432 -0
  62. package/project-template-v2/.claude/agents/refs/framework-5-component-filter.md +252 -0
  63. package/project-template-v2/.claude/agents/refs/framework-game-feel-juice.md +266 -0
  64. package/project-template-v2/.claude/agents/refs/framework-mda.md +147 -0
  65. package/project-template-v2/.claude/agents/refs/game-designer-gameplay-sufficiency.md +123 -0
  66. package/project-template-v2/.claude/agents/refs/ta-3d-flip-recipe.md +88 -0
  67. package/project-template-v2/.claude/agents/refs/ta-atlas-deliverable-standard.md +67 -0
  68. package/project-template-v2/.claude/agents/refs/ta-batch-pipeline-recipes.md +120 -0
  69. package/project-template-v2/.claude/agents/refs/ta-image-generation-detail.md +300 -0
  70. package/project-template-v2/.claude/agents/refs/ta-image-ops-reference.md +495 -0
  71. package/project-template-v2/.claude/agents/refs/ta-pipeline-cookbook.md +1141 -0
  72. package/project-template-v2/.claude/agents/refs/ta-tools-reference.md +111 -0
  73. package/project-template-v2/.claude/agents/refs/ta-vfx-preset-catalog.md +365 -0
  74. package/project-template-v2/.claude/agents/refs/threejs-cannon-pitfalls.md +412 -0
  75. package/project-template-v2/.claude/agents/reviewer.md +75 -0
  76. package/project-template-v2/.claude/agents/technical-artist.md +86 -0
  77. package/project-template-v2/.claude/hooks/snapshot-milestone.mjs +243 -0
  78. package/project-template-v2/.claude/hooks/user-prompt.mjs +133 -0
  79. package/project-template-v2/.claude/settings.json +33 -0
  80. package/project-template-v2/.claude/skills/brainstorming/SKILL.md +161 -0
  81. package/project-template-v2/.claude/skills/brainstorming/scripts/frame-template.html +270 -0
  82. package/project-template-v2/.claude/skills/brainstorming/scripts/helper.js +177 -0
  83. package/project-template-v2/.claude/skills/brainstorming/scripts/server.cjs +354 -0
  84. package/project-template-v2/.claude/skills/brainstorming/scripts/start-server.sh +148 -0
  85. package/project-template-v2/.claude/skills/brainstorming/scripts/stop-server.sh +56 -0
  86. package/project-template-v2/.claude/skills/brainstorming/scripts/wait-for-selection.sh +62 -0
  87. package/project-template-v2/.claude/skills/brainstorming/spec-document-reviewer-prompt.md +49 -0
  88. package/project-template-v2/.claude/skills/brainstorming/visual-companion.md +309 -0
  89. package/project-template-v2/.claude/skills/playcraft-ad-psychology/SKILL.md +182 -0
  90. package/project-template-v2/.claude/skills/playcraft-art-style-guide/SKILL.md +123 -0
  91. package/project-template-v2/.claude/skills/playcraft-asset-state-sheet/SKILL.md +205 -0
  92. package/project-template-v2/.claude/skills/playcraft-audio-generation/SKILL.md +280 -0
  93. package/project-template-v2/.claude/skills/playcraft-batch-pipeline/SKILL.md +184 -0
  94. package/project-template-v2/.claude/skills/playcraft-build-optimizer/SKILL.md +306 -0
  95. package/project-template-v2/.claude/skills/playcraft-image-generation/SKILL.md +298 -0
  96. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/build-sprite-sheet.template.mjs +123 -0
  97. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/compare-style.template.mjs +254 -0
  98. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/gen-batch-sprite.template.mjs +324 -0
  99. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/gen-batch.template.mjs +97 -0
  100. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/gen-edit-variants.template.mjs +118 -0
  101. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/process-batch.template.mjs +137 -0
  102. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/prompt-cookbook.md +397 -0
  103. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/validate-sprite-sheet.template.mjs +296 -0
  104. package/project-template-v2/.claude/skills/playcraft-image-ops/SKILL.md +122 -0
  105. package/project-template-v2/.claude/skills/playcraft-image-processing/SKILL.md +219 -0
  106. package/project-template-v2/.claude/skills/playcraft-masking/SKILL.md +373 -0
  107. package/project-template-v2/.claude/skills/playcraft-playable-optimization/SKILL.md +161 -0
  108. package/project-template-v2/.claude/skills/playcraft-research/SKILL.md +215 -0
  109. package/project-template-v2/.claude/skills/playcraft-skill-recommender/SKILL.md +382 -0
  110. package/project-template-v2/.claude/skills/playcraft-sprite-generation/SKILL.md +423 -0
  111. package/project-template-v2/.claude/skills/playcraft-sprite-remix/SKILL.md +158 -0
  112. package/project-template-v2/.claude/skills/playcraft-sprite-sheet/SKILL.md +100 -0
  113. package/project-template-v2/.claude/skills/playcraft-storyboard/SKILL.md +167 -0
  114. package/project-template-v2/.claude/skills/playcraft-style-qa/SKILL.md +270 -0
  115. package/project-template-v2/.claude/skills/playcraft-text-rendering/SKILL.md +236 -0
  116. package/project-template-v2/.claude/skills/playcraft-vfx-animation/SKILL.md +130 -0
  117. package/project-template-v2/.claude/skills/playwright-cli/SKILL.md +390 -0
  118. package/project-template-v2/.claude/skills/playwright-cli/references/element-attributes.md +23 -0
  119. package/project-template-v2/.claude/skills/playwright-cli/references/playwright-tests.md +39 -0
  120. package/project-template-v2/.claude/skills/playwright-cli/references/request-mocking.md +87 -0
  121. package/project-template-v2/.claude/skills/playwright-cli/references/running-code.md +240 -0
  122. package/project-template-v2/.claude/skills/playwright-cli/references/session-management.md +226 -0
  123. package/project-template-v2/.claude/skills/playwright-cli/references/spec-driven-testing.md +308 -0
  124. package/project-template-v2/.claude/skills/playwright-cli/references/storage-state.md +275 -0
  125. package/project-template-v2/.claude/skills/playwright-cli/references/test-generation.md +134 -0
  126. package/project-template-v2/.claude/skills/playwright-cli/references/tracing.md +142 -0
  127. package/project-template-v2/.claude/skills/playwright-cli/references/video-recording.md +153 -0
  128. package/project-template-v2/.claude/skills/session-analyzer/SKILL.md +386 -0
  129. package/project-template-v2/.claude/skills/session-analyzer/scripts/execution-breakdown.mjs +182 -0
  130. package/project-template-v2/.claude/skills/session-analyzer/scripts/find-turns.mjs +72 -0
  131. package/project-template-v2/.claude/skills/session-analyzer/scripts/heavy-output.mjs +121 -0
  132. package/project-template-v2/.claude/skills/session-analyzer/scripts/resolve-session.mjs +102 -0
  133. package/project-template-v2/.claude/skills/session-analyzer/scripts/subagent-stats.mjs +127 -0
  134. package/project-template-v2/.claude/skills/session-analyzer/scripts/subagent-tool-timeline.mjs +106 -0
  135. package/project-template-v2/.claude/skills/session-analyzer/scripts/time-gaps.mjs +128 -0
  136. package/project-template-v2/.claude/skills/session-analyzer/scripts/turn-timeline.mjs +67 -0
  137. package/project-template-v2/.claude/snapshot.mjs +263 -0
  138. package/project-template-v2/.playcraft/skills.lock.json +152 -0
  139. package/project-template-v2/CLAUDE.md +146 -0
  140. package/project-template-v2/assets/audio/bgm/.gitkeep +0 -0
  141. package/project-template-v2/assets/audio/sfx/.gitkeep +0 -0
  142. package/project-template-v2/assets/bundles/.gitkeep +0 -0
  143. package/project-template-v2/assets/images/bg/.gitkeep +0 -0
  144. package/project-template-v2/assets/images/reference/.gitkeep +0 -0
  145. package/project-template-v2/assets/images/storyboard/.gitkeep +0 -0
  146. package/project-template-v2/assets/images/tiles/.gitkeep +0 -0
  147. package/project-template-v2/assets/images/ui/.gitkeep +0 -0
  148. package/project-template-v2/assets/images/vfx/.gitkeep +0 -0
  149. package/project-template-v2/assets/models/.gitkeep +0 -0
  150. package/project-template-v2/docs/harness/iteration-1/context-flow.md +254 -0
  151. package/project-template-v2/docs/harness/iteration-1/generate-flow.md +91 -0
  152. package/project-template-v2/docs/harness/iteration-1/ideate-flow.md +214 -0
  153. package/project-template-v2/docs/harness/iteration-1/optimize-flow.md +75 -0
  154. package/project-template-v2/docs/harness/iteration-1/wrapup-flow.md +63 -0
  155. package/project-template-v2/docs/harness/iteration-2/context-flow.md +223 -0
  156. package/project-template-v2/docs/harness/iteration-2/generate-flow.md +129 -0
  157. package/project-template-v2/docs/harness/iteration-2/ideate-flow.md +267 -0
  158. package/project-template-v2/docs/harness/iteration-2/optimize-flow.md +164 -0
  159. package/project-template-v2/docs/harness/iteration-2/wrapup-flow.md +115 -0
  160. package/project-template-v2/docs/harness/orchestrator-flow.md +364 -0
  161. package/project-template-v2/docs/project-state.json +60 -0
  162. package/project-template-v2/docs/project-state.md +72 -0
  163. package/project-template-v2/docs/standards/README.md +225 -0
  164. package/project-template-v2/docs/standards/agent-behavior-standards.md +174 -0
  165. package/project-template-v2/docs/standards/artifacts/design-brief.md +19 -0
  166. package/project-template-v2/docs/standards/artifacts/design.md +22 -0
  167. package/project-template-v2/docs/standards/artifacts/game-code.md +41 -0
  168. package/project-template-v2/docs/standards/artifacts/todo-list.md +41 -0
  169. package/project-template-v2/docs/standards/iter1-agent-behavior-standards.md +343 -0
  170. package/project-template-v2/game/index.ts +18 -0
  171. package/project-template-v2/globals.d.ts +51 -0
  172. package/project-template-v2/index.css +34 -0
  173. package/project-template-v2/index.html +18 -0
  174. package/project-template-v2/main.ts +9 -0
  175. package/project-template-v2/package.json +46 -0
  176. package/project-template-v2/skills/_shared/scripts/dispatch-clear.mjs +31 -0
  177. package/project-template-v2/skills/_shared/scripts/dispatch-set.mjs +86 -0
  178. package/project-template-v2/skills/_shared/scripts/dod-check.mjs +153 -0
  179. package/project-template-v2/skills/_shared/scripts/handoff-append.mjs +70 -0
  180. package/project-template-v2/skills/_shared/scripts/lib/validator-artifacts.mjs +91 -0
  181. package/project-template-v2/skills/_shared/scripts/pipeline/dod-config.mjs +131 -0
  182. package/project-template-v2/skills/_shared/scripts/pipeline/index.mjs +80 -0
  183. package/project-template-v2/skills/_shared/scripts/pipeline/iteration-1-core.mjs +90 -0
  184. package/project-template-v2/skills/_shared/scripts/pipeline/iteration-2-wrap.mjs +93 -0
  185. package/project-template-v2/skills/_shared/scripts/pipeline/iteration-3-visual.mjs +23 -0
  186. package/project-template-v2/skills/_shared/scripts/render-project-state.mjs +230 -0
  187. package/project-template-v2/skills/_shared/scripts/state-advance-stage.mjs +58 -0
  188. package/project-template-v2/skills/_shared/scripts/state-get.mjs +339 -0
  189. package/project-template-v2/skills/_shared/scripts/state-handoff.mjs +39 -0
  190. package/project-template-v2/skills/_shared/scripts/state-set.mjs +94 -0
  191. package/project-template-v2/skills/_shared/scripts/state-store.mjs +783 -0
  192. package/project-template-v2/skills/_shared/scripts/todo-add.mjs +88 -0
  193. package/project-template-v2/skills/_shared/scripts/todo-get.mjs +130 -0
  194. package/project-template-v2/skills/_shared/scripts/todo-remove.mjs +33 -0
  195. package/project-template-v2/skills/_shared/scripts/todo-set.mjs +47 -0
  196. package/project-template-v2/skills/_shared/scripts/verify-asset-code-sync.mjs +268 -0
  197. package/project-template-v2/skills/_shared/scripts/verify-env.mjs +285 -0
  198. package/project-template-v2/skills/_shared/scripts/verify-placeholders.mjs +161 -0
  199. package/project-template-v2/skills/playable-autoplay/SKILL.md +176 -0
  200. package/project-template-v2/skills/playable-autoplay/agents/openai.yaml +4 -0
  201. package/project-template-v2/skills/playable-debug/SKILL.md +116 -0
  202. package/project-template-v2/skills/playable-debug/agents/openai.yaml +4 -0
  203. package/project-template-v2/skills/playable-debug/references/debug-config.md +40 -0
  204. package/project-template-v2/skills/playable-record/SKILL.md +140 -0
  205. package/project-template-v2/skills/playable-record/scripts/lib/dev-server.mjs +104 -0
  206. package/project-template-v2/skills/playable-record/scripts/lib/record-audio-bridge.js +141 -0
  207. package/project-template-v2/skills/playable-record/scripts/record-playable.mjs +425 -0
  208. package/project-template-v2/skills/playable-record/scripts/verify-contract.mjs +261 -0
  209. package/project-template-v2/skills/playable-record/scripts/verify-firstwin.mjs +398 -0
  210. package/project-template-v2/skills/playable-record/scripts/verify-fusion.mjs +322 -0
  211. package/project-template-v2/skills/playable-record/scripts/verify-lifecycle.mjs +105 -0
  212. package/project-template-v2/skills/playable-record/scripts/verify-vlm-video.mjs +230 -0
  213. package/project-template-v2/skills/playable-validate/SKILL.md +61 -0
  214. package/project-template-v2/skills/playable-validate/validation-rules.md +14 -0
  215. package/project-template-v2/skills/playable-verify-ui/SKILL.md +63 -0
  216. package/project-template-v2/skills/playable-verify-ui/scripts/lib/__init__.py +1 -0
  217. package/project-template-v2/skills/playable-verify-ui/scripts/lib/config_expr.js +218 -0
  218. package/project-template-v2/skills/playable-verify-ui/scripts/lib/node_utils.js +51 -0
  219. package/project-template-v2/skills/playable-verify-ui/scripts/lib/profile_loader.py +59 -0
  220. package/project-template-v2/skills/playable-verify-ui/scripts/lib/report.py +106 -0
  221. package/project-template-v2/skills/playable-verify-ui/scripts/lib/runtime_contract.js +116 -0
  222. package/project-template-v2/skills/playable-verify-ui/scripts/verify_fetch_antipatterns.py +59 -0
  223. package/project-template-v2/skills/playable-verify-ui/scripts/verify_hardcoded_layout.js +64 -0
  224. package/project-template-v2/skills/playable-verify-ui/scripts/verify_runtime_contract.js +58 -0
  225. package/project-template-v2/skills/playable-verify-ui/scripts/verify_text_overlap.py +333 -0
  226. package/project-template-v2/ta-workspace/scripts/.gitkeep +0 -0
  227. package/project-template-v2/tsconfig.json +20 -0
  228. package/project-template-v2/vite.config.ts +27 -0
@@ -0,0 +1,343 @@
1
+ # Iteration 1 Agent Behavior Standards
2
+
3
+ > 迭代1的 agent 行为评价标准。本文按 flow 拆,只写“这个 flow 下 agent 行为是否合格”的判断标准;详细执行步骤仍在 `docs/harness/iteration-1/*-flow.md`。
4
+
5
+ ## 迭代目标
6
+
7
+ 迭代1的目标是完成主核心玩法闭环:从用户初始意图收敛出核心玩法方向,把方向转成可派发的 todo 与 atom 复用上下文,逐个实现玩法子任务,并最终形成可 build、可自动演示、可验证、可录像的最小 playable。
8
+
9
+ 本迭代只评价核心玩法是否成立和运行时闭环是否可证明。不把包装、广告转化链路、最终视觉质量、复杂关卡扩展或生产级资产完整性纳入完成标准。
10
+
11
+ ## 全 flow 执行过程诊断
12
+
13
+ 以下评价点适用于迭代1所有 flow,不用在每个 flow 里重复展开。
14
+
15
+ - 行为失败:是否出现工具/bash 等行为失败;失败后是否记录原因和下一步处理。
16
+ - 参数错误:是否出现工具或命令参数用错;同一参数错误重复出现时,应视为执行质量问题。
17
+ - 重试健康度:同一 verifier、tool 或写入动作多次未通过时,是否停止复盘,而不是继续硬跑。
18
+ - 耗时异常:单个行为耗时明显过长时,是否产生了相称的信息、产物或证据。
19
+ - 时间分布:read、update/edit、工具调用、验证、用户等待大致各花了多久。
20
+ - 上下文准备时长:从 dispatch 到“已读完必要上下文,可以开始产出”花了多久。
21
+ - 记录要求:失败、重复重试和明显耗时异常应进入 handoff / run notes,供调度者判断继续、重派或修改 flow。
22
+
23
+ ## 迭代调度者工作预期
24
+
25
+ 以下评价点适用于迭代1所有 flow,不用在每个 flow 里重复展开。
26
+
27
+ - 能识别 active dispatch / pending user input / todo pool / stage exit,不重复派发或跳过未完成工单。
28
+ - 负责把当前 stage 目标收窄成 dispatch,不替 subagent 产出 design、todo、code 或 review verdict。
29
+ - relay 用户输入时保留原问题、选项、推荐项和影响说明,不自行扩写设计内容。
30
+ - 根据 handoff、artifact 和 verifier 结果更新 todo / gate / stage,不从口头总结直接推进。
31
+ - blocker、failed evidence 或执行诊断异常出现时,能暂停、重派或改 flow,而不是硬推进。
32
+
33
+ ## ideate
34
+
35
+ Flow 目标:
36
+
37
+ - 把用户需求收敛成核心玩法方向。
38
+ - 本阶段只评价核心玩法是否清楚,不评价实现计划、包装、视觉终稿或 CTA (Call To Action, 行动召唤)。
39
+
40
+ skill/文档引用:
41
+
42
+ - `docs/harness/iteration-1/ideate-flow.md` 必读
43
+ - brainstorming - 需加载
44
+ - playcraft-skill-recommender - 需加载
45
+ - `.claude/agents/refs/game-designer-gameplay-sufficiency.md` - 需阅读
46
+ - `.claude/agents/refs/atom-skill-library.md` - 需阅读
47
+
48
+ 派发信息评价:
49
+
50
+ - role 必须是 `game-designer`。
51
+ - `requiredContext` 至少包含 ideate flow、用户原始需求和预期产物路径。
52
+ - 用户意图应原语义转发,不能被调度者润色成新的玩法结论。
53
+ - guidance 只写本阶段边界和验收信号,不重复 flow 的完整步骤,也不外行指导 designer 如何逐句思考。
54
+ - forbiddenTasks 明确禁止实现、技术选型、包装、CTA、视觉终稿和复杂关卡展开。
55
+
56
+ 预期流程:
57
+
58
+ - 先 `state:get -- --json dispatch`,确认自己是 active workticket 的 `game-designer`。
59
+ - 先做 web research 与 skill library exploration,并把发现以来源标记沉淀到 brief。
60
+ - skill exploration 体现 gettags / filter / match / role / keyword 等分层探索,必要时读强相关 atom,不是一次 match 后直接下结论。
61
+ - brainstorm 先自答研究已能决定的问题,再批量提出可选择、可比较、带推荐和影响说明的问题。
62
+ - 需要用户输入时写 `pendingUserInput` 并暂停,交给 orchestrator relay;中途 answer 不等于最终 user-confirm。
63
+ - 写 `docs/design.md` 前完成 gameplay sufficiency 自检,有不通过项时回到定点补充。
64
+ - 最后由 orchestrator 向用户确认核心玩法方向,确认后才能视为 ideate 可退出。
65
+
66
+ 不符合预期的流程:
67
+
68
+ - brief 是事后总结,看不到探索路径。
69
+ - design 写成实现方案或素材方案。
70
+ - 中途用户回答被当成最终 user-confirm。
71
+ - 玩法结论和用户输入语义不一致,且没有记录取舍原因。
72
+ - 重复问用户相似问题、或选项不可比较,视为 brainstorm 质量问题。
73
+ - 在未完成自检或未处理用户输入前写 design,视为流程跳步。
74
+ - discovery 长时间无有效发现时,应记录 no-match / low-confidence 与下一步选择。
75
+
76
+ 产物评价引用:
77
+
78
+ - `docs/standards/artifacts/design-brief.md`
79
+ - `docs/standards/artifacts/design.md`
80
+
81
+ 本 flow 额外产物边界:
82
+
83
+ - `docs/design.md` 只写核心玩法体验:玩家目标、单次操作、系统反馈、下一次决策、最简成功失败。
84
+ - 允许写玩法完整性需要的最小规则和反馈,但不写 runtime 文件、类名、函数签名、事件 payload、engine 初始化。
85
+ - 迭代1不应展开包装、广告话术、复杂关卡细节、最终视觉风格或后续商业转化链路。
86
+
87
+ State / Handoff 评价:
88
+
89
+ - `pendingUserInput` 的 id、prompt、options、recommended、impact 足够让 orchestrator 原样 relay。
90
+ - 用户回答被写回 brief 后,当前 pending input 应被 resolved。
91
+ - 最终退出前 handoff 引用 `docs/design-brief.md` 和 `docs/design.md`,并说明是否已等待最终用户确认。
92
+
93
+ ## context
94
+
95
+ Flow 目标:
96
+
97
+ - 把已确认的核心玩法转成 generate 可使用的计划等价物:atom-tree、todo_list 和机器态 todo 池。
98
+ - 本阶段锁定引擎与核心动作,为每个玩法子任务建立可派发、可验证、可复用的任务卡。
99
+
100
+ skill/文档引用:
101
+
102
+ - `docs/harness/iteration-1/context-flow.md` 必读
103
+ - playcraft-skill-recommender - 需加载
104
+ - `.claude/agents/refs/atom-skill-library.md` - 需阅读
105
+ - `docs/design.md` - 需阅读
106
+
107
+ 派发信息评价:
108
+
109
+ - role 必须是 `game-designer`,并明确本阶段允许写 todo。
110
+ - flow必须正确是 `docs/harness/iteration-1/context-flow.md`
111
+
112
+ 预期流程:
113
+
114
+ - 从 design 和 brief 提取 intent,使用 recommender 生成或刷新 `docs/atom-tree.json`。
115
+ - 生成/刷新 atomtree 的时候是使用了desine里面披露的关键字或者关键atom作为起点的
116
+ - 选择 atom 时区分轻量筛选与强相关深读;强相关 atom 的 `ref/` 源是 API (Application Programming Interface, 应用程序编程接口) / event / config 的权威。
117
+ - 根据 tags、DESC 语义、复用程度、依赖完整性和玩法实体/机制层差异进行评分筛选。
118
+ - 玩法相关性是其选择的第一原因,其次才是引擎。引擎不一致就一定是 ref 等级 1
119
+ - 递归补齐依赖,完成 selected atoms 与 link,再把复用结论落到任务卡。
120
+ - 在 generate 前锁定 engine 和 coreAction;锁定后不应在 generate 阶段临时更换。
121
+ - todo 拆分按玩家可感知玩法子任务,每个任务卡都能独立派发、独立验收。
122
+ - todo 不应该过分大也不应该过分小
123
+ - 能把 design intent 转成可执行 contract,而不是把设计文档改写成开发口号。
124
+ - 能区分“atom 可复用”“仅作参考”“不适用”,并记录原因。
125
+ - 拆 todo 不遗漏单玩法、多玩法衔接、最简成功失败这些迭代1核心范围。
126
+ - 不把 context 做成代码设计细节堆叠,也不把 acceptance 写成主观愿望。
127
+
128
+ 不符合预期的流程:
129
+
130
+ - recommender 命令失败、选择校验失败、link 失败后没有记录失败原因和是否可恢复。
131
+ - 多次 filter / match 没有强相关结果,仍不记录 low-confidence、从零实现或 design-only 的理由。
132
+ - 花大量时间深读无关 atom ref,但没有形成任务卡复用约束。
133
+ - todo 池只有摘要,没有任务卡全文/任务卡全文过于详细
134
+ - dispatch 只能手抄上下文,无法回链 `docs/todo_list.md#todo-<id>`。
135
+ - atom 选择与设计意图脱节,或只选 engine skeleton 忽略玩法/输入/反馈层。
136
+ - 拆 todo 时加入未确认玩法或后续迭代包装内容。
137
+ - `docs/atom-tree.json` 缺失且未说明原因。
138
+ - todo 池未覆盖本迭代所有玩法子任务,或 todo acceptance 不可验证。
139
+
140
+ 产物评价引用:
141
+
142
+ - `docs/standards/artifacts/todo-list.md`
143
+
144
+ 本 flow 额外产物边界:
145
+
146
+ - `docs/todo_list.md` 是 generate 的 plan source,不是普通备忘录。
147
+ - todo 可包含必要的 asset binding 约束,但不生产最终资产、不展开视觉终稿。
148
+ - 本阶段应该只聚焦核心的玩法而不是制作完整的游戏,需评价其是否有聚焦玩法核心
149
+
150
+ State / Handoff 评价:
151
+
152
+ - 机器态 todo 池非空,且每个 todo 的 `requiredContext` 指向同名任务卡锚点。
153
+ - shared decisions 写入 engine 和 coreAction 时,应有 skill match 或 design evidence 支撑。
154
+ - handoff 引用 atom-tree、todo_list,并说明 todo seed 数量、覆盖范围和无法覆盖的缺口。
155
+
156
+ ## generate
157
+
158
+ Flow 目标:
159
+
160
+ - 按 todo 池逐个实现核心玩法闭环。
161
+ - 每个 dispatch 只完成当前 todo 的 acceptance;本阶段结束前当前 iteration todo 必须清空。
162
+
163
+ skill/文档引用:
164
+
165
+ - `docs/harness/iteration-1/generate-flow.md` 必读
166
+ - playcraft-skill-recommender - 需要确认 atom/ref/scaffold 使用方式时加载
167
+ - 当前 dispatch 的 `docs/todo_list.md#todo-<id>` - 必读
168
+ - 任务卡指向的 `docs/design.md` 章节和 atom `SKILL.md` / `ref/` 源 - 必读
169
+
170
+ 派发信息评价:
171
+
172
+ - role 必须是 `developer`,且一次只派一个 todo。
173
+ - dispatch 继承或显式提供 goal、acceptance、allowedFiles、forbiddenTasks、requiredContext、verifier。
174
+ - `requiredContext` 必须包含对应任务卡全文锚点,不能只给 todo 摘要。
175
+ - allowedFiles 收窄到当前 todo 需要的 runtime 文件
176
+
177
+ 预期流程:
178
+
179
+ - developer 先确认 dispatch,再读任务卡全文、设计章节、现有代码和相关 atom ref。
180
+ - 改动前列清将改文件并确认在 allowedFiles 内;缺合约或意图不清时停止写 blocker。
181
+ - 实现只闭合当前 acceptance,不顺手做未来任务或重写整个项目。
182
+ - 复用 atom 时遵守 ref 源里的真实 API、event、config 和 asset binding。
183
+ - 不会认为ref等级1就完全没价值,还是会去了解其实现
184
+ - 对于参考atom里面的参数、配置需比较敏感,这些是质量保证的重点
185
+ - 写代码时候会先了解当前的实现
186
+ - 不会无脑加代码,会斟酌考虑框架 & 健壮性
187
+ - 写完之后会验证,而不是直接宣告做完了
188
+ - 本地验证使用 dispatch 指定 verifier;done 只能来自验证结果和 artifact,不是总结。
189
+ - STOP 时 append handoff,由 orchestrator 判断 todo done / failed / retry。
190
+ - 不改写 `docs/design.md` 已确认的玩家体验。
191
+ - 不为通过脚本 fake success;玩家可见闭环必须实际可达。
192
+ - 能把失败归类为实现 bug、设计缺口、资产缺口或环境问题,并在 handoff 中说明。
193
+ - 发现本阶段明显漏拆 todo 时,只在被授权范围内补 generate todo,不加后续迭代工作。
194
+
195
+ 不符合预期的流程:
196
+
197
+ - 一次 dispatch 做多个 todo。
198
+ - 从 dispatch 摘要猜任务,未读任务卡全文。
199
+ - 同一 verifier 多次失败后继续无差别改代码,没有复盘失败 key。
200
+ - 参数错误、allowedFiles 越界、未读任务卡就修改。
201
+ - read 阶段明显不足导致返工,但没有记录缺失上下文并补读。
202
+ - build 通过但核心玩家路径不可达。
203
+ - 为通过脚本 fake success,或改写已确认设计语义。
204
+ - 越过 design / allowedFiles / forbiddenTasks。
205
+ - 当前 iteration todo 仍有 pending / in_progress / failed 时推进到 optimize。
206
+ - done todo 没有 verifier 或运行时证据。
207
+ - 不会读了一堆代码之后写的完全没关系
208
+ - 不应该执行了scaffold之后却在重新写代码
209
+
210
+ 产物评价引用:
211
+
212
+ - `docs/standards/artifacts/game-code.md`
213
+
214
+ 本 flow 额外产物边界:
215
+
216
+ - `game/**` 应呈现核心玩法 runtime loop,可以使用 placeholder / minimal visual 支撑验证。
217
+ - 不要求最终视觉质量、商业包装、广告 CTA 或完整关卡内容。
218
+ - 多玩法项目应至少让各玩法子任务的核心路径都可被验证。
219
+
220
+ State / Handoff 评价:
221
+
222
+ - developer 不自行 `todo:set`,不清 dispatch,不推进 stage。
223
+ - handoff 包含改动文件、acceptanceResults、verifier 结果、artifactRefs 或 blockers。
224
+ - orchestrator 根据 handoff 和 verifier 更新 todo 状态,直到当前 iteration todo 全部 done。
225
+
226
+ ## optimize
227
+
228
+ Flow 目标:
229
+
230
+ - 把 generate 产出的 game 收敛成可自动演示、可验证、可录像的交付物。
231
+ - 本阶段聚焦运行时和视频闭环,不修改已确认核心玩法。
232
+
233
+ skill/文档引用:
234
+
235
+ - `docs/harness/iteration-1/optimize-flow.md` 必读
236
+ - `.claude/agents/developer.md` 必读
237
+ - playable-record - 需加载
238
+ - playable-debug - first win / autoplay 排障时加载
239
+ - playable-validate - 需要 runtime / video validation loop 时加载
240
+ - `skills/_shared/scripts/pipeline/dod-config.mjs` - 需阅读
241
+
242
+ 派发信息评价:
243
+
244
+ - 默认 role 是 `developer`;DoD (Definition of Done, 完成定义) 失败需要路由时,根据 failure key 和 owner 重新派发。
245
+ - dispatch 明确本次修复哪个 DoD key 或验证缺口。
246
+ - `requiredContext` 包含 optimize flow、失败报告、相关 game 文件和运行时/录像 skill。
247
+ - forbiddenTasks 禁止重做玩法设计、扩大视觉包装、把 debug workaround 当交付结果。
248
+
249
+ 预期流程:
250
+
251
+ - 先 build 并修复报错,再接入/验证 `window.__playable` runtime contract。
252
+ - autoplay 必须能自动跑完整核心闭环并到达 ENDCARD,不能靠人工操作补齐。
253
+ - 依次运行 contract、first win、fusion 等验证;fusion 无适用对象时应明确 no-op。
254
+ - 录像使用 `record:mp4` headed 60fps 路径,产出 MP4 (MPEG-4 Part 14, 数字多媒体容器格式) 证据。
255
+ - 需要语义视频评审时使用 VLM (Vision-Language Model, 视觉语言模型) video verifier,并保留结果路径。
256
+ - DoD 收尾以 `dod:check` 或等价 evidence package 为准;无脚本 DoD 需要 orchestrator 明确确认。
257
+ - 能按失败 key 定位:build、contract、firstLevelWin、fusion、autoplay、record。
258
+ - 修复优先恢复 runtime contract 和状态可达性,不是只让录像脚本不报错。
259
+ - 不把自动演示改成绕过核心玩法的直达成功。
260
+ - handoff 逐项报告 pass/fail、artifactRefs 和 remaining blockers。
261
+
262
+ 不符合预期的流程:
263
+
264
+ - 跳过 autoplay 直接人工录屏。
265
+ - build、contract 或 first win 失败仍标 DoD 通过。
266
+ - 录像存在但没有核心玩法过程。
267
+ - 为了 first win 直接跳到 ENDCARD。
268
+ - 录制失败后不先检查 contract / first win,而是连续重复 record。
269
+ - build 报错、端口占用、浏览器安装、ffmpeg 缺失等环境问题和代码问题混在一起。
270
+ - verify 参数多次用错或同一失败 key 多轮无进展,仍不暂停重派或改 flow。
271
+ - 新增玩法、重写设计、补广告包装或做最终视觉质量环。
272
+ - MP4 缺失,或 handoff / validate 路径无法证明录像对应当前版本。
273
+
274
+ 产物评价引用:
275
+
276
+ - `docs/standards/artifacts/game-code.md`
277
+ - `docs/standards/artifacts/recording-evidence.md`
278
+
279
+ 本 flow 额外产物边界:
280
+
281
+ - 可接受优化是验证闭环、自动演示、稳定录制和小范围 bug fix。
282
+ - 不接受在 optimize 阶段新增玩法、重写设计、补广告包装或做最终视觉质量环。
283
+
284
+ State / Handoff 评价:
285
+
286
+ - 有脚本 DoD 由验证结果写入;autoplay 这类无脚本 DoD 由 orchestrator 基于证据显式确认。
287
+ - failed DoD 不应被手动改成 passed;需先修复并重跑或记录 blocker。
288
+ - handoff 应说明各 DoD key 的状态,并引用 `validate/**` 与 `recordings/*.mp4`。
289
+
290
+ ## wrapup
291
+
292
+ Flow 目标:
293
+
294
+ - 回收迭代1运行态副作用,刷新项目入口文档,让后续 agent 看到真实工程状态。
295
+ - 本 flow 不派发角色;由 orchestrator / 脚本执行。
296
+
297
+ skill/文档引用:
298
+
299
+ - `docs/harness/iteration-1/wrapup-flow.md` 必读
300
+ - `docs/harness/orchestrator-flow.md` 必读
301
+ - `package.json` - 需阅读
302
+ - `npm run state:get` 输出 - 需阅读
303
+ - 当前目录中的关键产物与 runtime 入口 - 需核对
304
+
305
+ 派发信息评价:
306
+
307
+ - 本 flow 无 subagent dispatch;如果出现角色派发,应能解释为什么 flow 目标已被扩展,否则视为越界。
308
+ - 不应把 wrapup 写成 reviewer 或 developer 的新工作票。
309
+
310
+ 预期流程:
311
+
312
+ - 检查并回收 dev server、record 进程、临时端口占用和不需要留存的临时产物。
313
+ - 保留交付证据,不删除本迭代验证所需 MP4 / validate artifact。
314
+ - 刷新 `CLAUDE.md` 时只写当前工程事实:包命令、入口、状态与设计产物、目录地图、全员边界、关键缺口。
315
+ - `CLAUDE.md` 不复制调度剧本、完整 todo 池、handoff 历史、未来迭代细节或 role card 全文。
316
+ - orchestrator 以事实核对为主,不借 wrapup 修改设计、代码或验证结论。
317
+ - 能区分“入口速览应记录的稳定事实”和“state/handoff 才该承载的运行态细节”。
318
+ - 如果发现 todo 未清空或 DoD 未通过,应阻塞推进而不是把缺口写进 CLAUDE 后继续。
319
+
320
+ 不符合预期的流程:
321
+
322
+ - `CLAUDE.md` 写成流程手册或状态历史。
323
+ - 删除了需要保留的录像/验证证据。
324
+ - todo 或 DoD 未完成仍推进阶段。
325
+ - 清理操作耗时异常时,没有说明卡在端口、进程、文件还是验证产物判定。
326
+ - 更新 `CLAUDE.md` 前未覆盖 package、入口、state、关键产物和目录地图,导致事实错误。
327
+ - 执行破坏性交付证据的清理。
328
+ - 仍有悬挂 dev / record 进程且没有明确不可清理原因。
329
+
330
+ 产物评价引用:
331
+
332
+ - 暂无独立 artifact 标准;按 wrapup flow 的入口卡片规则评价 `CLAUDE.md`。
333
+
334
+ 本 flow 额外产物边界:
335
+
336
+ - `CLAUDE.md` 是项目速览,不是第二份 pipeline spec。
337
+ - 只刷新当前目录事实和少量关键缺口;不要写过程回忆录。
338
+
339
+ State / Handoff 评价:
340
+
341
+ - 进入下一迭代前,当前 iteration todo 必须全部 done。
342
+ - wrapup 完成后 stage advance 应通过 `todosCleared` 等硬门槛。
343
+ - 如仍有悬挂进程、未清理资源或文档事实不一致,不得推进。
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Placeholder until `playcraft remix init-template` applies an engine pack.
3
+ * Safe to replace — see game/.playcraft-scaffold-pending
4
+ */
5
+
6
+ export function startGame(parentId: string): { destroy?: (removeCanvas?: boolean) => void } {
7
+ const parent = document.getElementById(parentId);
8
+ const message = 'Engine not scaffolded. Run: playcraft remix init-template --from-atom-tree';
9
+ if (parent) {
10
+ parent.innerHTML = `<p style="font-family:system-ui,sans-serif;padding:2rem;color:#888">${message}</p>`;
11
+ }
12
+ console.warn(`[playcraft] ${message}`);
13
+ return {
14
+ destroy() {
15
+ if (parent) parent.innerHTML = '';
16
+ },
17
+ };
18
+ }
@@ -0,0 +1,51 @@
1
+ declare module "*.png" {
2
+ const src: string;
3
+ export default src;
4
+ }
5
+
6
+ declare module "*.webp" {
7
+ const src: string;
8
+ export default src;
9
+ }
10
+
11
+ declare module "*.jpg" {
12
+ const src: string;
13
+ export default src;
14
+ }
15
+
16
+ declare module "*.jpeg" {
17
+ const src: string;
18
+ export default src;
19
+ }
20
+
21
+ declare module "*.svg" {
22
+ const src: string;
23
+ export default src;
24
+ }
25
+
26
+ declare module "*.gif" {
27
+ const src: string;
28
+ export default src;
29
+ }
30
+
31
+ declare module "*.mp3" {
32
+ const src: string;
33
+ export default src;
34
+ }
35
+
36
+ declare module "*.ogg" {
37
+ const src: string;
38
+ export default src;
39
+ }
40
+
41
+ declare module "*.wav" {
42
+ const src: string;
43
+ export default src;
44
+ }
45
+
46
+ declare module "*.m4a" {
47
+ const src: string;
48
+ export default src;
49
+ }
50
+
51
+ declare const __DEV__: boolean;
@@ -0,0 +1,34 @@
1
+ *,
2
+ *::before,
3
+ *::after {
4
+ margin: 0;
5
+ padding: 0;
6
+ box-sizing: border-box;
7
+ -webkit-tap-highlight-color: transparent;
8
+ }
9
+
10
+ html,
11
+ body {
12
+ width: 100%;
13
+ height: 100%;
14
+ overflow: hidden;
15
+ background: #000;
16
+ -webkit-user-select: none;
17
+ user-select: none;
18
+ -webkit-touch-callout: none;
19
+ overscroll-behavior: none;
20
+ touch-action: none;
21
+ }
22
+
23
+ #game-container {
24
+ width: 100%;
25
+ height: 100%;
26
+ padding-top: env(safe-area-inset-top);
27
+ padding-right: env(safe-area-inset-right);
28
+ padding-bottom: env(safe-area-inset-bottom);
29
+ padding-left: env(safe-area-inset-left);
30
+ }
31
+
32
+ canvas {
33
+ display: block;
34
+ }
@@ -0,0 +1,18 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta
6
+ name="viewport"
7
+ content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
8
+ />
9
+ <meta name="apple-mobile-web-app-capable" content="yes" />
10
+ <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
11
+ <meta name="format-detection" content="telephone=no" />
12
+ <title>PlayCraft Playable</title>
13
+ </head>
14
+ <body>
15
+ <div id="game-container"></div>
16
+ <script type="module" src="/main.ts"></script>
17
+ </body>
18
+ </html>
@@ -0,0 +1,9 @@
1
+ import "./index.css";
2
+ import { startGame } from "./game/index";
3
+
4
+ let game = startGame("game-container");
5
+
6
+ window.addEventListener("resize", () => {
7
+ game.destroy?.(true);
8
+ game = startGame("game-container");
9
+ });
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "playcraft-game",
3
+ "version": "0.1.0",
4
+ "playcraftTemplateVersion": "0.4.0-alpha.0",
5
+ "description": "PlayCraft Playable Ads project",
6
+ "private": true,
7
+ "scripts": {
8
+ "dev": "vite",
9
+ "build": "vite build",
10
+ "preview": "vite preview",
11
+ "typecheck": "tsc --noEmit",
12
+ "state:get": "node skills/_shared/scripts/state-get.mjs --root=.",
13
+ "state:set": "node skills/_shared/scripts/state-set.mjs --root=.",
14
+ "stage:advance": "node skills/_shared/scripts/state-advance-stage.mjs --root=.",
15
+ "todo:add": "node skills/_shared/scripts/todo-add.mjs --root=.",
16
+ "todo:get": "node skills/_shared/scripts/todo-get.mjs --root=.",
17
+ "todo:remove": "node skills/_shared/scripts/todo-remove.mjs --root=.",
18
+ "todo:set": "node skills/_shared/scripts/todo-set.mjs --root=.",
19
+ "dispatch:set": "node skills/_shared/scripts/dispatch-set.mjs --root=.",
20
+ "dispatch:clear": "node skills/_shared/scripts/dispatch-clear.mjs --root=.",
21
+ "handoff:append": "node skills/_shared/scripts/handoff-append.mjs --root=.",
22
+ "dod:check": "node skills/_shared/scripts/dod-check.mjs --root=.",
23
+ "verify:env": "node skills/_shared/scripts/verify-env.mjs --root=.",
24
+ "verify:contract": "node skills/playable-record/scripts/verify-contract.mjs --root=. --use-dev",
25
+ "verify:lifecycle": "node skills/playable-record/scripts/verify-lifecycle.mjs --root=. --use-dev",
26
+ "verify:firstwin": "node skills/playable-record/scripts/verify-firstwin.mjs --root=. --use-dev",
27
+ "verify:fusion": "node skills/playable-record/scripts/verify-fusion.mjs --root=.",
28
+ "verify:vlm-video": "node skills/playable-record/scripts/verify-vlm-video.mjs --root=.",
29
+ "verify:placeholders": "node skills/_shared/scripts/verify-placeholders.mjs --root=.",
30
+ "verify:asset-sync": "node skills/_shared/scripts/verify-asset-code-sync.mjs --root=.",
31
+ "verify:runtime-contract": "node skills/playable-verify-ui/scripts/verify_runtime_contract.js --root=.",
32
+ "verify:hardcoded-layout": "node skills/playable-verify-ui/scripts/verify_hardcoded_layout.js",
33
+ "record:mp4": "node skills/playable-record/scripts/record-playable.mjs --root=. --use-dev",
34
+ "record:mp4:install": "playwright install chromium"
35
+ },
36
+ "engines": {
37
+ "node": ">=20"
38
+ },
39
+ "dependencies": {},
40
+ "devDependencies": {
41
+ "@types/node": "^22.19.8",
42
+ "playwright": "^1.59.0",
43
+ "typescript": "^5.9.3",
44
+ "vite": "^7.1.3"
45
+ }
46
+ }
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * dispatch:clear — clear the current subagent workticket.
4
+ *
5
+ * Usage:
6
+ * npm run dispatch:clear
7
+ */
8
+
9
+ import { resolve } from 'node:path';
10
+ import { clearDispatch } from './state-store.mjs';
11
+
12
+ function parseArgs(argv) {
13
+ const opts = { root: process.cwd() };
14
+ for (const arg of argv) {
15
+ if (arg === '--') continue;
16
+ if (arg.startsWith('--root=')) { opts.root = arg.slice('--root='.length); continue; }
17
+ if (arg === '--help' || arg === '-h') {
18
+ console.log('Usage: dispatch-clear.mjs [--root=.]');
19
+ process.exit(0);
20
+ }
21
+ }
22
+ return opts;
23
+ }
24
+
25
+ function main() {
26
+ const opts = parseArgs(process.argv.slice(2));
27
+ clearDispatch(resolve(opts.root));
28
+ console.log('[dispatch:clear] dispatch cleared');
29
+ }
30
+
31
+ main();
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * dispatch:set — replace the current subagent workticket.
4
+ *
5
+ * Usage:
6
+ * npm run dispatch:set -- id=core-action-v1 role=developer goal="..." \
7
+ * allowedFiles="game/**" acceptance="feedback visible;progress+1" --mark-todo
8
+ * npm run dispatch:set -- id=stage:ideate role=game-designer goal="lock core gameplay"
9
+ */
10
+
11
+ import { resolve } from 'node:path';
12
+ import { readState, setDispatch, setDispatchAndMarkTodoState } from './state-store.mjs';
13
+
14
+ function parseArgs(argv) {
15
+ const opts = { root: process.cwd(), kv: {}, markTodo: false };
16
+ for (const arg of argv) {
17
+ if (arg === '--') continue;
18
+ if (arg.startsWith('--root=')) { opts.root = arg.slice('--root='.length); continue; }
19
+ if (arg === '--mark-todo') { opts.markTodo = true; continue; }
20
+ if (arg === '--help' || arg === '-h') {
21
+ console.log('Usage: dispatch-set.mjs [--root=.] id=<todo-or-stage-id> role=<role> goal="..." [guidance="..."] [skillHints="a;b"] [requiredContext="a;b"] [contextReuse="<key-or-note>"] [allowedFiles="a;b"] [forbiddenTasks="a;b"] [acceptance="a;b"] [verifier="..."] [--mark-todo]');
22
+ process.exit(0);
23
+ }
24
+ const m = arg.match(/^([a-zA-Z0-9_]+)=([\s\S]*)$/);
25
+ if (m) opts.kv[m[1]] = m[2];
26
+ }
27
+ return opts;
28
+ }
29
+
30
+ function isRealTodoId(id) {
31
+ return id && id !== 'none' && !id.startsWith('stage:');
32
+ }
33
+
34
+ function hasKv(kv, key) {
35
+ return Object.prototype.hasOwnProperty.call(kv, key);
36
+ }
37
+
38
+ function main() {
39
+ const opts = parseArgs(process.argv.slice(2));
40
+ const root = resolve(opts.root);
41
+ const id = opts.kv.id || opts.kv.activeTodoId;
42
+
43
+ if (!id) { console.error('[dispatch:set] id= is required'); process.exit(1); }
44
+
45
+ const currentState = readState(root);
46
+ const todo = isRealTodoId(id)
47
+ ? currentState.todos.find((t) => t.id === id && t.iteration === currentState.pipeline.iteration)
48
+ ?? currentState.todos.find((t) => t.id === id)
49
+ : null;
50
+
51
+ const role = opts.kv.role || todo?.role;
52
+ if (!role) { console.error('[dispatch:set] role= is required'); process.exit(1); }
53
+
54
+ const dispatch = {
55
+ activeTodoId: id,
56
+ role,
57
+ goal: hasKv(opts.kv, 'goal') ? opts.kv.goal : todo?.goal || todo?.title || '',
58
+ guidance: hasKv(opts.kv, 'guidance') ? opts.kv.guidance : '',
59
+ skillHints: hasKv(opts.kv, 'skillHints') ? opts.kv.skillHints : [],
60
+ requiredContext: hasKv(opts.kv, 'requiredContext') ? opts.kv.requiredContext : todo?.requiredContext || [],
61
+ contextReuse: hasKv(opts.kv, 'contextReuse')
62
+ ? opts.kv.contextReuse
63
+ : opts.kv.contextReuseKey || todo?.contextReuse || '',
64
+ allowedFiles: hasKv(opts.kv, 'allowedFiles') ? opts.kv.allowedFiles : [],
65
+ forbiddenTasks: hasKv(opts.kv, 'forbiddenTasks') ? opts.kv.forbiddenTasks : [],
66
+ acceptance: hasKv(opts.kv, 'acceptance') ? opts.kv.acceptance : todo?.acceptance || [],
67
+ verifier: hasKv(opts.kv, 'verifier') ? opts.kv.verifier : todo?.verifier || '',
68
+ };
69
+
70
+ let state;
71
+ if (opts.markTodo && isRealTodoId(id)) {
72
+ try {
73
+ state = setDispatchAndMarkTodoState(root, dispatch, id, { status: 'in_progress' });
74
+ } catch (error) {
75
+ console.error(`[dispatch:set] failed to write dispatch and mark todo in_progress: ${error.message}`);
76
+ process.exit(2);
77
+ }
78
+ } else {
79
+ state = setDispatch(root, dispatch);
80
+ }
81
+
82
+ console.log(`[dispatch:set] ${state.dispatch.activeTodoId} → role=${state.dispatch.role}`);
83
+ if (opts.markTodo && isRealTodoId(id)) console.log(` todo ${id}: status=in_progress`);
84
+ }
85
+
86
+ main();