@playcraft/cli 0.1.53-beta → 0.1.54

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 (400) hide show
  1. package/README.md +3 -62
  2. package/dist/agent/local-backend.js +1 -1
  3. package/dist/cli-root-help.js +0 -2
  4. package/dist/commands/build-all.js +19 -5
  5. package/dist/commands/build.js +28 -15
  6. package/dist/commands/create.js +33 -26
  7. package/dist/commands/login.js +42 -84
  8. package/dist/commands/skills.js +0 -4
  9. package/dist/commands/tools-3d.js +0 -11
  10. package/dist/commands/tools-generation.js +0 -6
  11. package/dist/commands/tools.js +0 -2
  12. package/dist/config.js +4 -59
  13. package/dist/index.js +3 -42
  14. package/dist/remix/clone.js +0 -2
  15. package/dist/remix/init-template.js +0 -2
  16. package/dist/remix/pull.js +0 -2
  17. package/dist/remix/push.js +1 -21
  18. package/dist/utils/agent-api-client.js +30 -210
  19. package/dist/utils/playcraft-http-client.js +4 -6
  20. package/package.json +5 -15
  21. package/SKILLS_REGISTRY.md +0 -149
  22. package/dist/auth/account-activation.js +0 -157
  23. package/dist/auth/messages.js +0 -30
  24. package/dist/commands/build-temp.js +0 -26
  25. package/dist/commands/platform-skills.generated.js +0 -19
  26. package/dist/commands/playable.js +0 -53
  27. package/dist/commands/preview-runtime.js +0 -21
  28. package/dist/commands/tools-batch.js +0 -113
  29. package/dist/commands/video.js +0 -122
  30. package/dist/commands/workspace-runtime.js +0 -54
  31. package/dist/commands/workspace.js +0 -40
  32. package/dist/preview-runtime/distribution.js +0 -77
  33. package/dist/project-skills/builtin-import.js +0 -225
  34. package/dist/project-skills/commands.js +0 -77
  35. package/dist/project-skills/lifecycle.js +0 -28
  36. package/dist/project-skills/local-run.js +0 -112
  37. package/dist/project-skills/local-store.js +0 -221
  38. package/dist/project-skills/messages.js +0 -80
  39. package/dist/project-skills/reconcile.js +0 -62
  40. package/dist/project-skills/remote-cache.js +0 -51
  41. package/dist/project-skills/validation.js +0 -19
  42. package/dist/recording/messages.js +0 -40
  43. package/dist/recording/project-digest.js +0 -85
  44. package/dist/recording/recorder.js +0 -293
  45. package/dist/recording/scenario.js +0 -50
  46. package/dist/skill-registry/client.js +0 -345
  47. package/dist/skill-registry/commands.js +0 -180
  48. package/dist/skill-registry/evaluation-client.js +0 -156
  49. package/dist/skill-registry/evaluation-commands.js +0 -174
  50. package/dist/skill-registry/messages.js +0 -177
  51. package/dist/skill-registry/package.js +0 -275
  52. package/dist/skill-registry/platform-package.js +0 -100
  53. package/dist/utils/environment-endpoints.js +0 -17
  54. package/dist/utils/error-diagnostics.js +0 -20
  55. package/dist/utils/tool-operation-journal.js +0 -124
  56. package/dist/utils/video-evidence-git.js +0 -81
  57. package/dist/video-replication/client.js +0 -234
  58. package/dist/video-replication/comparison-evidence.js +0 -149
  59. package/dist/video-replication/comparison-files.js +0 -57
  60. package/dist/video-replication/comparison-log.js +0 -72
  61. package/dist/video-replication/comparison-messages.js +0 -104
  62. package/dist/video-replication/comparison-output.js +0 -63
  63. package/dist/video-replication/comparison-preflight.js +0 -66
  64. package/dist/video-replication/comparison.js +0 -230
  65. package/dist/video-replication/diagnostics.js +0 -41
  66. package/dist/video-replication/evidence.js +0 -165
  67. package/dist/video-replication/media.js +0 -112
  68. package/dist/video-replication/messages.js +0 -97
  69. package/dist/workspace/messages.js +0 -67
  70. package/dist/workspace/transfer-client.js +0 -237
  71. package/dist/workspace/transfer-errors.js +0 -48
  72. package/dist/workspace-runtime/batch/content-changes.js +0 -30
  73. package/dist/workspace-runtime/batch/control.js +0 -86
  74. package/dist/workspace-runtime/batch/deliver.js +0 -173
  75. package/dist/workspace-runtime/batch/freeze.js +0 -101
  76. package/dist/workspace-runtime/batch/generate.js +0 -249
  77. package/dist/workspace-runtime/batch/git.js +0 -40
  78. package/dist/workspace-runtime/batch/occupancy.js +0 -8
  79. package/dist/workspace-runtime/batch/policy.js +0 -70
  80. package/dist/workspace-runtime/batch/prepare.js +0 -317
  81. package/dist/workspace-runtime/batch/processes.js +0 -72
  82. package/dist/workspace-runtime/batch/records.js +0 -113
  83. package/dist/workspace-runtime/batch/routes.js +0 -61
  84. package/dist/workspace-runtime/batch/source-candidate.js +0 -86
  85. package/dist/workspace-runtime/batch/source-capture.js +0 -146
  86. package/dist/workspace-runtime/batch/source-failure.js +0 -43
  87. package/dist/workspace-runtime/batch/source-publish.js +0 -130
  88. package/dist/workspace-runtime/codex/app-server.js +0 -1065
  89. package/dist/workspace-runtime/codex/compact.js +0 -46
  90. package/dist/workspace-runtime/codex/config-toml.js +0 -107
  91. package/dist/workspace-runtime/codex/delivery-tools.js +0 -144
  92. package/dist/workspace-runtime/codex/jsonrpc-stdio.js +0 -145
  93. package/dist/workspace-runtime/codex/launcher-client.js +0 -177
  94. package/dist/workspace-runtime/codex/loopback.js +0 -146
  95. package/dist/workspace-runtime/codex/mcp-config.js +0 -39
  96. package/dist/workspace-runtime/codex/model-broker.js +0 -263
  97. package/dist/workspace-runtime/codex/native-adapter.js +0 -9
  98. package/dist/workspace-runtime/codex/permissions.js +0 -79
  99. package/dist/workspace-runtime/codex/thread-image.js +0 -38
  100. package/dist/workspace-runtime/codex/tool-response.js +0 -10
  101. package/dist/workspace-runtime/codex/ui-instructions.js +0 -4
  102. package/dist/workspace-runtime/codex/ui-tools.js +0 -203
  103. package/dist/workspace-runtime/codex/work-mode.js +0 -15
  104. package/dist/workspace-runtime/main.js +0 -10
  105. package/dist/workspace-runtime/persistence/journal.js +0 -365
  106. package/dist/workspace-runtime/persistence/native-subagents.js +0 -162
  107. package/dist/workspace-runtime/persistence/sqlite-client.js +0 -77
  108. package/dist/workspace-runtime/persistence/sqlite-worker.js +0 -1161
  109. package/dist/workspace-runtime/persistence/stopped-execution.js +0 -77
  110. package/dist/workspace-runtime/previews/diagnostics.js +0 -44
  111. package/dist/workspace-runtime/previews/output.js +0 -36
  112. package/dist/workspace-runtime/previews/publish.js +0 -283
  113. package/dist/workspace-runtime/previews/runtime-preview.js +0 -251
  114. package/dist/workspace-runtime/previews/single-file.js +0 -43
  115. package/dist/workspace-runtime/processes/managed-writes.js +0 -69
  116. package/dist/workspace-runtime/serve.js +0 -441
  117. package/dist/workspace-runtime/server/accept-operation.js +0 -61
  118. package/dist/workspace-runtime/server/asset-transfers.js +0 -63
  119. package/dist/workspace-runtime/server/auth.js +0 -21
  120. package/dist/workspace-runtime/server/connectivity.js +0 -211
  121. package/dist/workspace-runtime/server/desktop-host.js +0 -429
  122. package/dist/workspace-runtime/server/desktop-preview-config.js +0 -81
  123. package/dist/workspace-runtime/server/desktop-preview-service.js +0 -157
  124. package/dist/workspace-runtime/server/desktop-preview-static.js +0 -53
  125. package/dist/workspace-runtime/server/desktop-preview.js +0 -189
  126. package/dist/workspace-runtime/server/dispatch.js +0 -1655
  127. package/dist/workspace-runtime/server/endpoints.js +0 -21
  128. package/dist/workspace-runtime/server/execution-group.js +0 -90
  129. package/dist/workspace-runtime/server/http.js +0 -1339
  130. package/dist/workspace-runtime/server/lock.js +0 -53
  131. package/dist/workspace-runtime/server/operation-record.js +0 -33
  132. package/dist/workspace-runtime/server/rfb-watch-gate.js +0 -168
  133. package/dist/workspace-runtime/server/session-restore.js +0 -84
  134. package/dist/workspace-runtime/server/source-uploader.js +0 -138
  135. package/dist/workspace-runtime/server/submit-operation.js +0 -41
  136. package/dist/workspace-runtime/server/terminal-host.js +0 -366
  137. package/dist/workspace-runtime/server/types.js +0 -1
  138. package/dist/workspace-runtime/server/workspace-transfer.js +0 -168
  139. package/dist/workspace-runtime/verify-artifact.js +0 -59
  140. package/dist/workspace-runtime/workspaces/append-only-log.js +0 -62
  141. package/dist/workspace-runtime/workspaces/archive.js +0 -207
  142. package/dist/workspace-runtime/workspaces/artifact-events.js +0 -55
  143. package/dist/workspace-runtime/workspaces/artifact-files.js +0 -199
  144. package/dist/workspace-runtime/workspaces/artifact-receipts.js +0 -89
  145. package/dist/workspace-runtime/workspaces/artifacts.js +0 -282
  146. package/dist/workspace-runtime/workspaces/asset-library-import.js +0 -387
  147. package/dist/workspace-runtime/workspaces/asset-publication-access.js +0 -25
  148. package/dist/workspace-runtime/workspaces/asset-transfer-dependencies.js +0 -81
  149. package/dist/workspace-runtime/workspaces/asset-transfer-publish.js +0 -438
  150. package/dist/workspace-runtime/workspaces/asset-transfer-storage.js +0 -389
  151. package/dist/workspace-runtime/workspaces/attachment-content.js +0 -73
  152. package/dist/workspace-runtime/workspaces/attachments.js +0 -185
  153. package/dist/workspace-runtime/workspaces/batch-commit.js +0 -142
  154. package/dist/workspace-runtime/workspaces/binary-content.js +0 -65
  155. package/dist/workspace-runtime/workspaces/binary-write.js +0 -117
  156. package/dist/workspace-runtime/workspaces/cli-context.js +0 -23
  157. package/dist/workspace-runtime/workspaces/cli-credentials.js +0 -115
  158. package/dist/workspace-runtime/workspaces/composer-context.js +0 -147
  159. package/dist/workspace-runtime/workspaces/context-error.js +0 -2
  160. package/dist/workspace-runtime/workspaces/delivery-build.js +0 -331
  161. package/dist/workspace-runtime/workspaces/delivery-store.js +0 -168
  162. package/dist/workspace-runtime/workspaces/delivery.js +0 -64
  163. package/dist/workspace-runtime/workspaces/dependencies.js +0 -279
  164. package/dist/workspace-runtime/workspaces/developer-command.js +0 -98
  165. package/dist/workspace-runtime/workspaces/directories.js +0 -132
  166. package/dist/workspace-runtime/workspaces/directory-access.js +0 -37
  167. package/dist/workspace-runtime/workspaces/directory-attachments.js +0 -245
  168. package/dist/workspace-runtime/workspaces/directory-create.js +0 -57
  169. package/dist/workspace-runtime/workspaces/directory-maintenance.js +0 -111
  170. package/dist/workspace-runtime/workspaces/directory-mutations.js +0 -238
  171. package/dist/workspace-runtime/workspaces/directory-revisions.js +0 -56
  172. package/dist/workspace-runtime/workspaces/directory-stats.js +0 -49
  173. package/dist/workspace-runtime/workspaces/disk-snapshot.js +0 -31
  174. package/dist/workspace-runtime/workspaces/empty-template.js +0 -42
  175. package/dist/workspace-runtime/workspaces/file-content.js +0 -48
  176. package/dist/workspace-runtime/workspaces/files-search.js +0 -116
  177. package/dist/workspace-runtime/workspaces/files.js +0 -150
  178. package/dist/workspace-runtime/workspaces/git-credential-broker.js +0 -312
  179. package/dist/workspace-runtime/workspaces/git-credential-helper.js +0 -68
  180. package/dist/workspace-runtime/workspaces/git-direct-store.js +0 -155
  181. package/dist/workspace-runtime/workspaces/git.js +0 -670
  182. package/dist/workspace-runtime/workspaces/instructions.js +0 -56
  183. package/dist/workspace-runtime/workspaces/json5-edit.js +0 -313
  184. package/dist/workspace-runtime/workspaces/library-attachments.js +0 -268
  185. package/dist/workspace-runtime/workspaces/operation-log.js +0 -23
  186. package/dist/workspace-runtime/workspaces/optional-platform-skills.js +0 -14
  187. package/dist/workspace-runtime/workspaces/parameter-agent-inputs.js +0 -97
  188. package/dist/workspace-runtime/workspaces/parameter-agent-protocol.js +0 -40
  189. package/dist/workspace-runtime/workspaces/parameter-agent-store.js +0 -58
  190. package/dist/workspace-runtime/workspaces/parameter-agent.js +0 -284
  191. package/dist/workspace-runtime/workspaces/parameter-assets.js +0 -189
  192. package/dist/workspace-runtime/workspaces/parameters.js +0 -329
  193. package/dist/workspace-runtime/workspaces/prepare.js +0 -278
  194. package/dist/workspace-runtime/workspaces/registry.js +0 -251
  195. package/dist/workspace-runtime/workspaces/remix-references.js +0 -301
  196. package/dist/workspace-runtime/workspaces/revisions.js +0 -31
  197. package/dist/workspace-runtime/workspaces/session-image.js +0 -104
  198. package/dist/workspace-runtime/workspaces/shared-git.js +0 -40
  199. package/dist/workspace-runtime/workspaces/skill-artifact-loader.js +0 -95
  200. package/dist/workspace-runtime/workspaces/skills.js +0 -191
  201. package/dist/workspace-runtime/workspaces/theme-asset-index.js +0 -157
  202. package/dist/workspace-runtime/workspaces/transfer-quota.js +0 -69
  203. package/dist/workspace-runtime/workspaces/transfer.js +0 -471
  204. package/dist/workspace-runtime/workspaces/turn-changes.js +0 -75
  205. package/dist/workspace-runtime/workspaces/video-attachments.js +0 -49
  206. package/project-template/.claude/skills/playcraft-replica-validation/SKILL.md +0 -25
  207. package/project-template/.claude/skills/playcraft-replica-validation/references/contracts.md +0 -79
  208. package/project-template/.claude/skills/playcraft-video-understanding/SKILL.md +0 -29
  209. package/project-template/.claude/skills/playcraft-video-understanding/references/contracts.md +0 -37
  210. package/project-template-v2/.claude/agents/artist.md +0 -82
  211. package/project-template-v2/.claude/agents/developer.md +0 -153
  212. package/project-template-v2/.claude/agents/game-designer.md +0 -264
  213. package/project-template-v2/.claude/agents/refs/artist-art-style-catalog.md +0 -533
  214. package/project-template-v2/.claude/agents/refs/artist-color-audio-recipes.md +0 -153
  215. package/project-template-v2/.claude/agents/refs/artist-dimension-axis.md +0 -27
  216. package/project-template-v2/.claude/agents/refs/artist-master-composite-recipes.md +0 -208
  217. package/project-template-v2/.claude/agents/refs/atom-skill-library.md +0 -81
  218. package/project-template-v2/.claude/agents/refs/developer-impl-cookbook.md +0 -432
  219. package/project-template-v2/.claude/agents/refs/framework-5-component-filter.md +0 -252
  220. package/project-template-v2/.claude/agents/refs/framework-game-feel-juice.md +0 -266
  221. package/project-template-v2/.claude/agents/refs/framework-mda.md +0 -147
  222. package/project-template-v2/.claude/agents/refs/game-designer-gameplay-sufficiency.md +0 -123
  223. package/project-template-v2/.claude/agents/refs/ta-3d-flip-recipe.md +0 -88
  224. package/project-template-v2/.claude/agents/refs/ta-atlas-deliverable-standard.md +0 -67
  225. package/project-template-v2/.claude/agents/refs/ta-batch-pipeline-recipes.md +0 -120
  226. package/project-template-v2/.claude/agents/refs/ta-image-generation-detail.md +0 -300
  227. package/project-template-v2/.claude/agents/refs/ta-image-ops-reference.md +0 -495
  228. package/project-template-v2/.claude/agents/refs/ta-pipeline-cookbook.md +0 -1141
  229. package/project-template-v2/.claude/agents/refs/ta-tools-reference.md +0 -111
  230. package/project-template-v2/.claude/agents/refs/ta-vfx-preset-catalog.md +0 -365
  231. package/project-template-v2/.claude/agents/refs/threejs-cannon-pitfalls.md +0 -412
  232. package/project-template-v2/.claude/agents/reviewer.md +0 -75
  233. package/project-template-v2/.claude/agents/technical-artist.md +0 -86
  234. package/project-template-v2/.claude/hooks/snapshot-milestone.mjs +0 -243
  235. package/project-template-v2/.claude/hooks/user-prompt.mjs +0 -133
  236. package/project-template-v2/.claude/settings.json +0 -33
  237. package/project-template-v2/.claude/skills/brainstorming/SKILL.md +0 -161
  238. package/project-template-v2/.claude/skills/brainstorming/scripts/frame-template.html +0 -270
  239. package/project-template-v2/.claude/skills/brainstorming/scripts/helper.js +0 -177
  240. package/project-template-v2/.claude/skills/brainstorming/scripts/server.cjs +0 -354
  241. package/project-template-v2/.claude/skills/brainstorming/scripts/start-server.sh +0 -148
  242. package/project-template-v2/.claude/skills/brainstorming/scripts/stop-server.sh +0 -56
  243. package/project-template-v2/.claude/skills/brainstorming/scripts/wait-for-selection.sh +0 -62
  244. package/project-template-v2/.claude/skills/brainstorming/spec-document-reviewer-prompt.md +0 -49
  245. package/project-template-v2/.claude/skills/brainstorming/visual-companion.md +0 -309
  246. package/project-template-v2/.claude/skills/playcraft-ad-psychology/SKILL.md +0 -182
  247. package/project-template-v2/.claude/skills/playcraft-art-style-guide/SKILL.md +0 -123
  248. package/project-template-v2/.claude/skills/playcraft-asset-state-sheet/SKILL.md +0 -205
  249. package/project-template-v2/.claude/skills/playcraft-audio-generation/SKILL.md +0 -280
  250. package/project-template-v2/.claude/skills/playcraft-batch-pipeline/SKILL.md +0 -184
  251. package/project-template-v2/.claude/skills/playcraft-build-optimizer/SKILL.md +0 -306
  252. package/project-template-v2/.claude/skills/playcraft-image-generation/SKILL.md +0 -370
  253. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/build-sprite-sheet.template.mjs +0 -123
  254. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/compare-style.template.mjs +0 -254
  255. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/gen-batch-sprite.template.mjs +0 -333
  256. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/gen-batch.template.mjs +0 -95
  257. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/gen-edit-variants.template.mjs +0 -118
  258. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/process-batch.template.mjs +0 -136
  259. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/prompt-cookbook.md +0 -397
  260. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/validate-sprite-sheet.template.mjs +0 -296
  261. package/project-template-v2/.claude/skills/playcraft-image-ops/SKILL.md +0 -122
  262. package/project-template-v2/.claude/skills/playcraft-image-processing/SKILL.md +0 -219
  263. package/project-template-v2/.claude/skills/playcraft-masking/SKILL.md +0 -373
  264. package/project-template-v2/.claude/skills/playcraft-playable-optimization/SKILL.md +0 -161
  265. package/project-template-v2/.claude/skills/playcraft-research/SKILL.md +0 -215
  266. package/project-template-v2/.claude/skills/playcraft-skill-recommender/SKILL.md +0 -382
  267. package/project-template-v2/.claude/skills/playcraft-sprite-generation/SKILL.md +0 -423
  268. package/project-template-v2/.claude/skills/playcraft-sprite-remix/SKILL.md +0 -158
  269. package/project-template-v2/.claude/skills/playcraft-sprite-sheet/SKILL.md +0 -100
  270. package/project-template-v2/.claude/skills/playcraft-storyboard/SKILL.md +0 -167
  271. package/project-template-v2/.claude/skills/playcraft-style-qa/SKILL.md +0 -270
  272. package/project-template-v2/.claude/skills/playcraft-text-rendering/SKILL.md +0 -236
  273. package/project-template-v2/.claude/skills/playcraft-vfx-animation/SKILL.md +0 -130
  274. package/project-template-v2/.claude/skills/playwright-cli/SKILL.md +0 -390
  275. package/project-template-v2/.claude/skills/playwright-cli/references/element-attributes.md +0 -23
  276. package/project-template-v2/.claude/skills/playwright-cli/references/playwright-tests.md +0 -39
  277. package/project-template-v2/.claude/skills/playwright-cli/references/request-mocking.md +0 -87
  278. package/project-template-v2/.claude/skills/playwright-cli/references/running-code.md +0 -240
  279. package/project-template-v2/.claude/skills/playwright-cli/references/session-management.md +0 -226
  280. package/project-template-v2/.claude/skills/playwright-cli/references/spec-driven-testing.md +0 -308
  281. package/project-template-v2/.claude/skills/playwright-cli/references/storage-state.md +0 -275
  282. package/project-template-v2/.claude/skills/playwright-cli/references/test-generation.md +0 -134
  283. package/project-template-v2/.claude/skills/playwright-cli/references/tracing.md +0 -142
  284. package/project-template-v2/.claude/skills/playwright-cli/references/video-recording.md +0 -153
  285. package/project-template-v2/.claude/skills/session-analyzer/SKILL.md +0 -386
  286. package/project-template-v2/.claude/skills/session-analyzer/scripts/execution-breakdown.mjs +0 -182
  287. package/project-template-v2/.claude/skills/session-analyzer/scripts/find-turns.mjs +0 -72
  288. package/project-template-v2/.claude/skills/session-analyzer/scripts/heavy-output.mjs +0 -121
  289. package/project-template-v2/.claude/skills/session-analyzer/scripts/resolve-session.mjs +0 -102
  290. package/project-template-v2/.claude/skills/session-analyzer/scripts/subagent-stats.mjs +0 -127
  291. package/project-template-v2/.claude/skills/session-analyzer/scripts/subagent-tool-timeline.mjs +0 -106
  292. package/project-template-v2/.claude/skills/session-analyzer/scripts/time-gaps.mjs +0 -128
  293. package/project-template-v2/.claude/skills/session-analyzer/scripts/turn-timeline.mjs +0 -67
  294. package/project-template-v2/.claude/snapshot.mjs +0 -263
  295. package/project-template-v2/.playcraft/skills.lock.json +0 -152
  296. package/project-template-v2/CLAUDE.md +0 -146
  297. package/project-template-v2/assets/audio/bgm/.gitkeep +0 -0
  298. package/project-template-v2/assets/audio/sfx/.gitkeep +0 -0
  299. package/project-template-v2/assets/bundles/.gitkeep +0 -0
  300. package/project-template-v2/assets/images/bg/.gitkeep +0 -0
  301. package/project-template-v2/assets/images/reference/.gitkeep +0 -0
  302. package/project-template-v2/assets/images/storyboard/.gitkeep +0 -0
  303. package/project-template-v2/assets/images/tiles/.gitkeep +0 -0
  304. package/project-template-v2/assets/images/ui/.gitkeep +0 -0
  305. package/project-template-v2/assets/images/vfx/.gitkeep +0 -0
  306. package/project-template-v2/assets/models/.gitkeep +0 -0
  307. package/project-template-v2/docs/harness/iteration-1/context-flow.md +0 -254
  308. package/project-template-v2/docs/harness/iteration-1/generate-flow.md +0 -91
  309. package/project-template-v2/docs/harness/iteration-1/ideate-flow.md +0 -214
  310. package/project-template-v2/docs/harness/iteration-1/optimize-flow.md +0 -75
  311. package/project-template-v2/docs/harness/iteration-1/wrapup-flow.md +0 -63
  312. package/project-template-v2/docs/harness/iteration-2/context-flow.md +0 -223
  313. package/project-template-v2/docs/harness/iteration-2/generate-flow.md +0 -129
  314. package/project-template-v2/docs/harness/iteration-2/ideate-flow.md +0 -267
  315. package/project-template-v2/docs/harness/iteration-2/optimize-flow.md +0 -164
  316. package/project-template-v2/docs/harness/iteration-2/wrapup-flow.md +0 -115
  317. package/project-template-v2/docs/harness/orchestrator-flow.md +0 -364
  318. package/project-template-v2/docs/project-state.json +0 -60
  319. package/project-template-v2/docs/project-state.md +0 -72
  320. package/project-template-v2/docs/standards/README.md +0 -225
  321. package/project-template-v2/docs/standards/agent-behavior-standards.md +0 -174
  322. package/project-template-v2/docs/standards/artifacts/design-brief.md +0 -19
  323. package/project-template-v2/docs/standards/artifacts/design.md +0 -22
  324. package/project-template-v2/docs/standards/artifacts/game-code.md +0 -41
  325. package/project-template-v2/docs/standards/artifacts/todo-list.md +0 -41
  326. package/project-template-v2/docs/standards/iter1-agent-behavior-standards.md +0 -343
  327. package/project-template-v2/game/index.ts +0 -18
  328. package/project-template-v2/globals.d.ts +0 -51
  329. package/project-template-v2/index.css +0 -34
  330. package/project-template-v2/index.html +0 -18
  331. package/project-template-v2/main.ts +0 -9
  332. package/project-template-v2/package.json +0 -46
  333. package/project-template-v2/skills/_shared/scripts/dispatch-clear.mjs +0 -31
  334. package/project-template-v2/skills/_shared/scripts/dispatch-set.mjs +0 -86
  335. package/project-template-v2/skills/_shared/scripts/dod-check.mjs +0 -153
  336. package/project-template-v2/skills/_shared/scripts/handoff-append.mjs +0 -70
  337. package/project-template-v2/skills/_shared/scripts/lib/validator-artifacts.mjs +0 -91
  338. package/project-template-v2/skills/_shared/scripts/pipeline/dod-config.mjs +0 -131
  339. package/project-template-v2/skills/_shared/scripts/pipeline/index.mjs +0 -80
  340. package/project-template-v2/skills/_shared/scripts/pipeline/iteration-1-core.mjs +0 -90
  341. package/project-template-v2/skills/_shared/scripts/pipeline/iteration-2-wrap.mjs +0 -93
  342. package/project-template-v2/skills/_shared/scripts/pipeline/iteration-3-visual.mjs +0 -23
  343. package/project-template-v2/skills/_shared/scripts/render-project-state.mjs +0 -230
  344. package/project-template-v2/skills/_shared/scripts/state-advance-stage.mjs +0 -58
  345. package/project-template-v2/skills/_shared/scripts/state-get.mjs +0 -339
  346. package/project-template-v2/skills/_shared/scripts/state-handoff.mjs +0 -39
  347. package/project-template-v2/skills/_shared/scripts/state-set.mjs +0 -94
  348. package/project-template-v2/skills/_shared/scripts/state-store.mjs +0 -783
  349. package/project-template-v2/skills/_shared/scripts/todo-add.mjs +0 -88
  350. package/project-template-v2/skills/_shared/scripts/todo-get.mjs +0 -130
  351. package/project-template-v2/skills/_shared/scripts/todo-remove.mjs +0 -33
  352. package/project-template-v2/skills/_shared/scripts/todo-set.mjs +0 -47
  353. package/project-template-v2/skills/_shared/scripts/verify-asset-code-sync.mjs +0 -268
  354. package/project-template-v2/skills/_shared/scripts/verify-env.mjs +0 -285
  355. package/project-template-v2/skills/_shared/scripts/verify-placeholders.mjs +0 -161
  356. package/project-template-v2/skills/playable-autoplay/SKILL.md +0 -176
  357. package/project-template-v2/skills/playable-autoplay/agents/openai.yaml +0 -4
  358. package/project-template-v2/skills/playable-debug/SKILL.md +0 -116
  359. package/project-template-v2/skills/playable-debug/agents/openai.yaml +0 -4
  360. package/project-template-v2/skills/playable-debug/references/debug-config.md +0 -40
  361. package/project-template-v2/skills/playable-record/SKILL.md +0 -140
  362. package/project-template-v2/skills/playable-record/scripts/lib/dev-server.mjs +0 -104
  363. package/project-template-v2/skills/playable-record/scripts/lib/record-audio-bridge.js +0 -141
  364. package/project-template-v2/skills/playable-record/scripts/record-playable.mjs +0 -425
  365. package/project-template-v2/skills/playable-record/scripts/verify-contract.mjs +0 -261
  366. package/project-template-v2/skills/playable-record/scripts/verify-firstwin.mjs +0 -398
  367. package/project-template-v2/skills/playable-record/scripts/verify-fusion.mjs +0 -322
  368. package/project-template-v2/skills/playable-record/scripts/verify-lifecycle.mjs +0 -105
  369. package/project-template-v2/skills/playable-record/scripts/verify-vlm-video.mjs +0 -230
  370. package/project-template-v2/skills/playable-validate/SKILL.md +0 -61
  371. package/project-template-v2/skills/playable-validate/validation-rules.md +0 -14
  372. package/project-template-v2/skills/playable-verify-ui/SKILL.md +0 -63
  373. package/project-template-v2/skills/playable-verify-ui/scripts/lib/__init__.py +0 -1
  374. package/project-template-v2/skills/playable-verify-ui/scripts/lib/config_expr.js +0 -218
  375. package/project-template-v2/skills/playable-verify-ui/scripts/lib/node_utils.js +0 -51
  376. package/project-template-v2/skills/playable-verify-ui/scripts/lib/profile_loader.py +0 -59
  377. package/project-template-v2/skills/playable-verify-ui/scripts/lib/report.py +0 -106
  378. package/project-template-v2/skills/playable-verify-ui/scripts/lib/runtime_contract.js +0 -116
  379. package/project-template-v2/skills/playable-verify-ui/scripts/verify_fetch_antipatterns.py +0 -59
  380. package/project-template-v2/skills/playable-verify-ui/scripts/verify_hardcoded_layout.js +0 -64
  381. package/project-template-v2/skills/playable-verify-ui/scripts/verify_runtime_contract.js +0 -58
  382. package/project-template-v2/skills/playable-verify-ui/scripts/verify_text_overlap.py +0 -333
  383. package/project-template-v2/ta-workspace/scripts/.gitkeep +0 -0
  384. package/project-template-v2/tsconfig.json +0 -20
  385. package/project-template-v2/vite.config.ts +0 -27
  386. package/project-templates/batch-locks/phaser.yaml +0 -922
  387. package/project-templates/batch-locks/threejs.yaml +0 -978
  388. package/project-templates/empty/AGENTS.md +0 -41
  389. package/project-templates/empty/gitignore +0 -33
  390. package/templates/preview-runtime/v1/README.md +0 -71
  391. package/templates/preview-runtime/v1/build-preview.mjs +0 -1324
  392. package/templates/preview-runtime/v1/manifest.json +0 -17
  393. package/templates/preview-runtime/v1/release-guard.mjs +0 -87
  394. package/templates/preview-runtime/v1/runtime.d.mts +0 -3
  395. package/templates/preview-runtime/v1/runtime.d.ts +0 -3
  396. package/templates/preview-runtime/v1/runtime.mjs +0 -1121
  397. package/templates/preview-runtime/v1/types/adapters.d.ts +0 -26
  398. package/templates/preview-runtime/v1/types/preview.d.ts +0 -23
  399. package/templates/preview-runtime/v1/types/protocol.d.ts +0 -94
  400. package/templates/preview-runtime/v1/types/runtime.d.ts +0 -14
@@ -1,77 +0,0 @@
1
- import { operationRecordSchema, transitionOperation } from '@playcraft/common/cloud-workspace/runtime';
2
- const STOP_BUCKET = 'stopped_execution_epochs';
3
- const ACTIVE_OPERATIONS = new Set(['queued', 'dispatched', 'accepted', 'uncertain']);
4
- /** Called only inside the journal writer transaction after authoritative process-stop evidence. */
5
- export function settleStoppedExecution(database, scope, pid, occurredAt, writer) {
6
- const key = JSON.stringify([scope.runtimeId, scope.generation, scope.runtimeEpoch]);
7
- if (!readRecord(database, STOP_BUCKET, key))
8
- writeRecord(database, STOP_BUCKET, key, { ...scope, pid, occurredAt });
9
- const events = [];
10
- const stoppedSessions = new Set();
11
- const rows = database.prepare(`SELECT scope_key, operation_json FROM operation_intents
12
- WHERE json_extract(operation_json, '$.generation') = ? AND json_extract(operation_json, '$.runtimeEpoch') = ?
13
- AND json_extract(operation_json, '$.kind') IN ('session.turn', 'session.review', 'session.compact')`)
14
- .all(scope.generation, scope.runtimeEpoch);
15
- for (const row of rows) {
16
- const operation = operationRecordSchema.parse(JSON.parse(row.operation_json));
17
- const binding = readRecord(database, 'operation_execution_scopes', JSON.stringify([row.scope_key, operation.operationId]));
18
- const source = database.prepare('SELECT 1 FROM source_events WHERE runtime_id = ? AND generation = ? AND runtime_epoch = ? AND operation_id = ? LIMIT 1')
19
- .get(scope.runtimeId, scope.generation, scope.runtimeEpoch, operation.operationId);
20
- if ((!binding || binding.runtimeId !== scope.runtimeId || binding.generation !== scope.generation || binding.runtimeEpoch !== scope.runtimeEpoch) && !source)
21
- continue;
22
- if (operation.sessionId)
23
- stoppedSessions.add(operation.sessionId);
24
- const session = operation.sessionId ? readRecord(database, 'sessions', operation.sessionId) : undefined;
25
- const appendTerminal = (threadId, turnId, subAgent) => {
26
- const existing = database.prepare(`SELECT 1 FROM source_events WHERE runtime_id = ? AND generation = ? AND runtime_epoch = ?
27
- AND thread_id = ? AND turn_id = ? AND type IN ('turn/completed', 'turn.completed', 'turn.interrupted', 'turn.failed') LIMIT 1`)
28
- .get(scope.runtimeId, scope.generation, scope.runtimeEpoch, threadId, turnId);
29
- if (existing)
30
- return;
31
- const payload = { sessionId: operation.sessionId, workspaceId: operation.workspaceId,
32
- threadId, turnId, turn: { id: turnId, status: 'interrupted' }, reason: 'execution_group_stopped', subAgent };
33
- events.push(...writer.allocate({ ...scope, type: 'turn.interrupted', payload, occurredAt,
34
- sessionId: operation.sessionId, workspaceId: operation.workspaceId, operationId: operation.operationId, threadId, turnId }).committedEvents);
35
- };
36
- const children = database.prepare(`SELECT record_key, body_json FROM records WHERE bucket = 'native_subagent_turns'
37
- AND json_extract(body_json, '$.operationScopeKey') = ?`).all(row.scope_key);
38
- for (const child of children) {
39
- const [threadId, turnId] = JSON.parse(child.record_key);
40
- const link = readRecord(database, 'native_subagent_threads', threadId);
41
- if (!link || link.sessionId !== operation.sessionId || link.workspaceId !== operation.workspaceId || link.rootThreadId !== operation.nativeThreadId)
42
- continue;
43
- const { sessionId: _, workspaceId: __, operationScopeKey: ___, operationConfirmed: ____, ...subAgent } = link;
44
- appendTerminal(threadId, turnId, subAgent);
45
- }
46
- if (!ACTIVE_OPERATIONS.has(operation.status))
47
- continue;
48
- if (operation.nativeThreadId && operation.nativeTurnId)
49
- appendTerminal(operation.nativeThreadId, operation.nativeTurnId);
50
- writer.putOperation(row.scope_key, { ...transitionOperation(operation, 'interrupted', { error: 'execution_group_stopped' }), updatedAt: occurredAt });
51
- if (session && session.threadId === operation.nativeThreadId &&
52
- (session.activeTurnId === operation.nativeTurnId || (!session.activeTurnId && !operation.nativeTurnId && session.turnStatus === 'starting'))) {
53
- writeRecord(database, 'sessions', operation.sessionId, { ...session, turnStatus: 'interrupted', turnBlock: undefined,
54
- activeTurnId: undefined, recoverability: 'history_only' });
55
- }
56
- }
57
- for (const row of database.prepare("SELECT record_key, body_json FROM records WHERE bucket = 'approvals'").all()) {
58
- const approval = JSON.parse(row.body_json);
59
- if (approval.status === 'pending' && approval.runtimeId === scope.runtimeId && approval.generation === scope.generation &&
60
- approval.runtimeEpoch === scope.runtimeEpoch && stoppedSessions.has(String(approval.sessionId)))
61
- writeRecord(database, 'approvals', row.record_key, { ...approval, status: 'expired' });
62
- }
63
- return events;
64
- }
65
- export function stoppedExecutionEpochs(database, runtimeId, generation) {
66
- const rows = database.prepare(`SELECT body_json FROM records WHERE bucket = ?
67
- AND json_extract(body_json, '$.runtimeId') = ? AND json_extract(body_json, '$.generation') = ?`).all(STOP_BUCKET, runtimeId, generation);
68
- return rows.map(row => Number(JSON.parse(row.body_json).runtimeEpoch)).sort((a, b) => a - b);
69
- }
70
- function readRecord(database, bucket, key) {
71
- const row = database.prepare('SELECT body_json FROM records WHERE bucket = ? AND record_key = ?').get(bucket, key);
72
- return row ? JSON.parse(row.body_json) : undefined;
73
- }
74
- function writeRecord(database, bucket, key, value) {
75
- database.prepare('INSERT INTO records (bucket, record_key, body_json) VALUES (?, ?, ?) ON CONFLICT(bucket, record_key) DO UPDATE SET body_json = excluded.body_json')
76
- .run(bucket, key, JSON.stringify(value));
77
- }
@@ -1,44 +0,0 @@
1
- export const PREVIEW_DIAGNOSTICS_MARKER = 'data-playcraft-diagnostics';
2
- /**
3
- * Runs only inside a published preview. It reports browser-visible failures and a small
4
- * performance sample to the workspace; delivery builds never include this script.
5
- */
6
- export const PREVIEW_DIAGNOSTICS_SCRIPT = `(function(){
7
- if(window.__playcraftDiagnosticsV1)return;
8
- window.__playcraftDiagnosticsV1=true;
9
- var pageId=Math.random().toString(36).slice(2)+Date.now().toString(36);
10
- var seq=0,buffer=[],seen={},stopped=false,start=Date.now();
11
- function clean(value){try{return String(value).slice(0,2000)}catch(e){return ''}}
12
- function emit(type,data){if(stopped||buffer.length>=100)return;var key=type+':'+(data.message||data.url||'');if(seen[key])return;seen[key]=1;buffer.push(Object.assign({type:type,at:Date.now()-start},data));}
13
- function flush(){if(!buffer.length)return;var batch=buffer.splice(0,10);seq++;try{window.parent.postMessage({__playcraft:'diagnostics',v:1,pageId:pageId,seq:seq,events:batch},'*')}catch(e){}}
14
- var timer=setInterval(flush,500);
15
- window.addEventListener('error',function(event){
16
- var target=event.target;
17
- if(target&&target!==window&&target.tagName){emit('resource',{tag:String(target.tagName).toLowerCase(),url:clean(target.currentSrc||target.src||target.href||'')});return;}
18
- emit('error',{message:clean(event.message),source:clean(event.filename),line:event.lineno,col:event.colno});
19
- },true);
20
- window.addEventListener('unhandledrejection',function(event){var reason=event.reason;emit('unhandledrejection',{message:clean(reason&&reason.message?reason.message:reason)});});
21
- window.addEventListener('securitypolicyviolation',function(event){emit('securitypolicyviolation',{message:clean(event.violatedDirective),source:clean(event.blockedURI)});});
22
- window.addEventListener('webglcontextlost',function(){emit('webgl-context-lost',{message:'webgl context lost'});},true);
23
- function navigation(){
24
- try{var entry=performance.getEntriesByType('navigation')[0];if(entry)emit('navigation',{duration:Math.round(entry.duration),domContentLoaded:Math.round(entry.domContentLoadedEventEnd),load:Math.round(entry.loadEventEnd)});}catch(e){}
25
- try{var paint=performance.getEntriesByType('paint');for(var i=0;i<paint.length;i++){if(paint[i].name==='first-contentful-paint')emit('paint',{message:'first-contentful-paint',duration:Math.round(paint[i].startTime)});}}catch(e){}
26
- }
27
- if(document.readyState==='complete')navigation();else window.addEventListener('load',navigation,{once:true});
28
- try{var observer=new PerformanceObserver(function(list){var entries=list.getEntries();for(var i=0;i<entries.length;i++){if(entries[i].name==='first-contentful-paint')emit('paint',{message:'first-contentful-paint',duration:Math.round(entries[i].startTime)});}});observer.observe({type:'paint',buffered:true});}catch(e){}
29
- var frames=0,fpsStart=performance.now();
30
- function sample(){frames++;var now=performance.now();if(now-fpsStart<5000){requestAnimationFrame(sample);}else{emit('fps',{fps:Math.round(frames/((now-fpsStart)/1000))});}}
31
- requestAnimationFrame(sample);
32
- window.setTimeout(function(){flush();stopped=true;clearInterval(timer);},60000);
33
- })();`;
34
- /** Injects only at preview publish time, after the builder has produced a single HTML file. */
35
- export function injectPreviewDiagnostics(bytes) {
36
- const html = bytes.toString('utf8');
37
- if (html.includes(PREVIEW_DIAGNOSTICS_MARKER))
38
- return bytes;
39
- const script = `<script ${PREVIEW_DIAGNOSTICS_MARKER}>${PREVIEW_DIAGNOSTICS_SCRIPT}</script>`;
40
- const head = /<head[^>]*>/i.exec(html);
41
- const body = /<\/body\s*>/i.exec(html);
42
- const at = head ? head.index + head[0].length : body ? body.index : html.length;
43
- return Buffer.from(html.slice(0, at) + script + html.slice(at), 'utf8');
44
- }
@@ -1,36 +0,0 @@
1
- import { randomUUID } from 'node:crypto';
2
- import { chmod, lstat, mkdir, realpath, rename, rm, writeFile } from 'node:fs/promises';
3
- import { dirname, join, relative } from 'node:path';
4
- import { WORKSPACE_PLAYABLE_OUTPUT_PATH } from '@playcraft/common/cloud-workspace/runtime';
5
- /** Persist only validated, self-contained build bytes; unrelated delivery files are preserved. */
6
- export async function saveWorkspacePlayableOutput(root, bytes) {
7
- const workspace = await realpath(root);
8
- let directory = workspace;
9
- for (const segment of dirname(WORKSPACE_PLAYABLE_OUTPUT_PATH).split('/')) {
10
- directory = join(directory, segment);
11
- const created = await mkdir(directory, { mode: 0o2775 }).then(() => true, error => {
12
- if (error.code !== 'EEXIST')
13
- throw error;
14
- return false;
15
- });
16
- const stat = await lstat(directory);
17
- if (!stat.isDirectory() || stat.isSymbolicLink() || relative(workspace, await realpath(directory)) !== relative(workspace, directory))
18
- throw new Error('preview_build_failed');
19
- if (created)
20
- await chmod(directory, 0o2775);
21
- }
22
- const target = join(workspace, WORKSPACE_PLAYABLE_OUTPUT_PATH);
23
- const temporary = join(directory, `.playable-${randomUUID()}.tmp`);
24
- try {
25
- await writeFile(temporary, bytes, { flag: 'wx', mode: 0o664 });
26
- await chmod(temporary, 0o664);
27
- const stat = await lstat(target).catch(error => { if (error.code === 'ENOENT')
28
- return undefined; throw error; });
29
- if (stat && (!stat.isFile() || stat.isSymbolicLink() || stat.nlink !== 1))
30
- throw new Error('preview_build_failed');
31
- await rename(temporary, target);
32
- }
33
- finally {
34
- await rm(temporary, { force: true });
35
- }
36
- }
@@ -1,283 +0,0 @@
1
- import { createHash } from 'node:crypto';
2
- import { spawn } from 'node:child_process';
3
- import { platformEndpoint } from '@playcraft/common/cloud-workspace/runtime';
4
- import { constants } from 'node:fs';
5
- import { lstat, open, readdir, rm } from 'node:fs/promises';
6
- import { join } from 'node:path';
7
- import { PREVIEW_HTML_MAX_BYTES, PREVIEW_LOG_TAIL_MAX, WORKSPACE_ARTIFACT_OUTPUT_DIRECTORY, previewPublishResultSchema, previewReservationSchema, transitionOperation, } from '@playcraft/common/cloud-workspace/runtime';
8
- import { excludeFromGit, readDependencies, scheduleDependencyInstall, } from '../workspaces/dependencies.js';
9
- import { runDeveloperCommand } from '../workspaces/developer-command.js';
10
- import { revisionScope, workspaceRoot } from '../workspaces/registry.js';
11
- import { classifyPreviewOutput, findExternalLocalReferences } from './single-file.js';
12
- import { saveWorkspacePlayableOutput } from './output.js';
13
- import { injectPreviewDiagnostics } from './diagnostics.js';
14
- import { OperationLogStore } from '../workspaces/operation-log.js';
15
- import { prepareRuntimePreview, RuntimePreviewBuildError } from './runtime-preview.js';
16
- const BUILD_TIMEOUT_MS = 10 * 60_000;
17
- /** Build output and the builder's own scratch folder live in the checkout, hidden from Git. */
18
- const OUTPUT_FOLDER = '.playcraft-preview-out';
19
- const BUILDER_TEMP_FOLDER = '.playcraft-temp';
20
- /**
21
- * The generic single-file build. `--mode full` keeps the builder from asking which stages to run.
22
- * Group-writable output lets the control user, a member of the development group, remove it.
23
- */
24
- const BUILD_COMMAND = 'umask 002 && playcraft build --mode full --platform playcraft --format html';
25
- class PreviewFailure extends Error {
26
- code;
27
- constructor(code) {
28
- super(code);
29
- this.code = code;
30
- }
31
- }
32
- const running = new WeakMap();
33
- /**
34
- * Checks what can be checked before the operation is accepted. The build itself runs later in
35
- * `runPreviewPublish`; the dispatch request returns as soon as the operation is accepted.
36
- */
37
- export async function previewWorkspaceRoot(state, operation) {
38
- if (!operation.workspaceId || !/^[A-Za-z0-9_-]+$/.test(operation.operationId)) {
39
- throw new PreviewFailure('invalid_preview_publish');
40
- }
41
- if (operation.sessionId !== undefined) {
42
- const session = state.journal.getSession(operation.sessionId);
43
- if (!session || (state.config.workspaceMode === 'multi' && (session.workspaceId !== operation.workspaceId || (session.directoryName ?? 'basic') !== (operation.directoryName ?? 'basic')))) {
44
- throw new PreviewFailure('session_workspace_mismatch');
45
- }
46
- }
47
- return workspaceRoot(state, operation.workspaceId, operation.directoryName);
48
- }
49
- /** Tracks a background publish so tests and shutdown can wait for it. */
50
- export function trackPreviewPublish(state, task) {
51
- const tasks = running.get(state) ?? new Set();
52
- running.set(state, tasks);
53
- const tracked = task.finally(() => tasks.delete(tracked));
54
- tasks.add(tracked);
55
- }
56
- export async function settlePreviewPublishes(state) {
57
- await Promise.all([...(running.get(state) ?? [])]);
58
- }
59
- /** A publish cut off by a restart has no build left running; it is closed rather than left accepted. */
60
- export async function recoverInterruptedPreviews(journal) {
61
- for (const { scopeKey, operation } of journal.listOperations()) {
62
- if (operation.kind !== 'preview.publish' || operation.status !== 'accepted')
63
- continue;
64
- await journal.putOperation(scopeKey, transitionOperation(operation, 'interrupted', { error: 'preview_interrupted' }));
65
- }
66
- }
67
- export async function runPreviewPublish(state, operation, root) {
68
- const workspaceId = operation.workspaceId;
69
- const scope = operation.sessionId === undefined
70
- ? {}
71
- : { sessionId: operation.sessionId, clientRequestId: operation.clientRequestId };
72
- const outputDir = join(root, OUTPUT_FOLDER, operation.operationId);
73
- const output = { log: '' };
74
- const operationLog = new OperationLogStore(state.config.stateDir);
75
- let logChain = Promise.resolve();
76
- const appendLog = (text) => {
77
- logChain = logChain.then(() => operationLog.append(operation.operationId, text)).catch(() => undefined);
78
- };
79
- await operationLog.append(operation.operationId, `$ preview build\n`).catch(() => undefined);
80
- try {
81
- await ensureDependencies(state, revisionScope(state, workspaceId, operation.directoryName) ?? workspaceId, root, output);
82
- const runtimePreview = await prepareRuntimePreview(state, operation, root);
83
- if (runtimePreview)
84
- await excludeFromGit(root, '/.playcraft-editor-preview/');
85
- await excludeFromGit(root, `/${OUTPUT_FOLDER}/`);
86
- await excludeFromGit(root, `/${BUILDER_TEMP_FOLDER}/`);
87
- await excludeFromGit(root, `/${WORKSPACE_ARTIFACT_OUTPUT_DIRECTORY}/`);
88
- await buildPreview(state, root, outputDir, operation.operationId, output, appendLog, runtimePreview?.command);
89
- const runtimeBuild = runtimePreview ? await runtimePreview.finish() : undefined;
90
- const built = runtimeBuild?.bytes ?? await readSingleHtml(outputDir);
91
- const bytes = injectPreviewDiagnostics(built);
92
- if (bytes.byteLength > PREVIEW_HTML_MAX_BYTES)
93
- throw new PreviewFailure('preview_not_single_file');
94
- if (findExternalLocalReferences(bytes.toString('utf8')).length > 0) {
95
- throw new PreviewFailure('preview_not_single_file');
96
- }
97
- if (!runtimePreview)
98
- await saveWorkspacePlayableOutput(root, bytes);
99
- const contentDigest = createHash('sha256').update(bytes).digest('hex');
100
- const contentMd5 = createHash('md5').update(bytes).digest('base64');
101
- const source = await sourceRevision(root);
102
- const reserved = previewReservationSchema.parse(await postControl(state, '/runtime/internal/preview-reservations', {
103
- workspaceId,
104
- directoryName: operation.directoryName ?? 'basic',
105
- ...scope,
106
- operationId: operation.operationId,
107
- contentDigest,
108
- contentMd5,
109
- sizeBytes: bytes.byteLength,
110
- gitHead: source.head,
111
- dirty: source.dirty,
112
- cliVersion: state.config.cliVersion,
113
- }));
114
- if (reserved.sessionId !== operation.sessionId)
115
- throw new PreviewFailure('preview_scope_mismatch');
116
- if (!reserved.alreadyUploaded) {
117
- const uploaded = await fetch(reserved.uploadUrl, {
118
- method: 'PUT',
119
- redirect: 'error',
120
- signal: AbortSignal.timeout(120_000),
121
- headers: {
122
- 'content-type': 'text/html; charset=utf-8',
123
- 'content-md5': contentMd5,
124
- 'content-length': String(bytes.byteLength),
125
- },
126
- body: new Uint8Array(bytes),
127
- });
128
- await uploaded.body?.cancel();
129
- if (!uploaded.ok)
130
- throw new PreviewFailure('preview_upload_failed');
131
- }
132
- const published = previewPublishResultSchema.parse(await postControl(state, '/runtime/internal/preview-completions', {
133
- workspaceId,
134
- directoryName: operation.directoryName ?? 'basic',
135
- ...scope,
136
- operationId: operation.operationId,
137
- artifactId: reserved.artifactId,
138
- expectedPublishRevision: reserved.expectedPublishRevision,
139
- logTail: tail(output.log),
140
- }));
141
- if (published.sessionId !== operation.sessionId || published.previewId !== reserved.previewId ||
142
- published.artifactId !== reserved.artifactId ||
143
- published.contentDigest !== contentDigest ||
144
- (runtimeBuild && JSON.stringify(published.runtimeParameters) !== JSON.stringify(runtimeBuild.profile))) {
145
- throw new PreviewFailure('preview_scope_mismatch');
146
- }
147
- if (published.status === 'conflict')
148
- throw new PreviewFailure('publish_conflict');
149
- return published;
150
- }
151
- catch (error) {
152
- const code = error instanceof PreviewFailure || error instanceof RuntimePreviewBuildError ? error.code : 'preview_build_failed';
153
- appendLog(`\n[${code}] ${error instanceof Error ? error.message : code}\n`);
154
- if (code !== 'publish_conflict') {
155
- await postControl(state, '/runtime/internal/preview-failures', {
156
- workspaceId,
157
- directoryName: operation.directoryName ?? 'basic',
158
- ...scope,
159
- operationId: operation.operationId,
160
- error: code,
161
- logTail: tail(output.log || (error instanceof Error ? error.message : '')),
162
- }).catch(() => undefined);
163
- }
164
- throw new PreviewFailure(code);
165
- }
166
- finally {
167
- await logChain;
168
- await rm(outputDir, { recursive: true, force: true }).catch(() => undefined);
169
- }
170
- }
171
- export function previewFailureCode(error) {
172
- const code = error instanceof PreviewFailure
173
- ? error.code
174
- : error instanceof Error && /^[a-z_]+$/.test(error.message)
175
- ? error.message
176
- : 'preview_build_failed';
177
- return code.slice(0, 256);
178
- }
179
- /**
180
- * Checks the install against the current manifest and lockfile before building, so a package
181
- * Codex added since the workspace opened is installed first. A running install is joined rather
182
- * than started twice; a failed one is retried once here.
183
- */
184
- async function ensureDependencies(state, workspaceId, root, output) {
185
- await scheduleDependencyInstall(state, workspaceId, root);
186
- const dependencies = readDependencies(state, workspaceId);
187
- if (dependencies.status !== 'ready' && dependencies.status !== 'none') {
188
- output.log = [dependencies.error, dependencies.logTail].filter(Boolean).join('\n');
189
- throw new PreviewFailure('dependencies_not_ready');
190
- }
191
- }
192
- async function buildPreview(state, root, outputDir, operationId, output, onLog, runtimeCommand) {
193
- // Tests replace the build; the real one needs a project and the published CLI.
194
- const planned = process.env.PLAYCRAFT_PREVIEW_BUILD_COMMAND || BUILD_COMMAND;
195
- const outcome = await runDeveloperCommand(state, {
196
- processId: `preview-${operationId}`,
197
- cwd: root,
198
- command: runtimeCommand ?? `${planned} --output ${shellQuote(outputDir)} .`,
199
- timeoutMs: BUILD_TIMEOUT_MS,
200
- onOutput: (chunk) => {
201
- const text = String(chunk);
202
- output.log = (output.log + text).slice(-64 * 1024);
203
- onLog?.(text);
204
- },
205
- });
206
- if (outcome.code !== 0)
207
- throw new PreviewFailure('preview_build_failed');
208
- }
209
- /** Reads the one HTML file without following links, so the uploaded bytes are what was checked. */
210
- async function readSingleHtml(outputDir) {
211
- const listed = await readdir(outputDir, { withFileTypes: true }).catch(() => {
212
- throw new PreviewFailure('preview_not_single_file');
213
- });
214
- const entries = listed.map((entry) => ({
215
- name: entry.name,
216
- kind: entry.isSymbolicLink() ? 'symlink' : entry.isFile() ? 'file' : 'dir',
217
- }));
218
- const classified = classifyPreviewOutput(entries);
219
- if (!classified.ok)
220
- throw new PreviewFailure('preview_not_single_file');
221
- const source = join(outputDir, classified.entry);
222
- const stat = await lstat(source);
223
- if (!stat.isFile())
224
- throw new PreviewFailure('preview_not_single_file');
225
- const handle = await open(source, constants.O_RDONLY | constants.O_NOFOLLOW);
226
- try {
227
- return await handle.readFile();
228
- }
229
- finally {
230
- await handle.close();
231
- }
232
- }
233
- async function sourceRevision(root) {
234
- const head = await git(root, ['rev-parse', 'HEAD']);
235
- const status = await git(root, ['status', '--porcelain']);
236
- const revision = head.stdout.trim();
237
- if (head.code !== 0 || !/^[0-9a-f]{7,64}$/i.test(revision))
238
- return { dirty: true };
239
- return { head: revision, dirty: status.code !== 0 || status.stdout.trim().length > 0 };
240
- }
241
- function git(cwd, args) {
242
- return new Promise((resolve) => {
243
- const child = spawn('git', args, { cwd, stdio: ['ignore', 'pipe', 'ignore'] });
244
- let stdout = '';
245
- child.stdout.on('data', (chunk) => {
246
- stdout = (stdout + String(chunk)).slice(-8_000);
247
- });
248
- child.once('error', () => resolve({ code: null, stdout }));
249
- child.once('close', (code) => resolve({ code, stdout }));
250
- });
251
- }
252
- async function postControl(state, path, body) {
253
- const endpoint = platformEndpoint(state.config.publicBaseUrl, path);
254
- const response = await fetch(endpoint, {
255
- method: 'POST',
256
- redirect: 'error',
257
- signal: AbortSignal.timeout(60_000),
258
- headers: {
259
- authorization: `Bearer ${state.config.controlToken}`,
260
- 'playcraft-env': state.config.environment,
261
- 'content-type': 'application/json',
262
- },
263
- body: JSON.stringify({
264
- runtimeId: state.config.runtimeId,
265
- generation: state.config.generation,
266
- runtimeEpoch: state.runtimeEpoch,
267
- ...body,
268
- }),
269
- });
270
- const payload = (await response.json().catch(() => ({})));
271
- if (!response.ok) {
272
- const record = (payload && typeof payload === 'object' ? payload : {});
273
- const reason = typeof record.reason === 'string' ? record.reason : typeof record.error === 'string' ? record.error : '';
274
- throw new PreviewFailure(/^[a-z_]{1,64}$/.test(reason) ? reason : 'preview_upload_failed');
275
- }
276
- return payload;
277
- }
278
- function shellQuote(value) {
279
- return `'${value.replace(/'/g, `'\\''`)}'`;
280
- }
281
- function tail(value) {
282
- return value.slice(-PREVIEW_LOG_TAIL_MAX);
283
- }