@playcraft/cli 0.1.50-beta → 0.1.51

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 (406) 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/image.js +6 -2
  8. package/dist/commands/login.js +42 -84
  9. package/dist/commands/skills.js +0 -4
  10. package/dist/commands/tools-3d.js +0 -11
  11. package/dist/commands/tools-generation.js +137 -69
  12. package/dist/commands/tools-image-context.js +29 -0
  13. package/dist/commands/tools-utils.js +12 -0
  14. package/dist/commands/tools.js +2 -2
  15. package/dist/config.js +4 -59
  16. package/dist/index.js +3 -40
  17. package/dist/remix/clone.js +0 -2
  18. package/dist/remix/init-template.js +0 -2
  19. package/dist/remix/pull.js +0 -2
  20. package/dist/remix/push.js +1 -21
  21. package/dist/utils/agent-api-client.js +30 -210
  22. package/dist/utils/image-asset-context.js +228 -0
  23. package/dist/utils/playcraft-http-client.js +4 -6
  24. package/package.json +5 -15
  25. package/project-template/.claude/agents/refs/ta-image-generation-detail.md +67 -123
  26. package/project-template/.claude/skills/playcraft-image-generation/SKILL.md +135 -63
  27. package/project-template/.claude/skills/playcraft-image-generation/reference/gen-batch-sprite.template.mjs +42 -33
  28. package/project-template/.claude/skills/playcraft-image-generation/reference/gen-batch.template.mjs +18 -20
  29. package/project-template/.claude/skills/playcraft-image-generation/reference/process-batch.template.mjs +6 -7
  30. package/project-template/.claude/skills/playcraft-image-generation/reference/prompt-cookbook.md +39 -39
  31. package/project-templates/phaser/.claude/agents/refs/ta-image-generation-detail.md +59 -59
  32. package/project-templates/phaser/.claude/skills/playcraft-image-generation/SKILL.md +135 -63
  33. package/project-templates/phaser/.claude/skills/playcraft-image-generation/reference/gen-batch-sprite.template.mjs +42 -33
  34. package/project-templates/phaser/.claude/skills/playcraft-image-generation/reference/gen-batch.template.mjs +18 -20
  35. package/project-templates/phaser/.claude/skills/playcraft-image-generation/reference/process-batch.template.mjs +6 -7
  36. package/project-templates/phaser/.claude/skills/playcraft-image-generation/reference/prompt-cookbook.md +39 -39
  37. package/project-templates/threejs/.claude/agents/refs/ta-image-generation-detail.md +59 -59
  38. package/project-templates/threejs/.claude/skills/playcraft-image-generation/SKILL.md +135 -63
  39. package/project-templates/threejs/.claude/skills/playcraft-image-generation/reference/gen-batch-sprite.template.mjs +42 -33
  40. package/project-templates/threejs/.claude/skills/playcraft-image-generation/reference/gen-batch.template.mjs +18 -20
  41. package/project-templates/threejs/.claude/skills/playcraft-image-generation/reference/process-batch.template.mjs +6 -7
  42. package/project-templates/threejs/.claude/skills/playcraft-image-generation/reference/prompt-cookbook.md +39 -39
  43. package/SKILLS_REGISTRY.md +0 -149
  44. package/dist/auth/account-activation.js +0 -157
  45. package/dist/auth/messages.js +0 -30
  46. package/dist/commands/build-temp.js +0 -26
  47. package/dist/commands/platform-skills.generated.js +0 -19
  48. package/dist/commands/playable.js +0 -53
  49. package/dist/commands/tools-batch.js +0 -113
  50. package/dist/commands/video.js +0 -122
  51. package/dist/commands/workspace-runtime.js +0 -54
  52. package/dist/commands/workspace.js +0 -40
  53. package/dist/project-skills/builtin-import.js +0 -225
  54. package/dist/project-skills/commands.js +0 -77
  55. package/dist/project-skills/lifecycle.js +0 -28
  56. package/dist/project-skills/local-run.js +0 -112
  57. package/dist/project-skills/local-store.js +0 -221
  58. package/dist/project-skills/messages.js +0 -80
  59. package/dist/project-skills/reconcile.js +0 -62
  60. package/dist/project-skills/remote-cache.js +0 -51
  61. package/dist/project-skills/validation.js +0 -19
  62. package/dist/recording/messages.js +0 -40
  63. package/dist/recording/project-digest.js +0 -85
  64. package/dist/recording/recorder.js +0 -293
  65. package/dist/recording/scenario.js +0 -50
  66. package/dist/skill-registry/client.js +0 -345
  67. package/dist/skill-registry/commands.js +0 -180
  68. package/dist/skill-registry/evaluation-client.js +0 -156
  69. package/dist/skill-registry/evaluation-commands.js +0 -174
  70. package/dist/skill-registry/messages.js +0 -177
  71. package/dist/skill-registry/package.js +0 -275
  72. package/dist/skill-registry/platform-package.js +0 -100
  73. package/dist/utils/environment-endpoints.js +0 -17
  74. package/dist/utils/error-diagnostics.js +0 -20
  75. package/dist/utils/tool-operation-journal.js +0 -124
  76. package/dist/utils/video-evidence-git.js +0 -81
  77. package/dist/video-replication/client.js +0 -234
  78. package/dist/video-replication/comparison-evidence.js +0 -149
  79. package/dist/video-replication/comparison-files.js +0 -57
  80. package/dist/video-replication/comparison-log.js +0 -72
  81. package/dist/video-replication/comparison-messages.js +0 -104
  82. package/dist/video-replication/comparison-output.js +0 -63
  83. package/dist/video-replication/comparison-preflight.js +0 -66
  84. package/dist/video-replication/comparison.js +0 -230
  85. package/dist/video-replication/diagnostics.js +0 -41
  86. package/dist/video-replication/evidence.js +0 -165
  87. package/dist/video-replication/media.js +0 -112
  88. package/dist/video-replication/messages.js +0 -97
  89. package/dist/workspace/messages.js +0 -67
  90. package/dist/workspace/transfer-client.js +0 -233
  91. package/dist/workspace/transfer-errors.js +0 -48
  92. package/dist/workspace-runtime/batch/content-changes.js +0 -30
  93. package/dist/workspace-runtime/batch/control.js +0 -86
  94. package/dist/workspace-runtime/batch/deliver.js +0 -173
  95. package/dist/workspace-runtime/batch/freeze.js +0 -101
  96. package/dist/workspace-runtime/batch/generate.js +0 -249
  97. package/dist/workspace-runtime/batch/git.js +0 -40
  98. package/dist/workspace-runtime/batch/occupancy.js +0 -8
  99. package/dist/workspace-runtime/batch/policy.js +0 -70
  100. package/dist/workspace-runtime/batch/prepare.js +0 -317
  101. package/dist/workspace-runtime/batch/processes.js +0 -72
  102. package/dist/workspace-runtime/batch/records.js +0 -113
  103. package/dist/workspace-runtime/batch/routes.js +0 -61
  104. package/dist/workspace-runtime/batch/source-candidate.js +0 -86
  105. package/dist/workspace-runtime/batch/source-capture.js +0 -146
  106. package/dist/workspace-runtime/batch/source-failure.js +0 -43
  107. package/dist/workspace-runtime/batch/source-publish.js +0 -130
  108. package/dist/workspace-runtime/codex/app-server.js +0 -1065
  109. package/dist/workspace-runtime/codex/compact.js +0 -46
  110. package/dist/workspace-runtime/codex/config-toml.js +0 -107
  111. package/dist/workspace-runtime/codex/delivery-tools.js +0 -144
  112. package/dist/workspace-runtime/codex/jsonrpc-stdio.js +0 -145
  113. package/dist/workspace-runtime/codex/launcher-client.js +0 -177
  114. package/dist/workspace-runtime/codex/loopback.js +0 -146
  115. package/dist/workspace-runtime/codex/mcp-config.js +0 -39
  116. package/dist/workspace-runtime/codex/model-broker.js +0 -263
  117. package/dist/workspace-runtime/codex/native-adapter.js +0 -9
  118. package/dist/workspace-runtime/codex/permissions.js +0 -79
  119. package/dist/workspace-runtime/codex/thread-image.js +0 -38
  120. package/dist/workspace-runtime/codex/tool-response.js +0 -10
  121. package/dist/workspace-runtime/codex/ui-instructions.js +0 -4
  122. package/dist/workspace-runtime/codex/ui-tools.js +0 -203
  123. package/dist/workspace-runtime/codex/work-mode.js +0 -15
  124. package/dist/workspace-runtime/main.js +0 -10
  125. package/dist/workspace-runtime/persistence/journal.js +0 -365
  126. package/dist/workspace-runtime/persistence/native-subagents.js +0 -162
  127. package/dist/workspace-runtime/persistence/sqlite-client.js +0 -77
  128. package/dist/workspace-runtime/persistence/sqlite-worker.js +0 -1161
  129. package/dist/workspace-runtime/persistence/stopped-execution.js +0 -77
  130. package/dist/workspace-runtime/previews/diagnostics.js +0 -44
  131. package/dist/workspace-runtime/previews/output.js +0 -36
  132. package/dist/workspace-runtime/previews/publish.js +0 -283
  133. package/dist/workspace-runtime/previews/runtime-preview.js +0 -177
  134. package/dist/workspace-runtime/previews/single-file.js +0 -43
  135. package/dist/workspace-runtime/processes/managed-writes.js +0 -69
  136. package/dist/workspace-runtime/serve.js +0 -441
  137. package/dist/workspace-runtime/server/accept-operation.js +0 -61
  138. package/dist/workspace-runtime/server/asset-transfers.js +0 -63
  139. package/dist/workspace-runtime/server/auth.js +0 -21
  140. package/dist/workspace-runtime/server/connectivity.js +0 -209
  141. package/dist/workspace-runtime/server/desktop-host.js +0 -429
  142. package/dist/workspace-runtime/server/desktop-preview-config.js +0 -81
  143. package/dist/workspace-runtime/server/desktop-preview-service.js +0 -157
  144. package/dist/workspace-runtime/server/desktop-preview-static.js +0 -53
  145. package/dist/workspace-runtime/server/desktop-preview.js +0 -189
  146. package/dist/workspace-runtime/server/dispatch.js +0 -1632
  147. package/dist/workspace-runtime/server/endpoints.js +0 -21
  148. package/dist/workspace-runtime/server/execution-group.js +0 -90
  149. package/dist/workspace-runtime/server/http.js +0 -1340
  150. package/dist/workspace-runtime/server/lock.js +0 -53
  151. package/dist/workspace-runtime/server/operation-record.js +0 -33
  152. package/dist/workspace-runtime/server/rfb-watch-gate.js +0 -168
  153. package/dist/workspace-runtime/server/session-restore.js +0 -84
  154. package/dist/workspace-runtime/server/source-uploader.js +0 -138
  155. package/dist/workspace-runtime/server/submit-operation.js +0 -41
  156. package/dist/workspace-runtime/server/terminal-host.js +0 -366
  157. package/dist/workspace-runtime/server/types.js +0 -1
  158. package/dist/workspace-runtime/server/workspace-transfer.js +0 -168
  159. package/dist/workspace-runtime/verify-artifact.js +0 -59
  160. package/dist/workspace-runtime/workspaces/append-only-log.js +0 -62
  161. package/dist/workspace-runtime/workspaces/archive.js +0 -207
  162. package/dist/workspace-runtime/workspaces/artifact-events.js +0 -55
  163. package/dist/workspace-runtime/workspaces/artifact-files.js +0 -199
  164. package/dist/workspace-runtime/workspaces/artifact-receipts.js +0 -89
  165. package/dist/workspace-runtime/workspaces/artifacts.js +0 -282
  166. package/dist/workspace-runtime/workspaces/asset-library-import.js +0 -366
  167. package/dist/workspace-runtime/workspaces/asset-transfer-dependencies.js +0 -81
  168. package/dist/workspace-runtime/workspaces/asset-transfer-publish.js +0 -434
  169. package/dist/workspace-runtime/workspaces/asset-transfer-storage.js +0 -389
  170. package/dist/workspace-runtime/workspaces/attachment-content.js +0 -73
  171. package/dist/workspace-runtime/workspaces/attachments.js +0 -185
  172. package/dist/workspace-runtime/workspaces/batch-commit.js +0 -142
  173. package/dist/workspace-runtime/workspaces/binary-content.js +0 -65
  174. package/dist/workspace-runtime/workspaces/binary-write.js +0 -112
  175. package/dist/workspace-runtime/workspaces/cli-context.js +0 -23
  176. package/dist/workspace-runtime/workspaces/cli-credentials.js +0 -115
  177. package/dist/workspace-runtime/workspaces/composer-context.js +0 -147
  178. package/dist/workspace-runtime/workspaces/context-error.js +0 -2
  179. package/dist/workspace-runtime/workspaces/delivery-build.js +0 -331
  180. package/dist/workspace-runtime/workspaces/delivery-store.js +0 -168
  181. package/dist/workspace-runtime/workspaces/delivery.js +0 -64
  182. package/dist/workspace-runtime/workspaces/dependencies.js +0 -279
  183. package/dist/workspace-runtime/workspaces/developer-command.js +0 -98
  184. package/dist/workspace-runtime/workspaces/directories.js +0 -132
  185. package/dist/workspace-runtime/workspaces/directory-access.js +0 -37
  186. package/dist/workspace-runtime/workspaces/directory-attachments.js +0 -245
  187. package/dist/workspace-runtime/workspaces/directory-create.js +0 -57
  188. package/dist/workspace-runtime/workspaces/directory-maintenance.js +0 -111
  189. package/dist/workspace-runtime/workspaces/directory-mutations.js +0 -238
  190. package/dist/workspace-runtime/workspaces/directory-revisions.js +0 -56
  191. package/dist/workspace-runtime/workspaces/directory-stats.js +0 -49
  192. package/dist/workspace-runtime/workspaces/disk-snapshot.js +0 -31
  193. package/dist/workspace-runtime/workspaces/empty-template.js +0 -42
  194. package/dist/workspace-runtime/workspaces/file-content.js +0 -48
  195. package/dist/workspace-runtime/workspaces/files-search.js +0 -116
  196. package/dist/workspace-runtime/workspaces/files.js +0 -150
  197. package/dist/workspace-runtime/workspaces/git-credential-broker.js +0 -312
  198. package/dist/workspace-runtime/workspaces/git-credential-helper.js +0 -68
  199. package/dist/workspace-runtime/workspaces/git-direct-store.js +0 -155
  200. package/dist/workspace-runtime/workspaces/git.js +0 -670
  201. package/dist/workspace-runtime/workspaces/instructions.js +0 -56
  202. package/dist/workspace-runtime/workspaces/json5-edit.js +0 -313
  203. package/dist/workspace-runtime/workspaces/library-attachments.js +0 -268
  204. package/dist/workspace-runtime/workspaces/operation-log.js +0 -23
  205. package/dist/workspace-runtime/workspaces/optional-platform-skills.js +0 -14
  206. package/dist/workspace-runtime/workspaces/parameter-agent-inputs.js +0 -87
  207. package/dist/workspace-runtime/workspaces/parameter-agent-protocol.js +0 -29
  208. package/dist/workspace-runtime/workspaces/parameter-agent-store.js +0 -58
  209. package/dist/workspace-runtime/workspaces/parameter-agent.js +0 -282
  210. package/dist/workspace-runtime/workspaces/parameters.js +0 -295
  211. package/dist/workspace-runtime/workspaces/prepare.js +0 -278
  212. package/dist/workspace-runtime/workspaces/registry.js +0 -251
  213. package/dist/workspace-runtime/workspaces/remix-references.js +0 -301
  214. package/dist/workspace-runtime/workspaces/revisions.js +0 -31
  215. package/dist/workspace-runtime/workspaces/session-image.js +0 -104
  216. package/dist/workspace-runtime/workspaces/shared-git.js +0 -40
  217. package/dist/workspace-runtime/workspaces/skill-artifact-loader.js +0 -95
  218. package/dist/workspace-runtime/workspaces/skills.js +0 -191
  219. package/dist/workspace-runtime/workspaces/transfer-quota.js +0 -69
  220. package/dist/workspace-runtime/workspaces/transfer.js +0 -471
  221. package/dist/workspace-runtime/workspaces/turn-changes.js +0 -75
  222. package/dist/workspace-runtime/workspaces/video-attachments.js +0 -49
  223. package/project-template/.claude/skills/playcraft-replica-validation/SKILL.md +0 -25
  224. package/project-template/.claude/skills/playcraft-replica-validation/references/contracts.md +0 -79
  225. package/project-template/.claude/skills/playcraft-video-understanding/SKILL.md +0 -29
  226. package/project-template/.claude/skills/playcraft-video-understanding/references/contracts.md +0 -37
  227. package/project-template-v2/.claude/agents/artist.md +0 -82
  228. package/project-template-v2/.claude/agents/developer.md +0 -153
  229. package/project-template-v2/.claude/agents/game-designer.md +0 -264
  230. package/project-template-v2/.claude/agents/refs/artist-art-style-catalog.md +0 -533
  231. package/project-template-v2/.claude/agents/refs/artist-color-audio-recipes.md +0 -153
  232. package/project-template-v2/.claude/agents/refs/artist-dimension-axis.md +0 -27
  233. package/project-template-v2/.claude/agents/refs/artist-master-composite-recipes.md +0 -208
  234. package/project-template-v2/.claude/agents/refs/atom-skill-library.md +0 -81
  235. package/project-template-v2/.claude/agents/refs/developer-impl-cookbook.md +0 -432
  236. package/project-template-v2/.claude/agents/refs/framework-5-component-filter.md +0 -252
  237. package/project-template-v2/.claude/agents/refs/framework-game-feel-juice.md +0 -266
  238. package/project-template-v2/.claude/agents/refs/framework-mda.md +0 -147
  239. package/project-template-v2/.claude/agents/refs/game-designer-gameplay-sufficiency.md +0 -123
  240. package/project-template-v2/.claude/agents/refs/ta-3d-flip-recipe.md +0 -88
  241. package/project-template-v2/.claude/agents/refs/ta-atlas-deliverable-standard.md +0 -67
  242. package/project-template-v2/.claude/agents/refs/ta-batch-pipeline-recipes.md +0 -120
  243. package/project-template-v2/.claude/agents/refs/ta-image-generation-detail.md +0 -300
  244. package/project-template-v2/.claude/agents/refs/ta-image-ops-reference.md +0 -495
  245. package/project-template-v2/.claude/agents/refs/ta-pipeline-cookbook.md +0 -1141
  246. package/project-template-v2/.claude/agents/refs/ta-tools-reference.md +0 -111
  247. package/project-template-v2/.claude/agents/refs/ta-vfx-preset-catalog.md +0 -365
  248. package/project-template-v2/.claude/agents/refs/threejs-cannon-pitfalls.md +0 -412
  249. package/project-template-v2/.claude/agents/reviewer.md +0 -75
  250. package/project-template-v2/.claude/agents/technical-artist.md +0 -86
  251. package/project-template-v2/.claude/hooks/snapshot-milestone.mjs +0 -243
  252. package/project-template-v2/.claude/hooks/user-prompt.mjs +0 -133
  253. package/project-template-v2/.claude/settings.json +0 -33
  254. package/project-template-v2/.claude/skills/brainstorming/SKILL.md +0 -161
  255. package/project-template-v2/.claude/skills/brainstorming/scripts/frame-template.html +0 -270
  256. package/project-template-v2/.claude/skills/brainstorming/scripts/helper.js +0 -177
  257. package/project-template-v2/.claude/skills/brainstorming/scripts/server.cjs +0 -354
  258. package/project-template-v2/.claude/skills/brainstorming/scripts/start-server.sh +0 -148
  259. package/project-template-v2/.claude/skills/brainstorming/scripts/stop-server.sh +0 -56
  260. package/project-template-v2/.claude/skills/brainstorming/scripts/wait-for-selection.sh +0 -62
  261. package/project-template-v2/.claude/skills/brainstorming/spec-document-reviewer-prompt.md +0 -49
  262. package/project-template-v2/.claude/skills/brainstorming/visual-companion.md +0 -309
  263. package/project-template-v2/.claude/skills/playcraft-ad-psychology/SKILL.md +0 -182
  264. package/project-template-v2/.claude/skills/playcraft-art-style-guide/SKILL.md +0 -123
  265. package/project-template-v2/.claude/skills/playcraft-asset-state-sheet/SKILL.md +0 -205
  266. package/project-template-v2/.claude/skills/playcraft-audio-generation/SKILL.md +0 -280
  267. package/project-template-v2/.claude/skills/playcraft-batch-pipeline/SKILL.md +0 -184
  268. package/project-template-v2/.claude/skills/playcraft-build-optimizer/SKILL.md +0 -306
  269. package/project-template-v2/.claude/skills/playcraft-image-generation/SKILL.md +0 -298
  270. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/build-sprite-sheet.template.mjs +0 -123
  271. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/compare-style.template.mjs +0 -254
  272. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/gen-batch-sprite.template.mjs +0 -324
  273. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/gen-batch.template.mjs +0 -97
  274. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/gen-edit-variants.template.mjs +0 -118
  275. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/process-batch.template.mjs +0 -137
  276. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/prompt-cookbook.md +0 -397
  277. package/project-template-v2/.claude/skills/playcraft-image-generation/reference/validate-sprite-sheet.template.mjs +0 -296
  278. package/project-template-v2/.claude/skills/playcraft-image-ops/SKILL.md +0 -122
  279. package/project-template-v2/.claude/skills/playcraft-image-processing/SKILL.md +0 -219
  280. package/project-template-v2/.claude/skills/playcraft-masking/SKILL.md +0 -373
  281. package/project-template-v2/.claude/skills/playcraft-playable-optimization/SKILL.md +0 -161
  282. package/project-template-v2/.claude/skills/playcraft-research/SKILL.md +0 -215
  283. package/project-template-v2/.claude/skills/playcraft-skill-recommender/SKILL.md +0 -382
  284. package/project-template-v2/.claude/skills/playcraft-sprite-generation/SKILL.md +0 -423
  285. package/project-template-v2/.claude/skills/playcraft-sprite-remix/SKILL.md +0 -158
  286. package/project-template-v2/.claude/skills/playcraft-sprite-sheet/SKILL.md +0 -100
  287. package/project-template-v2/.claude/skills/playcraft-storyboard/SKILL.md +0 -167
  288. package/project-template-v2/.claude/skills/playcraft-style-qa/SKILL.md +0 -270
  289. package/project-template-v2/.claude/skills/playcraft-text-rendering/SKILL.md +0 -236
  290. package/project-template-v2/.claude/skills/playcraft-vfx-animation/SKILL.md +0 -130
  291. package/project-template-v2/.claude/skills/playwright-cli/SKILL.md +0 -390
  292. package/project-template-v2/.claude/skills/playwright-cli/references/element-attributes.md +0 -23
  293. package/project-template-v2/.claude/skills/playwright-cli/references/playwright-tests.md +0 -39
  294. package/project-template-v2/.claude/skills/playwright-cli/references/request-mocking.md +0 -87
  295. package/project-template-v2/.claude/skills/playwright-cli/references/running-code.md +0 -240
  296. package/project-template-v2/.claude/skills/playwright-cli/references/session-management.md +0 -226
  297. package/project-template-v2/.claude/skills/playwright-cli/references/spec-driven-testing.md +0 -308
  298. package/project-template-v2/.claude/skills/playwright-cli/references/storage-state.md +0 -275
  299. package/project-template-v2/.claude/skills/playwright-cli/references/test-generation.md +0 -134
  300. package/project-template-v2/.claude/skills/playwright-cli/references/tracing.md +0 -142
  301. package/project-template-v2/.claude/skills/playwright-cli/references/video-recording.md +0 -153
  302. package/project-template-v2/.claude/skills/session-analyzer/SKILL.md +0 -386
  303. package/project-template-v2/.claude/skills/session-analyzer/scripts/execution-breakdown.mjs +0 -182
  304. package/project-template-v2/.claude/skills/session-analyzer/scripts/find-turns.mjs +0 -72
  305. package/project-template-v2/.claude/skills/session-analyzer/scripts/heavy-output.mjs +0 -121
  306. package/project-template-v2/.claude/skills/session-analyzer/scripts/resolve-session.mjs +0 -102
  307. package/project-template-v2/.claude/skills/session-analyzer/scripts/subagent-stats.mjs +0 -127
  308. package/project-template-v2/.claude/skills/session-analyzer/scripts/subagent-tool-timeline.mjs +0 -106
  309. package/project-template-v2/.claude/skills/session-analyzer/scripts/time-gaps.mjs +0 -128
  310. package/project-template-v2/.claude/skills/session-analyzer/scripts/turn-timeline.mjs +0 -67
  311. package/project-template-v2/.claude/snapshot.mjs +0 -263
  312. package/project-template-v2/.playcraft/skills.lock.json +0 -152
  313. package/project-template-v2/CLAUDE.md +0 -146
  314. package/project-template-v2/assets/audio/bgm/.gitkeep +0 -0
  315. package/project-template-v2/assets/audio/sfx/.gitkeep +0 -0
  316. package/project-template-v2/assets/bundles/.gitkeep +0 -0
  317. package/project-template-v2/assets/images/bg/.gitkeep +0 -0
  318. package/project-template-v2/assets/images/reference/.gitkeep +0 -0
  319. package/project-template-v2/assets/images/storyboard/.gitkeep +0 -0
  320. package/project-template-v2/assets/images/tiles/.gitkeep +0 -0
  321. package/project-template-v2/assets/images/ui/.gitkeep +0 -0
  322. package/project-template-v2/assets/images/vfx/.gitkeep +0 -0
  323. package/project-template-v2/assets/models/.gitkeep +0 -0
  324. package/project-template-v2/docs/harness/iteration-1/context-flow.md +0 -254
  325. package/project-template-v2/docs/harness/iteration-1/generate-flow.md +0 -91
  326. package/project-template-v2/docs/harness/iteration-1/ideate-flow.md +0 -214
  327. package/project-template-v2/docs/harness/iteration-1/optimize-flow.md +0 -75
  328. package/project-template-v2/docs/harness/iteration-1/wrapup-flow.md +0 -63
  329. package/project-template-v2/docs/harness/iteration-2/context-flow.md +0 -223
  330. package/project-template-v2/docs/harness/iteration-2/generate-flow.md +0 -129
  331. package/project-template-v2/docs/harness/iteration-2/ideate-flow.md +0 -267
  332. package/project-template-v2/docs/harness/iteration-2/optimize-flow.md +0 -164
  333. package/project-template-v2/docs/harness/iteration-2/wrapup-flow.md +0 -115
  334. package/project-template-v2/docs/harness/orchestrator-flow.md +0 -364
  335. package/project-template-v2/docs/project-state.json +0 -60
  336. package/project-template-v2/docs/project-state.md +0 -72
  337. package/project-template-v2/docs/standards/README.md +0 -225
  338. package/project-template-v2/docs/standards/agent-behavior-standards.md +0 -174
  339. package/project-template-v2/docs/standards/artifacts/design-brief.md +0 -19
  340. package/project-template-v2/docs/standards/artifacts/design.md +0 -22
  341. package/project-template-v2/docs/standards/artifacts/game-code.md +0 -41
  342. package/project-template-v2/docs/standards/artifacts/todo-list.md +0 -41
  343. package/project-template-v2/docs/standards/iter1-agent-behavior-standards.md +0 -343
  344. package/project-template-v2/game/index.ts +0 -18
  345. package/project-template-v2/globals.d.ts +0 -51
  346. package/project-template-v2/index.css +0 -34
  347. package/project-template-v2/index.html +0 -18
  348. package/project-template-v2/main.ts +0 -9
  349. package/project-template-v2/package.json +0 -46
  350. package/project-template-v2/skills/_shared/scripts/dispatch-clear.mjs +0 -31
  351. package/project-template-v2/skills/_shared/scripts/dispatch-set.mjs +0 -86
  352. package/project-template-v2/skills/_shared/scripts/dod-check.mjs +0 -153
  353. package/project-template-v2/skills/_shared/scripts/handoff-append.mjs +0 -70
  354. package/project-template-v2/skills/_shared/scripts/lib/validator-artifacts.mjs +0 -91
  355. package/project-template-v2/skills/_shared/scripts/pipeline/dod-config.mjs +0 -131
  356. package/project-template-v2/skills/_shared/scripts/pipeline/index.mjs +0 -80
  357. package/project-template-v2/skills/_shared/scripts/pipeline/iteration-1-core.mjs +0 -90
  358. package/project-template-v2/skills/_shared/scripts/pipeline/iteration-2-wrap.mjs +0 -93
  359. package/project-template-v2/skills/_shared/scripts/pipeline/iteration-3-visual.mjs +0 -23
  360. package/project-template-v2/skills/_shared/scripts/render-project-state.mjs +0 -230
  361. package/project-template-v2/skills/_shared/scripts/state-advance-stage.mjs +0 -58
  362. package/project-template-v2/skills/_shared/scripts/state-get.mjs +0 -339
  363. package/project-template-v2/skills/_shared/scripts/state-handoff.mjs +0 -39
  364. package/project-template-v2/skills/_shared/scripts/state-set.mjs +0 -94
  365. package/project-template-v2/skills/_shared/scripts/state-store.mjs +0 -783
  366. package/project-template-v2/skills/_shared/scripts/todo-add.mjs +0 -88
  367. package/project-template-v2/skills/_shared/scripts/todo-get.mjs +0 -130
  368. package/project-template-v2/skills/_shared/scripts/todo-remove.mjs +0 -33
  369. package/project-template-v2/skills/_shared/scripts/todo-set.mjs +0 -47
  370. package/project-template-v2/skills/_shared/scripts/verify-asset-code-sync.mjs +0 -268
  371. package/project-template-v2/skills/_shared/scripts/verify-env.mjs +0 -285
  372. package/project-template-v2/skills/_shared/scripts/verify-placeholders.mjs +0 -161
  373. package/project-template-v2/skills/playable-autoplay/SKILL.md +0 -176
  374. package/project-template-v2/skills/playable-autoplay/agents/openai.yaml +0 -4
  375. package/project-template-v2/skills/playable-debug/SKILL.md +0 -116
  376. package/project-template-v2/skills/playable-debug/agents/openai.yaml +0 -4
  377. package/project-template-v2/skills/playable-debug/references/debug-config.md +0 -40
  378. package/project-template-v2/skills/playable-record/SKILL.md +0 -140
  379. package/project-template-v2/skills/playable-record/scripts/lib/dev-server.mjs +0 -104
  380. package/project-template-v2/skills/playable-record/scripts/lib/record-audio-bridge.js +0 -141
  381. package/project-template-v2/skills/playable-record/scripts/record-playable.mjs +0 -425
  382. package/project-template-v2/skills/playable-record/scripts/verify-contract.mjs +0 -261
  383. package/project-template-v2/skills/playable-record/scripts/verify-firstwin.mjs +0 -398
  384. package/project-template-v2/skills/playable-record/scripts/verify-fusion.mjs +0 -322
  385. package/project-template-v2/skills/playable-record/scripts/verify-lifecycle.mjs +0 -105
  386. package/project-template-v2/skills/playable-record/scripts/verify-vlm-video.mjs +0 -230
  387. package/project-template-v2/skills/playable-validate/SKILL.md +0 -61
  388. package/project-template-v2/skills/playable-validate/validation-rules.md +0 -14
  389. package/project-template-v2/skills/playable-verify-ui/SKILL.md +0 -63
  390. package/project-template-v2/skills/playable-verify-ui/scripts/lib/__init__.py +0 -1
  391. package/project-template-v2/skills/playable-verify-ui/scripts/lib/config_expr.js +0 -218
  392. package/project-template-v2/skills/playable-verify-ui/scripts/lib/node_utils.js +0 -51
  393. package/project-template-v2/skills/playable-verify-ui/scripts/lib/profile_loader.py +0 -59
  394. package/project-template-v2/skills/playable-verify-ui/scripts/lib/report.py +0 -106
  395. package/project-template-v2/skills/playable-verify-ui/scripts/lib/runtime_contract.js +0 -116
  396. package/project-template-v2/skills/playable-verify-ui/scripts/verify_fetch_antipatterns.py +0 -59
  397. package/project-template-v2/skills/playable-verify-ui/scripts/verify_hardcoded_layout.js +0 -64
  398. package/project-template-v2/skills/playable-verify-ui/scripts/verify_runtime_contract.js +0 -58
  399. package/project-template-v2/skills/playable-verify-ui/scripts/verify_text_overlap.py +0 -333
  400. package/project-template-v2/ta-workspace/scripts/.gitkeep +0 -0
  401. package/project-template-v2/tsconfig.json +0 -20
  402. package/project-template-v2/vite.config.ts +0 -27
  403. package/project-templates/batch-locks/phaser.yaml +0 -922
  404. package/project-templates/batch-locks/threejs.yaml +0 -978
  405. package/project-templates/empty/AGENTS.md +0 -41
  406. package/project-templates/empty/gitignore +0 -33
@@ -1,97 +0,0 @@
1
- const messages = {
2
- en: {
3
- topic: 'Video understanding and replica comparison with evidence frames',
4
- models: 'List authorized video models and supported processing modes',
5
- understand: 'Understand a local reference video using a managed video model',
6
- jobs: 'Inspect or cancel an existing analysis without submitting new inference',
7
- get: 'Read an existing video task state', cancel: 'Explicitly request remote cancellation',
8
- workspace: 'Workspace UUID (defaults to the nearest workspace context file)',
9
- json: 'Print machine-readable JSON (always enabled)', video: 'Local MP4, MOV or WebM file',
10
- question: 'Focused question about the video', context: 'Prior analysis.json for this video',
11
- processing: 'auto | agentic | static', fps: 'Static sampling: 1 | 2 | 4 | 8',
12
- clip: 'Static clip in original video seconds: start:end',
13
- model: 'Authorized model configuration UUID', out: 'Artifact directory',
14
- timeout: 'Maximum local wait in seconds; the remote task remains recoverable',
15
- resume: 'Resume this existing run UUID; cannot be combined with new inputs',
16
- invalidArguments: 'Invalid video command arguments.',
17
- workspaceMissing: 'Specify --workspace or run inside a Cloud Workspace checkout.',
18
- workspaceMismatch: 'The explicit workspace does not match the checkout context.',
19
- videoMissing: 'The video must be a readable regular file.',
20
- videoQuota: 'The video exceeds 100 MiB or 180 seconds, or has unsupported dimensions.',
21
- videoFormat: 'The file is not a supported MP4, MOV or WebM video.',
22
- mediaTool: 'FFmpeg and ffprobe are required. Check the managed runtime installation.',
23
- outputConflict: 'The artifact directory belongs to another run. Choose an empty directory.',
24
- unsafeOutput: 'The artifact directory contains a linked or unsupported output path.',
25
- gitExcludeWarning: 'The local Git ignore rule could not be updated. Video analysis will continue; do not commit .playcraft/video-replication evidence to the repository.',
26
- invalidContext: 'The context is invalid or belongs to a different video.',
27
- invalidResult: 'The video service returned invalid or incomplete evidence.',
28
- sourceChanged: 'The video changed since it was probed or the task was created.',
29
- uploadFailed: 'Video upload could not be completed.',
30
- modelUnavailable: 'No authorized model supports the requested video processing mode.',
31
- resumeMissing: 'The saved request is missing or does not match this run and workspace.',
32
- timeoutReached: 'Local waiting ended. Resume this run to check its existing result.',
33
- interrupted: 'Interrupted. Remote cancellation was not requested or confirmed.',
34
- uncertain: 'The remote outcome is unknown. Check this run; do not submit another analysis.',
35
- remoteFailed: 'The remote analysis failed or was cancelled.',
36
- failed: 'Video understanding failed. Inspect the saved request and task before retrying.',
37
- probing: 'Inspecting the video', uploading: 'Uploading the video',
38
- preparing: 'Preparing the video command', loadingModels: 'Loading authorized video models',
39
- initializingUpload: 'Initializing the video upload', finalizingUpload: 'Validating the uploaded video',
40
- failureStage: 'Stage', failureReason: 'Reason', mediaExit: 'Media tool exit status',
41
- mediaTimedOut: 'Media tool timed out', mediaOutputLimit: 'Media tool output exceeded the limit',
42
- submitting: 'Submitting the analysis', waiting: 'Waiting for the existing analysis',
43
- extracting: 'Extracting evidence frames',
44
- summary: 'Summary', observations: 'Observed facts', events: 'Events',
45
- inferences: 'Inferences', unknowns: 'Unknowns', hints: 'Reconstruction suggestions',
46
- evidence: 'Evidence', entities: 'Entities', assets: 'Assets', rules: 'Candidate rules',
47
- transcriptNotice: 'Observed events cover only the demonstrated video. Inferred controls and hidden rules remain uncertain.',
48
- },
49
- zh: {
50
- topic: '视频理解与复刻比较,抽取证据关键帧',
51
- models: '列出有权使用的视频模型和处理模式',
52
- understand: '使用受管视频模型理解本地参考视频',
53
- jobs: '核对或取消已有任务,不新建推理', get: '读取已有视频任务状态', cancel: '明确请求远端取消',
54
- workspace: '工作区编号,默认读取最近的工作区上下文文件',
55
- json: '输出机器可读的 JSON(始终启用)', video: '本地 MP4、MOV 或 WebM 文件',
56
- question: '需要确认的视频问题', context: '同一视频的已有 analysis.json',
57
- processing: 'auto | agentic | static', fps: '静态抽样:1 | 2 | 4 | 8',
58
- clip: '原视频上的静态片段秒数:开始:结束', model: '有权使用的模型配置编号', out: '制品输出目录',
59
- timeout: '本地等待的最长秒数,远端任务仍可恢复', resume: '恢复已有任务编号,不能与新输入组合使用',
60
- invalidArguments: '视频命令参数无效。', workspaceMissing: '请指定 --workspace,或在云端工作区目录内运行。',
61
- workspaceMismatch: '指定的工作区与当前目录的工作区上下文不一致。',
62
- videoMissing: '视频必须是可读的普通文件。', videoQuota: '视频超出 100 MiB、180 秒或支持的画面尺寸。',
63
- videoFormat: '文件不是支持的 MP4、MOV 或 WebM 视频。', mediaTool: '需要 FFmpeg 和 ffprobe,请检查受管运行环境安装。',
64
- outputConflict: '输出目录属于另一轮任务,请使用空目录。', invalidContext: '上下文无效,或属于另一份视频。',
65
- unsafeOutput: '制品目录包含符号链接或不支持的输出路径。',
66
- gitExcludeWarning: '无法更新 Git 本地忽略规则。视频分析将继续,请勿将 .playcraft/video-replication 证据提交到仓库。',
67
- invalidResult: '视频服务返回的证据无效或不完整。', sourceChanged: '视频在探测后或任务创建后发生了变化。',
68
- uploadFailed: '视频上传未完成。', modelUnavailable: '没有有权使用且支持所需视频模式的模型。',
69
- resumeMissing: '找不到保存的请求,或请求与任务、工作区不一致。',
70
- timeoutReached: '本地等待结束,请恢复此任务核对已有结果。',
71
- interrupted: '操作已中断,尚未请求或确认远端取消。',
72
- uncertain: '远端结果未知,请核对此任务,不要另建分析。', remoteFailed: '远端分析失败或已取消。',
73
- failed: '视频理解失败,请先核对已保存的请求和任务再重试。',
74
- probing: '正在探测视频', uploading: '正在上传视频', submitting: '正在提交分析',
75
- preparing: '正在准备视频命令', loadingModels: '正在加载有权使用的视频模型',
76
- initializingUpload: '正在初始化视频上传', finalizingUpload: '正在校验已上传的视频',
77
- failureStage: '失败阶段', failureReason: '具体原因', mediaExit: '媒体工具退出状态',
78
- mediaTimedOut: '媒体工具执行超时', mediaOutputLimit: '媒体工具输出超出限制',
79
- waiting: '正在等待已有分析', extracting: '正在抽取证据关键帧',
80
- summary: '概述', observations: '观察事实', events: '事件', inferences: '推断', unknowns: '未知项',
81
- hints: '复刻建议', evidence: '证据', entities: '实体', assets: '素材', rules: '候选规则',
82
- transcriptNotice: '观察事件仅覆盖视频展示的路径;操作方式和隐藏规则的推断仍需确认。',
83
- },
84
- };
85
- export function videoMessage(key) {
86
- const locale = process.env.PLAYCRAFT_LANGUAGE || process.env.LANG || 'en';
87
- return messages[locale.startsWith('zh') ? 'zh' : 'en'][key];
88
- }
89
- export class VideoCliError extends Error {
90
- code;
91
- exitCode;
92
- constructor(code, exitCode = 4, options) {
93
- super(videoMessage(code), options);
94
- this.code = code;
95
- this.exitCode = exitCode;
96
- }
97
- }
@@ -1,67 +0,0 @@
1
- const messages = {
2
- en: {
3
- description: 'Download cloud workspaces and push local commits back',
4
- clone: 'Clone the current workspace files, including uncommitted changes',
5
- push: 'Push local commits back; reject concurrent cloud changes',
6
- workspaceId: 'Cloud workspace identifier', directory: 'Engineering directory, or root for the whole workspace',
7
- target: 'Local checkout directory', url: 'PlayCraft service base address, including any environment prefix',
8
- token: 'Personal access token', json: 'Print structured output',
9
- invalidTarget: 'Invalid workspace identifier, directory, or service address.',
10
- directoryExists: 'The target directory already exists. Choose an empty new directory.',
11
- metadataMissing: 'No workspace checkout metadata found. Run workspace clone first.',
12
- cleanRequired: 'Commit or discard local changes before running workspace push.',
13
- notReady: 'Workspace access is not ready. Open the workspace and retry.',
14
- conflict: 'Cloud files changed since this checkout. Clone again and merge your changes before pushing.',
15
- failed: 'Workspace transfer failed', cloned: 'Workspace cloned:', pushed: 'Local commits pushed to the cloud workspace.',
16
- tooLarge: 'The service rejected this transfer because of its size. Check the workspace quota and the service upload configuration; direct download cannot upload your changes.',
17
- byteCount: '{value} bytes',
18
- quotaExceeded: 'Push would use {actual}, exceeding the workspace quota of {limit}. Reduce the committed files or ask an administrator to increase the quota. Cloud files were not changed.',
19
- diskFull: 'Insufficient disk space for transfer staging or file replacement. Required: {actual}; available after reserved space: {limit}. Free disk space and retry.',
20
- diskFullUnknown: 'The disk filled while preparing or applying the transfer. Free disk space on the local computer or sandbox and retry. Your local commits are preserved.',
21
- diskUnavailable: 'Could not check available workspace storage. Retry or ask an administrator to check the sandbox disk.',
22
- proxyTooLarge: 'The upload gateway rejected the transfer (413). Ask an administrator to increase the gateway upload limit; direct download cannot upload your changes.',
23
- timeout: 'Workspace transfer timed out. Your local commits are preserved. Retry the push to confirm its result; ask an administrator to check service timeouts if it repeats.',
24
- network: 'Could not reach the workspace service. Check the service address and your connection, then retry. Your local commits are preserved.',
25
- busy: 'The workspace has an active task, terminal, or file write. Wait for it to finish, then retry the push.',
26
- gitMissing: 'Git is not installed or is unavailable on the command path. Install Git and retry.',
27
- gitFailed: 'Git could not prepare or apply the workspace transfer. Check local repository integrity and available disk space; retry or contact an administrator.',
28
- baseMissing: 'The original workspace snapshot is missing from this local repository. Clone the workspace again and merge your local files before pushing.',
29
- invalidTransfer: 'The workspace contains an unsupported path, symbolic link, or invalid transfer data. Check the committed files before retrying.',
30
- upgradeRequired: 'This server does not support incremental workspace transfer. Upgrade the server before pushing with this command.',
31
- preflight: 'Push preflight passed: {files} files, {bytes} of content. Preparing incremental transfer.',
32
- upload: 'Uploading incremental transfer: {bytes}.',
33
- login: 'Log in to the target environment using playcraft login --url',
34
- },
35
- zh: {
36
- description: '下载云工作区,并将本地提交推送回来', clone: '克隆当前工作区文件,包含尚未提交的修改',
37
- push: '把本地提交推送回来;云端有新修改时拒绝覆盖', workspaceId: '云工作区标识',
38
- directory: '工程目录;root 表示整个工作区', target: '本地克隆目录',
39
- url: 'PlayCraft 服务基址,保留环境路径前缀', token: '个人访问令牌', json: '输出结构化结果',
40
- invalidTarget: '工作区标识、目录或服务地址无效。', directoryExists: '目标目录已存在,请选择新的目录。',
41
- metadataMissing: '未找到工作区克隆信息,请先运行 workspace clone。', cleanRequired: '请先提交或丢弃本地修改,再运行 workspace push。',
42
- notReady: '工作区访问尚未就绪,请打开工作区后重试。', conflict: '云端文件在克隆后发生变化,请重新克隆并合并本地修改后再推送。',
43
- failed: '工作区传输失败', cloned: '工作区已克隆到:', pushed: '本地提交已推送回云工作区。',
44
- tooLarge: '服务端因大小拒绝了本次传输。请检查工作区配额及服务上传配置;直接下载无法把本地修改推回云端。',
45
- byteCount: '{value} 字节',
46
- quotaExceeded: '推送后工作区将占用 {actual},超过配额 {limit}。请减少已提交的文件,或联系管理员提高配额。云端文件未被修改。',
47
- diskFull: '暂存传输包或替换文件所需的磁盘空间不足。需要 {actual};保留余量后可用 {limit}。请释放磁盘空间后重试。',
48
- diskFullUnknown: '准备或应用传输时磁盘已满。请释放本机或沙箱磁盘空间后重试,本地提交已保留。',
49
- diskUnavailable: '无法检查工作区存储空间。请重试,或联系管理员检查沙箱磁盘。',
50
- proxyTooLarge: '上传网关拒绝了本次传输(413)。请联系管理员提高网关上传上限;直接下载无法把本地修改推回云端。',
51
- timeout: '工作区传输超时。本地提交已保留,可重试推送以确认结果;若持续发生,请联系管理员检查服务超时配置。',
52
- network: '无法连接工作区服务。请检查服务地址和网络后重试,本地提交已保留。',
53
- busy: '工作区有正在执行的任务、终端或文件写入。请等待结束后重试推送。',
54
- gitMissing: '未安装 Git 或命令路径中无法找到 Git。请安装后重试。',
55
- gitFailed: 'Git 无法准备或应用工作区传输。请检查本地仓库完整性及磁盘空间,重试或联系管理员。',
56
- baseMissing: '本地仓库缺少最初的工作区快照。请重新克隆工作区,并合并本地文件后再推送。',
57
- invalidTransfer: '工作区包含不支持的路径、符号链接或无效传输数据。请检查已提交文件后重试。',
58
- upgradeRequired: '当前服务端尚不支持工作区增量传输。请升级服务端后再使用此命令推送。',
59
- preflight: '推送预检查通过:{files} 个文件,内容共 {bytes}。正在准备增量传输。',
60
- upload: '正在上传增量传输包:{bytes}。',
61
- login: '请使用 playcraft login --url 登录目标环境',
62
- },
63
- };
64
- export function workspaceMessage(key, values = {}) {
65
- const locale = process.env.PLAYCRAFT_LANGUAGE || process.env.LANG || 'en';
66
- return messages[locale.startsWith('zh') ? 'zh' : 'en'][key].replace(/\{(\w+)\}/g, (placeholder, name) => String(values[name] ?? placeholder));
67
- }
@@ -1,233 +0,0 @@
1
- import { randomUUID } from 'node:crypto';
2
- import { createReadStream, createWriteStream, existsSync } from 'node:fs';
3
- import { mkdir, mkdtemp, readFile, rm, stat, statfs, writeFile } from 'node:fs/promises';
4
- import { tmpdir } from 'node:os';
5
- import { join, resolve } from 'node:path';
6
- import { Readable, Transform } from 'node:stream';
7
- import { pipeline } from 'node:stream/promises';
8
- import { RESOURCE_GRANT_ACTIONS, workspaceSessionScopeSchema } from '@playcraft/common/cloud-workspace/runtime';
9
- import { PlayCraftHttpClient } from '../utils/playcraft-http-client.js';
10
- import { createWorkspacePushTransfer, inspectWorkspaceCommit, RAW_ATTRIBUTES, runTransferGit, transferGit } from '../workspace-runtime/workspaces/transfer.js';
11
- import { workspaceMessage as message } from './messages.js';
12
- import { normalizeWorkspaceTransferError, transferByteCount, workspaceTransferFailure } from './transfer-errors.js';
13
- const META_FILE = '.playcraft-workspace.json';
14
- export function workspaceServiceUrl(baseUrl, path) {
15
- const base = new URL(baseUrl);
16
- if (!['http:', 'https:'].includes(base.protocol) || base.username || base.password || base.search || base.hash)
17
- throw new Error(message('invalidTarget'));
18
- return `${base.toString().replace(/\/+$/, '')}/${path.replace(/^\/+/, '')}`;
19
- }
20
- async function request(client, path, init = {}) {
21
- const headers = new Headers(init.headers);
22
- headers.set('Authorization', `Bearer ${client.token}`);
23
- headers.set('X-Request-Id', client.requestId);
24
- let response;
25
- try {
26
- response = await fetch(workspaceServiceUrl(client.baseUrl, path), {
27
- ...init, headers, redirect: 'error', signal: AbortSignal.timeout(15 * 60_000),
28
- });
29
- }
30
- catch (error) {
31
- throw normalizeWorkspaceTransferError(error);
32
- }
33
- if (response.ok)
34
- return response;
35
- const body = await response.json().catch(() => ({}));
36
- const value = body && typeof body === 'object' ? body : {};
37
- const nested = value.error && typeof value.error === 'object' ? value.error : {};
38
- const code = String(nested.code ?? value.reason ?? value.code ?? value.message ?? value.error ?? response.status);
39
- const rawDetails = nested.details ?? value.details;
40
- const details = rawDetails && typeof rawDetails === 'object' ? rawDetails : undefined;
41
- if (response.status === 401)
42
- throw new Error(`${message('login')} ${client.baseUrl}`);
43
- if (code.startsWith('workspace_transfer_') || code === 'invalid_workspace_transfer')
44
- throw workspaceTransferFailure(code, details);
45
- if (response.status === 413)
46
- throw workspaceTransferFailure('workspace_transfer_proxy_too_large');
47
- if (response.status === 408 || response.status === 504)
48
- throw workspaceTransferFailure('workspace_transfer_timeout');
49
- throw workspaceTransferFailure(code, details);
50
- }
51
- async function json(client, path, body) {
52
- const response = await request(client, path, body === undefined ? {} : {
53
- method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(body),
54
- });
55
- const value = await response.json();
56
- return (value?.result ?? value);
57
- }
58
- async function ensureAccess(client, workspaceId, directoryName) {
59
- const workspace = await json(client, `/api/cloud-workspaces/${workspaceId}`);
60
- const scope = workspace.projectId
61
- ? `/api/projects/${encodeURIComponent(workspace.projectId)}/cloud-workspaces/${workspaceId}`
62
- : `/api/cloud-workspaces/${workspaceId}`;
63
- let grant = await json(client, `${scope}/runtime-grants`, {
64
- clientRequestId: `workspace-cli-${randomUUID()}`, actions: RESOURCE_GRANT_ACTIONS,
65
- });
66
- for (let attempt = 0; grant.grantStatus === 'pending' && grant.grantRequestId && attempt < 60; attempt++) {
67
- await new Promise(resolve => setTimeout(resolve, 500));
68
- grant = await json(client, `${scope}/runtime-grants/${encodeURIComponent(grant.grantRequestId)}`);
69
- }
70
- if (grant.grantStatus !== 'ready')
71
- throw new Error(message('notReady'));
72
- let operation = await json(client, `/runtime/workspaces/${workspaceId}/ensure`, { clientRequestId: randomUUID(), directoryName: directoryName === 'root' ? 'basic' : directoryName });
73
- for (let attempt = 0; operation.operationId && ['queued', 'dispatched', 'accepted'].includes(operation.status ?? '') && attempt < 60; attempt++) {
74
- await new Promise(resolve => setTimeout(resolve, 500));
75
- operation = await json(client, `/runtime/operations/${encodeURIComponent(operation.operationId)}`);
76
- }
77
- if (operation.status !== 'completed')
78
- throw new Error(message('notReady'));
79
- }
80
- async function localDiskSpace(path, required) {
81
- const disk = await statfs(path);
82
- const available = disk.bavail * disk.bsize;
83
- if (required > available)
84
- throw workspaceTransferFailure('workspace_transfer_disk_full', { actual: required, limit: available });
85
- return available;
86
- }
87
- async function downloadBundle(response, target, temporary) {
88
- if (!response.body)
89
- throw new Error(message('failed'));
90
- try {
91
- const available = await localDiskSpace(temporary, Number(response.headers.get('content-length') ?? 0));
92
- let bytes = 0;
93
- const guard = new Transform({ transform(chunk, _encoding, callback) {
94
- bytes += chunk.length;
95
- callback(bytes > available ? workspaceTransferFailure('workspace_transfer_disk_full', { actual: bytes, limit: available }) : null, chunk);
96
- } });
97
- await pipeline(Readable.fromWeb(response.body), guard, createWriteStream(target, { flags: 'wx', mode: 0o600 }));
98
- const declared = response.headers.get('content-length');
99
- if (declared && Number(declared) !== bytes)
100
- throw workspaceTransferFailure('invalid_workspace_transfer');
101
- }
102
- finally {
103
- await response.body.cancel().catch(() => undefined);
104
- }
105
- }
106
- export async function workspaceClone(options) {
107
- const workspaceId = options.workspaceId.trim(), directoryName = options.directory ?? 'basic';
108
- if (!/^[a-f0-9-]{36}$/i.test(workspaceId) || !workspaceSessionScopeSchema.safeParse(directoryName).success)
109
- throw new Error(message('invalidTarget'));
110
- const target = resolve(options.dir?.trim() || `workspace-${workspaceId}-${directoryName}`);
111
- if (existsSync(target))
112
- throw new Error(message('directoryExists'));
113
- const client = new PlayCraftHttpClient(options);
114
- await ensureAccess(client, workspaceId, directoryName);
115
- const temporary = await mkdtemp(join(tmpdir(), 'playcraft-clone-'));
116
- let created = false;
117
- try {
118
- const response = await request(client, `/runtime/workspaces/${workspaceId}/git-bundle?directoryName=${encodeURIComponent(directoryName)}`);
119
- const tree = response.headers.get('x-playcraft-workspace-tree');
120
- if (!tree || !/^[a-f0-9]{40,64}$/.test(tree)) {
121
- await response.body?.cancel();
122
- throw new Error(message('failed'));
123
- }
124
- const bundlePath = join(temporary, 'workspace.bundle');
125
- await downloadBundle(response, bundlePath, temporary);
126
- await mkdir(target);
127
- created = true;
128
- const contentBytes = Number(response.headers.get('x-playcraft-workspace-content-bytes') ?? 0);
129
- if (Number.isSafeInteger(contentBytes) && contentBytes > 0)
130
- await localDiskSpace(target, contentBytes * 2);
131
- await runTransferGit(temporary, ['clone', '--no-checkout', '--', bundlePath, target]);
132
- await writeFile(join(target, '.git', 'info', 'attributes'), RAW_ATTRIBUTES);
133
- await runTransferGit(target, ['checkout', '--force', 'HEAD']);
134
- if (transferGit(target, ['rev-parse', 'HEAD^{tree}']) !== tree)
135
- throw new Error(message('failed'));
136
- transferGit(target, ['config', '--unset-all', 'remote.origin.url']);
137
- const meta = { schemaVersion: 'playcraft.workspace-checkout.v1', workspaceId, directoryName,
138
- baseUrl: client.baseUrl, tree };
139
- await writeFile(join(target, META_FILE), `${JSON.stringify(meta, null, 2)}\n`);
140
- const excludePath = join(target, '.git', 'info', 'exclude');
141
- const exclude = await readFile(excludePath, 'utf8').catch(() => '');
142
- await writeFile(excludePath, `${exclude}\n/${META_FILE}\n`);
143
- if (options.json)
144
- console.log(JSON.stringify({ ok: true, command: 'workspace.clone', data: { ...meta, dir: target } }));
145
- else
146
- console.log(`${message('cloned')} ${target}`);
147
- }
148
- catch (error) {
149
- if (created)
150
- await rm(target, { recursive: true, force: true });
151
- throw normalizeWorkspaceTransferError(error);
152
- }
153
- finally {
154
- await rm(temporary, { recursive: true, force: true });
155
- }
156
- }
157
- export async function workspacePush(options = {}) {
158
- const root = resolve(options.dir?.trim() || process.cwd());
159
- let meta;
160
- try {
161
- meta = JSON.parse(await readFile(join(root, META_FILE), 'utf8'));
162
- if (meta.schemaVersion !== 'playcraft.workspace-checkout.v1' || !/^[a-f0-9-]{36}$/i.test(meta.workspaceId) ||
163
- !workspaceSessionScopeSchema.safeParse(meta.directoryName).success || !/^[a-f0-9]{40,64}$/.test(meta.tree))
164
- throw new Error();
165
- workspaceServiceUrl(meta.baseUrl, '/');
166
- }
167
- catch {
168
- throw new Error(message('metadataMissing'));
169
- }
170
- if (transferGit(root, ['status', '--porcelain']).length > 0)
171
- throw new Error(message('cleanRequired'));
172
- const client = new PlayCraftHttpClient({ url: options.url || meta.baseUrl, token: options.token });
173
- if (workspaceServiceUrl(client.baseUrl, '/') !== workspaceServiceUrl(meta.baseUrl, '/'))
174
- throw new Error(message('invalidTarget'));
175
- await ensureAccess(client, meta.workspaceId, meta.directoryName);
176
- const targetTree = transferGit(root, ['rev-parse', 'HEAD^{tree}']);
177
- const stats = await inspectWorkspaceCommit(root, targetTree).catch(error => { throw normalizeWorkspaceTransferError(error); });
178
- const path = `/runtime/workspaces/${meta.workspaceId}/git-bundle?directoryName=${encodeURIComponent(meta.directoryName)}`;
179
- const preflightResponse = await request(client, `${path}&preflight=1&contentBytes=${stats.bytes}&fileCount=${stats.files}&expectedTree=${meta.tree}&targetTree=${targetTree}`);
180
- if (!preflightResponse.headers.get('content-type')?.includes('application/json')) {
181
- await preflightResponse.body?.cancel();
182
- throw workspaceTransferFailure('workspace_transfer_upgrade_required');
183
- }
184
- const preflight = await preflightResponse.json();
185
- if (preflight.protocolVersion !== 2)
186
- throw workspaceTransferFailure('workspace_transfer_upgrade_required');
187
- if (preflight.alreadyApplied && preflight.tree === targetTree) {
188
- meta.tree = targetTree;
189
- await writeFile(join(root, META_FILE), `${JSON.stringify(meta, null, 2)}\n`);
190
- if (options.json)
191
- console.log(JSON.stringify({ ok: true, command: 'workspace.push', data: { tree: targetTree, changedPaths: [] } }));
192
- else
193
- console.log(message('pushed'));
194
- return;
195
- }
196
- if (!options.json)
197
- console.error(message('preflight', { files: stats.files, bytes: transferByteCount(stats.bytes) }));
198
- let snapshot;
199
- try {
200
- snapshot = await createWorkspacePushTransfer(root, meta.tree);
201
- if (snapshot.tree !== targetTree)
202
- throw workspaceTransferFailure('workspace_transfer_conflict');
203
- const bundleBytes = (await stat(snapshot.bundlePath)).size;
204
- if (!options.json)
205
- console.error(message('upload', { bytes: transferByteCount(bundleBytes) }));
206
- const stream = createReadStream(snapshot.bundlePath);
207
- let response;
208
- try {
209
- response = await request(client, path, {
210
- method: 'POST', headers: { 'content-type': 'application/octet-stream', 'content-length': String(bundleBytes),
211
- 'x-playcraft-workspace-tree': meta.tree }, body: stream, duplex: 'half',
212
- });
213
- }
214
- finally {
215
- stream.destroy();
216
- }
217
- const result = await response.json();
218
- if (!/^[a-f0-9]{40,64}$/.test(result.tree))
219
- throw new Error(message('failed'));
220
- meta.tree = result.tree;
221
- await writeFile(join(root, META_FILE), `${JSON.stringify(meta, null, 2)}\n`);
222
- if (options.json)
223
- console.log(JSON.stringify({ ok: true, command: 'workspace.push', data: result }));
224
- else
225
- console.log(message('pushed'));
226
- }
227
- catch (error) {
228
- throw normalizeWorkspaceTransferError(error);
229
- }
230
- finally {
231
- await snapshot?.cleanup();
232
- }
233
- }
@@ -1,48 +0,0 @@
1
- import { WorkspaceTransferError } from '../workspace-runtime/workspaces/transfer.js';
2
- import { workspaceMessage as message } from './messages.js';
3
- export class WorkspaceCliTransferError extends Error {
4
- code;
5
- details;
6
- constructor(code, text, details) {
7
- super(text);
8
- this.code = code;
9
- this.details = details;
10
- }
11
- }
12
- export function transferByteCount(value) {
13
- return typeof value === 'number' && Number.isFinite(value)
14
- ? message('byteCount', { value: value.toLocaleString('en-US') }) : message('byteCount', { value: '—' });
15
- }
16
- export function workspaceTransferFailure(code, details) {
17
- const key = code === 'workspace_transfer_quota_exceeded' ? 'quotaExceeded'
18
- : code === 'workspace_transfer_disk_full' ? typeof details?.actual === 'number' && typeof details.limit === 'number' ? 'diskFull' : 'diskFullUnknown'
19
- : code === 'workspace_transfer_storage_unavailable' ? 'diskUnavailable'
20
- : code === 'workspace_transfer_proxy_too_large' ? 'proxyTooLarge'
21
- : code === 'workspace_transfer_too_large' ? 'tooLarge'
22
- : code.includes('timeout') ? 'timeout'
23
- : code === 'workspace_transfer_network' ? 'network'
24
- : code === 'workspace_transfer_conflict' ? 'conflict'
25
- : code === 'workspace_transfer_busy' ? 'busy'
26
- : code === 'workspace_transfer_git_missing' ? 'gitMissing'
27
- : code === 'workspace_transfer_base_missing' ? 'baseMissing'
28
- : code.startsWith('workspace_transfer_git_') ? 'gitFailed'
29
- : code === 'invalid_workspace_transfer' || code === 'workspace_transfer_symlink' ? 'invalidTransfer'
30
- : code === 'workspace_transfer_upgrade_required' ? 'upgradeRequired' : 'failed';
31
- const text = message(key, { actual: transferByteCount(details?.actual), limit: transferByteCount(details?.limit) });
32
- return new WorkspaceCliTransferError(code, key === 'failed' ? `${text}: ${code}` : text, details);
33
- }
34
- export function normalizeWorkspaceTransferError(error) {
35
- if (error instanceof WorkspaceCliTransferError)
36
- return error;
37
- if (error instanceof WorkspaceTransferError)
38
- return workspaceTransferFailure(error.code, error.details);
39
- const value = (error && typeof error === 'object' ? error : {});
40
- if (value.code === 'ENOSPC')
41
- return workspaceTransferFailure('workspace_transfer_disk_full');
42
- if (/Timeout|Abort/.test(value.name ?? '') || /TIMEOUT/.test(value.cause?.code ?? ''))
43
- return workspaceTransferFailure('workspace_transfer_timeout');
44
- if (/UND_ERR_SOCKET|ECONNRESET|ECONNREFUSED|ENOTFOUND|EPIPE/.test(value.cause?.code ?? value.code ?? '') ||
45
- error instanceof TypeError && /fetch|network|terminated/i.test(error.message))
46
- return workspaceTransferFailure('workspace_transfer_network');
47
- return error instanceof Error ? error : new Error(String(error));
48
- }
@@ -1,30 +0,0 @@
1
- import { gitRead } from './git.js';
2
- const reference = /^(?:[a-f0-9]{40}|[a-f0-9]{64})$/;
3
- const excludedDirectories = new Set(['node_modules', 'dist', 'build', 'coverage', 'docs', 'test', 'tests', '__tests__']);
4
- const contentExtension = /\.(?:[cm]?[jt]sx?|vue|svelte|html?|css|s[ac]ss|less|json5?|ya?ml|xml|glsl|wgsl|vert|frag|lua|py|svg|png|jpe?g|webp|avif|gif|bmp|mp[34]|wav|ogg|m4a|webm|glb|gltf|fbx|obj|bin|atlas|woff2?|ttf|otf)$/i;
5
- function contentPath(path) {
6
- const parts = path.split('/');
7
- if (parts.some(part => part.startsWith('.') || excludedDirectories.has(part)))
8
- return false;
9
- const name = parts.at(-1);
10
- if (/^(?:package(?:-lock)?\.json|npm-shrinkwrap\.json|pnpm-lock\.yaml|yarn\.lock|bun\.lockb?|tsconfig(?:\.[^.]+)?\.json|(?:vite|vitest|webpack|eslint|prettier)\.config\..+)$/i.test(name))
11
- return false;
12
- return contentExtension.test(name);
13
- }
14
- /** A completed batch member must change code, runtime configuration, or assets. */
15
- export async function requireBatchContentChanges(root, before, after) {
16
- if (!reference.test(before) || !reference.test(after))
17
- throw new Error('batch_change_reference_invalid');
18
- const stdout = await gitRead(root, ['diff', '--raw', '--no-abbrev', '--no-renames', '-z', before, after, '--']);
19
- const records = stdout.split('\0'), paths = [];
20
- for (let index = 0; index + 1 < records.length; index += 2) {
21
- const [oldMode, newMode, oldBlob, newBlob] = records[index].slice(1).split(' ');
22
- const path = records[index + 1];
23
- if ((oldMode === '100644' || oldMode === '100755' || newMode === '100644' || newMode === '100755')
24
- && oldBlob !== newBlob && contentPath(path))
25
- paths.push(path);
26
- }
27
- if (!paths.length)
28
- throw new Error('batch_generation_no_content_change');
29
- return paths;
30
- }
@@ -1,86 +0,0 @@
1
- import { setTimeout as delay } from 'node:timers/promises';
2
- import { sandboxBatchMemberStopSchema } from '@playcraft/common/cloud-workspace/runtime';
3
- import { groupExited, stopProcessGroup } from './processes.js';
4
- import { settleObservedGenerate } from './generate.js';
5
- import { memberStatus, readMember, serializeRun, writeMember, writeStopMarker } from './records.js';
6
- async function prove(record) {
7
- let stopped = true;
8
- for (const process of record.processes) {
9
- if (process.stopped || groupExited(process.pid))
10
- process.stopped = true;
11
- else {
12
- process.stopped = await stopProcessGroup(process);
13
- if (!process.stopped)
14
- stopped = false;
15
- }
16
- }
17
- return stopped;
18
- }
19
- function sessionBusy(state, record) {
20
- const session = record.sessionId ? state.journal.getSession(record.sessionId) : undefined;
21
- if (!session)
22
- return false;
23
- return session.turnBlock === 'uncertain' || session.turnStatus === 'starting' || session.turnStatus === 'running';
24
- }
25
- /** Read-only besides reconciling process proof. Does not start work or advance a phase. */
26
- export async function readBatchMemberStatus(state, runId) {
27
- const record = await readMember(state, runId);
28
- if (!record)
29
- return undefined;
30
- if (record.phase === 'generate' && record.state === 'running') {
31
- const settled = await settleObservedGenerate(state, record);
32
- if (settled.state !== 'running')
33
- return memberStatus(settled);
34
- }
35
- const processes = record.processes.map(process => ({ ...process, stopped: process.stopped || groupExited(process.pid) }));
36
- const live = processes.some(process => !process.stopped);
37
- let next = { ...record, processes };
38
- if (live && (record.writersStopped || record.state === 'completed' || record.state === 'stopped' || record.state === 'needs_user' || record.state === 'failed')) {
39
- next = { ...next, writersStopped: false, state: record.stopRequested ? 'stopping' : 'unknown', holding: true };
40
- }
41
- else if (!live && record.state === 'running') {
42
- const turnLive = sessionBusy(state, record);
43
- next = { ...next, writersStopped: !turnLive, state: record.stopRequested ? 'stopped' : turnLive ? 'running' : 'unknown', holding: turnLive || !record.stopRequested };
44
- }
45
- if (JSON.stringify(next) !== JSON.stringify(record))
46
- next = await writeMember(state, next);
47
- return memberStatus(next);
48
- }
49
- export async function stopBatchMember(state, runId, body) {
50
- const parsed = sandboxBatchMemberStopSchema.safeParse({ ...(body && typeof body === 'object' ? body : {}), runId });
51
- if (!parsed.success)
52
- throw new Error('invalid_batch_request');
53
- const command = parsed.data;
54
- return serializeRun(runId, async () => {
55
- const existing = await readMember(state, runId);
56
- if (existing && command.ownerFence < existing.ownerFence)
57
- throw new Error('stale_owner');
58
- if (existing?.state === 'completed' && existing.phase === 'deliver' && existing.evidence && existing.writersStopped)
59
- return memberStatus(existing);
60
- await writeStopMarker(state, runId, command.ownerFence);
61
- const session = existing?.sessionId ? state.journal.getSession(existing.sessionId) : undefined;
62
- if (session?.threadId && existing?.sessionId) {
63
- await state.native?.interrupt?.({ sessionId: existing.sessionId, threadId: session.threadId }).catch(() => undefined);
64
- const deadline = Date.now() + 2_000;
65
- while (sessionBusy(state, existing) && Date.now() < deadline)
66
- await delay(15);
67
- }
68
- const record = existing ?? {
69
- runId, ownerFence: command.ownerFence, occupancyId: '00000000-0000-0000-0000-000000000000', workspaceId: '00000000-0000-0000-0000-000000000000',
70
- directoryName: 'basic', phase: 'prepare', state: 'stopping', writersStopped: false, holding: true, stopRequested: true, processes: [],
71
- updatedAt: new Date().toISOString(),
72
- };
73
- const writersStopped = await prove(record) && !sessionBusy(state, record);
74
- const saved = await writeMember(state, {
75
- ...record, ownerFence: command.ownerFence, stopRequested: true, state: writersStopped ? 'stopped' : 'stopping',
76
- writersStopped, holding: !writersStopped,
77
- });
78
- return memberStatus(saved);
79
- });
80
- }
81
- export async function rememberProcess(state, runId, process) {
82
- const record = await readMember(state, runId);
83
- if (!record)
84
- return;
85
- await writeMember(state, { ...record, processes: [...record.processes.filter(item => item.pid !== process.pid), process] });
86
- }