@playcraft/cli 0.1.27 → 0.1.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -38
- package/dist/agent/local-backend.js +1 -1
- package/dist/cli-root-help.js +0 -2
- package/dist/commands/build.js +4 -9
- package/dist/commands/create.js +33 -26
- package/dist/commands/image.js +6 -2
- package/dist/commands/login.js +42 -84
- package/dist/commands/skills.js +0 -2
- package/dist/commands/tools-3d.js +0 -11
- package/dist/commands/tools-generation.js +109 -68
- package/dist/commands/tools-image-context.js +23 -0
- package/dist/commands/tools.js +2 -2
- package/dist/config.js +4 -59
- package/dist/index.js +3 -34
- package/dist/remix/clone.js +0 -2
- package/dist/remix/init-template.js +0 -2
- package/dist/remix/pull.js +0 -2
- package/dist/remix/push.js +1 -21
- package/dist/utils/agent-api-client.js +30 -185
- package/dist/utils/image-asset-context.js +105 -0
- package/dist/utils/playcraft-http-client.js +4 -6
- package/package.json +5 -14
- package/project-template/.claude/skills/playcraft-image-generation/SKILL.md +81 -23
- package/project-templates/phaser/.claude/skills/playcraft-image-generation/SKILL.md +81 -23
- package/project-templates/threejs/.claude/skills/playcraft-image-generation/SKILL.md +81 -23
- package/dist/auth/account-activation.js +0 -157
- package/dist/auth/messages.js +0 -30
- package/dist/commands/platform-skills.generated.js +0 -19
- package/dist/commands/playable.js +0 -53
- package/dist/commands/tools-batch.js +0 -87
- package/dist/commands/video.js +0 -111
- package/dist/commands/workspace-runtime.js +0 -54
- package/dist/project-skills/builtin-import.js +0 -225
- package/dist/project-skills/commands.js +0 -77
- package/dist/project-skills/lifecycle.js +0 -28
- package/dist/project-skills/local-run.js +0 -112
- package/dist/project-skills/local-store.js +0 -221
- package/dist/project-skills/messages.js +0 -80
- package/dist/project-skills/reconcile.js +0 -62
- package/dist/project-skills/remote-cache.js +0 -51
- package/dist/project-skills/validation.js +0 -19
- package/dist/recording/messages.js +0 -40
- package/dist/recording/project-digest.js +0 -85
- package/dist/recording/recorder.js +0 -293
- package/dist/recording/scenario.js +0 -50
- package/dist/utils/environment-endpoints.js +0 -17
- package/dist/utils/tool-operation-journal.js +0 -124
- package/dist/utils/video-evidence-git.js +0 -81
- package/dist/video-replication/client.js +0 -222
- package/dist/video-replication/comparison-evidence.js +0 -149
- package/dist/video-replication/comparison-files.js +0 -57
- package/dist/video-replication/comparison-log.js +0 -72
- package/dist/video-replication/comparison-messages.js +0 -104
- package/dist/video-replication/comparison-output.js +0 -63
- package/dist/video-replication/comparison-preflight.js +0 -66
- package/dist/video-replication/comparison.js +0 -216
- package/dist/video-replication/evidence.js +0 -165
- package/dist/video-replication/media.js +0 -111
- package/dist/video-replication/messages.js +0 -89
- package/dist/workspace-runtime/codex/app-server.js +0 -636
- package/dist/workspace-runtime/codex/config-toml.js +0 -107
- package/dist/workspace-runtime/codex/jsonrpc-stdio.js +0 -123
- package/dist/workspace-runtime/codex/launcher-client.js +0 -163
- package/dist/workspace-runtime/codex/loopback.js +0 -143
- package/dist/workspace-runtime/codex/model-broker.js +0 -258
- package/dist/workspace-runtime/codex/native-adapter.js +0 -9
- package/dist/workspace-runtime/main.js +0 -10
- package/dist/workspace-runtime/persistence/journal.js +0 -355
- package/dist/workspace-runtime/persistence/native-subagents.js +0 -162
- package/dist/workspace-runtime/persistence/sqlite-client.js +0 -77
- package/dist/workspace-runtime/persistence/sqlite-worker.js +0 -1057
- package/dist/workspace-runtime/previews/publish.js +0 -259
- package/dist/workspace-runtime/previews/single-file.js +0 -43
- package/dist/workspace-runtime/processes/managed-writes.js +0 -69
- package/dist/workspace-runtime/production/contracts.js +0 -17
- package/dist/workspace-runtime/production/controller.js +0 -207
- package/dist/workspace-runtime/production/dependencies.js +0 -60
- package/dist/workspace-runtime/production/native.js +0 -90
- package/dist/workspace-runtime/production/processes.js +0 -86
- package/dist/workspace-runtime/production/save-command.js +0 -24
- package/dist/workspace-runtime/production/source-copy.js +0 -91
- package/dist/workspace-runtime/production/stages.js +0 -202
- package/dist/workspace-runtime/production/storage.js +0 -32
- package/dist/workspace-runtime/serve.js +0 -202
- package/dist/workspace-runtime/server/auth.js +0 -21
- package/dist/workspace-runtime/server/connectivity.js +0 -201
- package/dist/workspace-runtime/server/desktop-host.js +0 -429
- package/dist/workspace-runtime/server/desktop-preview-config.js +0 -81
- package/dist/workspace-runtime/server/desktop-preview-service.js +0 -157
- package/dist/workspace-runtime/server/desktop-preview-static.js +0 -53
- package/dist/workspace-runtime/server/desktop-preview.js +0 -189
- package/dist/workspace-runtime/server/dispatch.js +0 -903
- package/dist/workspace-runtime/server/endpoints.js +0 -19
- package/dist/workspace-runtime/server/execution-group.js +0 -85
- package/dist/workspace-runtime/server/http.js +0 -984
- package/dist/workspace-runtime/server/lock.js +0 -53
- package/dist/workspace-runtime/server/rfb-watch-gate.js +0 -168
- package/dist/workspace-runtime/server/terminal-host.js +0 -294
- package/dist/workspace-runtime/server/types.js +0 -1
- package/dist/workspace-runtime/workspaces/artifact-events.js +0 -55
- package/dist/workspace-runtime/workspaces/artifact-files.js +0 -195
- package/dist/workspace-runtime/workspaces/artifact-receipts.js +0 -89
- package/dist/workspace-runtime/workspaces/artifacts.js +0 -260
- package/dist/workspace-runtime/workspaces/attachment-content.js +0 -111
- package/dist/workspace-runtime/workspaces/attachments.js +0 -175
- package/dist/workspace-runtime/workspaces/batch-commit.js +0 -142
- package/dist/workspace-runtime/workspaces/cli-context.js +0 -23
- package/dist/workspace-runtime/workspaces/cli-credentials.js +0 -111
- package/dist/workspace-runtime/workspaces/context-error.js +0 -2
- package/dist/workspace-runtime/workspaces/dependencies.js +0 -264
- package/dist/workspace-runtime/workspaces/developer-command.js +0 -64
- package/dist/workspace-runtime/workspaces/directories.js +0 -113
- package/dist/workspace-runtime/workspaces/directory-access.js +0 -29
- package/dist/workspace-runtime/workspaces/directory-maintenance.js +0 -111
- package/dist/workspace-runtime/workspaces/directory-stats.js +0 -49
- package/dist/workspace-runtime/workspaces/disk-snapshot.js +0 -31
- package/dist/workspace-runtime/workspaces/empty-template.js +0 -40
- package/dist/workspace-runtime/workspaces/files.js +0 -120
- package/dist/workspace-runtime/workspaces/git-credential-broker.js +0 -312
- package/dist/workspace-runtime/workspaces/git-credential-helper.js +0 -68
- package/dist/workspace-runtime/workspaces/git-direct-store.js +0 -155
- package/dist/workspace-runtime/workspaces/git.js +0 -517
- package/dist/workspace-runtime/workspaces/json5-edit.js +0 -170
- package/dist/workspace-runtime/workspaces/parameters.js +0 -272
- package/dist/workspace-runtime/workspaces/prepare.js +0 -264
- package/dist/workspace-runtime/workspaces/registry.js +0 -226
- package/dist/workspace-runtime/workspaces/revisions.js +0 -31
- package/dist/workspace-runtime/workspaces/skill-artifact-loader.js +0 -91
- package/dist/workspace-runtime/workspaces/skills.js +0 -189
- package/dist/workspace-runtime/workspaces/video-attachments.js +0 -49
- package/project-template/.claude/skills/playcraft-replica-validation/SKILL.md +0 -25
- package/project-template/.claude/skills/playcraft-replica-validation/references/contracts.md +0 -79
- package/project-template/.claude/skills/playcraft-video-understanding/SKILL.md +0 -29
- package/project-template/.claude/skills/playcraft-video-understanding/references/contracts.md +0 -37
- package/project-template-v2/.claude/agents/artist.md +0 -82
- package/project-template-v2/.claude/agents/developer.md +0 -153
- package/project-template-v2/.claude/agents/game-designer.md +0 -264
- package/project-template-v2/.claude/agents/refs/artist-art-style-catalog.md +0 -533
- package/project-template-v2/.claude/agents/refs/artist-color-audio-recipes.md +0 -153
- package/project-template-v2/.claude/agents/refs/artist-dimension-axis.md +0 -27
- package/project-template-v2/.claude/agents/refs/artist-master-composite-recipes.md +0 -208
- package/project-template-v2/.claude/agents/refs/atom-skill-library.md +0 -81
- package/project-template-v2/.claude/agents/refs/developer-impl-cookbook.md +0 -432
- package/project-template-v2/.claude/agents/refs/framework-5-component-filter.md +0 -252
- package/project-template-v2/.claude/agents/refs/framework-game-feel-juice.md +0 -266
- package/project-template-v2/.claude/agents/refs/framework-mda.md +0 -147
- package/project-template-v2/.claude/agents/refs/game-designer-gameplay-sufficiency.md +0 -123
- package/project-template-v2/.claude/agents/refs/ta-3d-flip-recipe.md +0 -88
- package/project-template-v2/.claude/agents/refs/ta-atlas-deliverable-standard.md +0 -67
- package/project-template-v2/.claude/agents/refs/ta-batch-pipeline-recipes.md +0 -120
- package/project-template-v2/.claude/agents/refs/ta-image-generation-detail.md +0 -300
- package/project-template-v2/.claude/agents/refs/ta-image-ops-reference.md +0 -495
- package/project-template-v2/.claude/agents/refs/ta-pipeline-cookbook.md +0 -1141
- package/project-template-v2/.claude/agents/refs/ta-tools-reference.md +0 -111
- package/project-template-v2/.claude/agents/refs/ta-vfx-preset-catalog.md +0 -365
- package/project-template-v2/.claude/agents/refs/threejs-cannon-pitfalls.md +0 -412
- package/project-template-v2/.claude/agents/reviewer.md +0 -75
- package/project-template-v2/.claude/agents/technical-artist.md +0 -86
- package/project-template-v2/.claude/hooks/snapshot-milestone.mjs +0 -243
- package/project-template-v2/.claude/hooks/user-prompt.mjs +0 -133
- package/project-template-v2/.claude/settings.json +0 -33
- package/project-template-v2/.claude/skills/brainstorming/SKILL.md +0 -161
- package/project-template-v2/.claude/skills/brainstorming/scripts/frame-template.html +0 -270
- package/project-template-v2/.claude/skills/brainstorming/scripts/helper.js +0 -177
- package/project-template-v2/.claude/skills/brainstorming/scripts/server.cjs +0 -354
- package/project-template-v2/.claude/skills/brainstorming/scripts/start-server.sh +0 -148
- package/project-template-v2/.claude/skills/brainstorming/scripts/stop-server.sh +0 -56
- package/project-template-v2/.claude/skills/brainstorming/scripts/wait-for-selection.sh +0 -62
- package/project-template-v2/.claude/skills/brainstorming/spec-document-reviewer-prompt.md +0 -49
- package/project-template-v2/.claude/skills/brainstorming/visual-companion.md +0 -309
- package/project-template-v2/.claude/skills/playcraft-ad-psychology/SKILL.md +0 -182
- package/project-template-v2/.claude/skills/playcraft-art-style-guide/SKILL.md +0 -123
- package/project-template-v2/.claude/skills/playcraft-asset-state-sheet/SKILL.md +0 -205
- package/project-template-v2/.claude/skills/playcraft-audio-generation/SKILL.md +0 -280
- package/project-template-v2/.claude/skills/playcraft-batch-pipeline/SKILL.md +0 -184
- package/project-template-v2/.claude/skills/playcraft-build-optimizer/SKILL.md +0 -306
- package/project-template-v2/.claude/skills/playcraft-image-generation/SKILL.md +0 -298
- package/project-template-v2/.claude/skills/playcraft-image-generation/reference/build-sprite-sheet.template.mjs +0 -123
- package/project-template-v2/.claude/skills/playcraft-image-generation/reference/compare-style.template.mjs +0 -254
- package/project-template-v2/.claude/skills/playcraft-image-generation/reference/gen-batch-sprite.template.mjs +0 -324
- package/project-template-v2/.claude/skills/playcraft-image-generation/reference/gen-batch.template.mjs +0 -97
- package/project-template-v2/.claude/skills/playcraft-image-generation/reference/gen-edit-variants.template.mjs +0 -118
- package/project-template-v2/.claude/skills/playcraft-image-generation/reference/process-batch.template.mjs +0 -137
- package/project-template-v2/.claude/skills/playcraft-image-generation/reference/prompt-cookbook.md +0 -397
- package/project-template-v2/.claude/skills/playcraft-image-generation/reference/validate-sprite-sheet.template.mjs +0 -296
- package/project-template-v2/.claude/skills/playcraft-image-ops/SKILL.md +0 -122
- package/project-template-v2/.claude/skills/playcraft-image-processing/SKILL.md +0 -219
- package/project-template-v2/.claude/skills/playcraft-masking/SKILL.md +0 -373
- package/project-template-v2/.claude/skills/playcraft-playable-optimization/SKILL.md +0 -161
- package/project-template-v2/.claude/skills/playcraft-research/SKILL.md +0 -215
- package/project-template-v2/.claude/skills/playcraft-skill-recommender/SKILL.md +0 -382
- package/project-template-v2/.claude/skills/playcraft-sprite-generation/SKILL.md +0 -423
- package/project-template-v2/.claude/skills/playcraft-sprite-remix/SKILL.md +0 -158
- package/project-template-v2/.claude/skills/playcraft-sprite-sheet/SKILL.md +0 -100
- package/project-template-v2/.claude/skills/playcraft-storyboard/SKILL.md +0 -167
- package/project-template-v2/.claude/skills/playcraft-style-qa/SKILL.md +0 -270
- package/project-template-v2/.claude/skills/playcraft-text-rendering/SKILL.md +0 -236
- package/project-template-v2/.claude/skills/playcraft-vfx-animation/SKILL.md +0 -130
- package/project-template-v2/.claude/skills/playwright-cli/SKILL.md +0 -390
- package/project-template-v2/.claude/skills/playwright-cli/references/element-attributes.md +0 -23
- package/project-template-v2/.claude/skills/playwright-cli/references/playwright-tests.md +0 -39
- package/project-template-v2/.claude/skills/playwright-cli/references/request-mocking.md +0 -87
- package/project-template-v2/.claude/skills/playwright-cli/references/running-code.md +0 -240
- package/project-template-v2/.claude/skills/playwright-cli/references/session-management.md +0 -226
- package/project-template-v2/.claude/skills/playwright-cli/references/spec-driven-testing.md +0 -308
- package/project-template-v2/.claude/skills/playwright-cli/references/storage-state.md +0 -275
- package/project-template-v2/.claude/skills/playwright-cli/references/test-generation.md +0 -134
- package/project-template-v2/.claude/skills/playwright-cli/references/tracing.md +0 -142
- package/project-template-v2/.claude/skills/playwright-cli/references/video-recording.md +0 -153
- package/project-template-v2/.claude/skills/session-analyzer/SKILL.md +0 -386
- package/project-template-v2/.claude/skills/session-analyzer/scripts/execution-breakdown.mjs +0 -182
- package/project-template-v2/.claude/skills/session-analyzer/scripts/find-turns.mjs +0 -72
- package/project-template-v2/.claude/skills/session-analyzer/scripts/heavy-output.mjs +0 -121
- package/project-template-v2/.claude/skills/session-analyzer/scripts/resolve-session.mjs +0 -102
- package/project-template-v2/.claude/skills/session-analyzer/scripts/subagent-stats.mjs +0 -127
- package/project-template-v2/.claude/skills/session-analyzer/scripts/subagent-tool-timeline.mjs +0 -106
- package/project-template-v2/.claude/skills/session-analyzer/scripts/time-gaps.mjs +0 -128
- package/project-template-v2/.claude/skills/session-analyzer/scripts/turn-timeline.mjs +0 -67
- package/project-template-v2/.claude/snapshot.mjs +0 -263
- package/project-template-v2/.playcraft/skills.lock.json +0 -152
- package/project-template-v2/CLAUDE.md +0 -146
- package/project-template-v2/assets/audio/bgm/.gitkeep +0 -0
- package/project-template-v2/assets/audio/sfx/.gitkeep +0 -0
- package/project-template-v2/assets/bundles/.gitkeep +0 -0
- package/project-template-v2/assets/images/bg/.gitkeep +0 -0
- package/project-template-v2/assets/images/reference/.gitkeep +0 -0
- package/project-template-v2/assets/images/storyboard/.gitkeep +0 -0
- package/project-template-v2/assets/images/tiles/.gitkeep +0 -0
- package/project-template-v2/assets/images/ui/.gitkeep +0 -0
- package/project-template-v2/assets/images/vfx/.gitkeep +0 -0
- package/project-template-v2/assets/models/.gitkeep +0 -0
- package/project-template-v2/docs/harness/iteration-1/context-flow.md +0 -254
- package/project-template-v2/docs/harness/iteration-1/generate-flow.md +0 -91
- package/project-template-v2/docs/harness/iteration-1/ideate-flow.md +0 -214
- package/project-template-v2/docs/harness/iteration-1/optimize-flow.md +0 -75
- package/project-template-v2/docs/harness/iteration-1/wrapup-flow.md +0 -63
- package/project-template-v2/docs/harness/iteration-2/context-flow.md +0 -223
- package/project-template-v2/docs/harness/iteration-2/generate-flow.md +0 -129
- package/project-template-v2/docs/harness/iteration-2/ideate-flow.md +0 -267
- package/project-template-v2/docs/harness/iteration-2/optimize-flow.md +0 -164
- package/project-template-v2/docs/harness/iteration-2/wrapup-flow.md +0 -115
- package/project-template-v2/docs/harness/orchestrator-flow.md +0 -364
- package/project-template-v2/docs/project-state.json +0 -60
- package/project-template-v2/docs/project-state.md +0 -72
- package/project-template-v2/docs/standards/README.md +0 -225
- package/project-template-v2/docs/standards/agent-behavior-standards.md +0 -174
- package/project-template-v2/docs/standards/artifacts/design-brief.md +0 -19
- package/project-template-v2/docs/standards/artifacts/design.md +0 -22
- package/project-template-v2/docs/standards/artifacts/game-code.md +0 -41
- package/project-template-v2/docs/standards/artifacts/todo-list.md +0 -41
- package/project-template-v2/docs/standards/iter1-agent-behavior-standards.md +0 -343
- package/project-template-v2/game/index.ts +0 -18
- package/project-template-v2/globals.d.ts +0 -51
- package/project-template-v2/index.css +0 -34
- package/project-template-v2/index.html +0 -18
- package/project-template-v2/main.ts +0 -9
- package/project-template-v2/package.json +0 -46
- package/project-template-v2/skills/_shared/scripts/dispatch-clear.mjs +0 -31
- package/project-template-v2/skills/_shared/scripts/dispatch-set.mjs +0 -86
- package/project-template-v2/skills/_shared/scripts/dod-check.mjs +0 -153
- package/project-template-v2/skills/_shared/scripts/handoff-append.mjs +0 -70
- package/project-template-v2/skills/_shared/scripts/lib/validator-artifacts.mjs +0 -91
- package/project-template-v2/skills/_shared/scripts/pipeline/dod-config.mjs +0 -131
- package/project-template-v2/skills/_shared/scripts/pipeline/index.mjs +0 -80
- package/project-template-v2/skills/_shared/scripts/pipeline/iteration-1-core.mjs +0 -90
- package/project-template-v2/skills/_shared/scripts/pipeline/iteration-2-wrap.mjs +0 -93
- package/project-template-v2/skills/_shared/scripts/pipeline/iteration-3-visual.mjs +0 -23
- package/project-template-v2/skills/_shared/scripts/render-project-state.mjs +0 -230
- package/project-template-v2/skills/_shared/scripts/state-advance-stage.mjs +0 -58
- package/project-template-v2/skills/_shared/scripts/state-get.mjs +0 -339
- package/project-template-v2/skills/_shared/scripts/state-handoff.mjs +0 -39
- package/project-template-v2/skills/_shared/scripts/state-set.mjs +0 -94
- package/project-template-v2/skills/_shared/scripts/state-store.mjs +0 -783
- package/project-template-v2/skills/_shared/scripts/todo-add.mjs +0 -88
- package/project-template-v2/skills/_shared/scripts/todo-get.mjs +0 -130
- package/project-template-v2/skills/_shared/scripts/todo-remove.mjs +0 -33
- package/project-template-v2/skills/_shared/scripts/todo-set.mjs +0 -47
- package/project-template-v2/skills/_shared/scripts/verify-asset-code-sync.mjs +0 -268
- package/project-template-v2/skills/_shared/scripts/verify-env.mjs +0 -285
- package/project-template-v2/skills/_shared/scripts/verify-placeholders.mjs +0 -161
- package/project-template-v2/skills/playable-autoplay/SKILL.md +0 -176
- package/project-template-v2/skills/playable-autoplay/agents/openai.yaml +0 -4
- package/project-template-v2/skills/playable-debug/SKILL.md +0 -116
- package/project-template-v2/skills/playable-debug/agents/openai.yaml +0 -4
- package/project-template-v2/skills/playable-debug/references/debug-config.md +0 -40
- package/project-template-v2/skills/playable-record/SKILL.md +0 -140
- package/project-template-v2/skills/playable-record/scripts/lib/dev-server.mjs +0 -104
- package/project-template-v2/skills/playable-record/scripts/lib/record-audio-bridge.js +0 -141
- package/project-template-v2/skills/playable-record/scripts/record-playable.mjs +0 -425
- package/project-template-v2/skills/playable-record/scripts/verify-contract.mjs +0 -261
- package/project-template-v2/skills/playable-record/scripts/verify-firstwin.mjs +0 -398
- package/project-template-v2/skills/playable-record/scripts/verify-fusion.mjs +0 -322
- package/project-template-v2/skills/playable-record/scripts/verify-lifecycle.mjs +0 -105
- package/project-template-v2/skills/playable-record/scripts/verify-vlm-video.mjs +0 -230
- package/project-template-v2/skills/playable-validate/SKILL.md +0 -61
- package/project-template-v2/skills/playable-validate/validation-rules.md +0 -14
- package/project-template-v2/skills/playable-verify-ui/SKILL.md +0 -63
- package/project-template-v2/skills/playable-verify-ui/scripts/lib/__init__.py +0 -1
- package/project-template-v2/skills/playable-verify-ui/scripts/lib/config_expr.js +0 -218
- package/project-template-v2/skills/playable-verify-ui/scripts/lib/node_utils.js +0 -51
- package/project-template-v2/skills/playable-verify-ui/scripts/lib/profile_loader.py +0 -59
- package/project-template-v2/skills/playable-verify-ui/scripts/lib/report.py +0 -106
- package/project-template-v2/skills/playable-verify-ui/scripts/lib/runtime_contract.js +0 -116
- package/project-template-v2/skills/playable-verify-ui/scripts/verify_fetch_antipatterns.py +0 -59
- package/project-template-v2/skills/playable-verify-ui/scripts/verify_hardcoded_layout.js +0 -64
- package/project-template-v2/skills/playable-verify-ui/scripts/verify_runtime_contract.js +0 -58
- package/project-template-v2/skills/playable-verify-ui/scripts/verify_text_overlap.py +0 -333
- package/project-template-v2/ta-workspace/scripts/.gitkeep +0 -0
- package/project-template-v2/tsconfig.json +0 -20
- package/project-template-v2/vite.config.ts +0 -27
- package/project-templates/batch-locks/phaser.yaml +0 -922
- package/project-templates/batch-locks/threejs.yaml +0 -978
- package/project-templates/empty/AGENTS.md +0 -25
- package/project-templates/empty/gitignore +0 -33
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import { readFileSync, existsSync } from 'fs';
|
|
2
|
-
import {
|
|
2
|
+
import { join } from 'path';
|
|
3
3
|
import { homedir } from 'os';
|
|
4
4
|
import { loadGlobalConfig } from '../config.js';
|
|
5
5
|
import { DEFAULT_PLAYCRAFT_CLOUD_BASE } from '../commands/login.js';
|
|
6
|
-
import { AGENT_TOOL_OPERATION_PROTOCOL, AGENT_TOOL_OPERATION_HEADERS, AGENT_TOOL_OPERATION_CAPABILITIES_PATH, } from '@playcraft/common/agent-tools';
|
|
7
|
-
import { beginToolOperation } from './tool-operation-journal.js';
|
|
8
|
-
import { businessEndpoint } from './environment-endpoints.js';
|
|
9
|
-
import { AccountActivationError, parseErrorPayload, pendingAccountActivationError, } from '../auth/account-activation.js';
|
|
10
6
|
/**
|
|
11
7
|
* 判断 token 是否为用户 PAT(Personal Access Token)。
|
|
12
8
|
* PAT 以 "playcraft_pat_" 开头;沙箱 JWT 为三段式 base64。
|
|
@@ -19,8 +15,8 @@ function isPatToken(token) {
|
|
|
19
15
|
* or from the CLI after `playcraft login`.
|
|
20
16
|
*
|
|
21
17
|
* 凭证解析优先级:
|
|
22
|
-
* API URL : PLAYCRAFT_API_URL →
|
|
23
|
-
* Token : PLAYCRAFT_SANDBOX_TOKEN →
|
|
18
|
+
* API URL : PLAYCRAFT_API_URL → .playcraft.json → ~/.playcraft/config.json → DEFAULT_PLAYCRAFT_CLOUD_BASE
|
|
19
|
+
* Token : PLAYCRAFT_SANDBOX_TOKEN → .playcraft.json token → ~/.playcraft/config.json token (PAT)
|
|
24
20
|
*
|
|
25
21
|
* 鉴权 header 自动选择:
|
|
26
22
|
* - 沙箱 JWT (非 PAT) → X-Sandbox-Token: <token>(后端 @SandboxToken 路由的沙箱分支)
|
|
@@ -29,7 +25,7 @@ function isPatToken(token) {
|
|
|
29
25
|
export class AgentApiClient {
|
|
30
26
|
apiUrl;
|
|
31
27
|
token;
|
|
32
|
-
|
|
28
|
+
isPat;
|
|
33
29
|
playcraftEnv;
|
|
34
30
|
constructor() {
|
|
35
31
|
const localConfig = AgentApiClient.loadLocalConfig();
|
|
@@ -40,7 +36,7 @@ export class AgentApiClient {
|
|
|
40
36
|
globalConfig.backendUrl ||
|
|
41
37
|
globalConfig.url ||
|
|
42
38
|
DEFAULT_PLAYCRAFT_CLOUD_BASE).replace(/\/+$/, '');
|
|
43
|
-
// Token: 环境变量 →
|
|
39
|
+
// Token: 沙箱 token 环境变量 → 本地 .playcraft.json → 全局 login 配置(PAT)
|
|
44
40
|
const token = process.env.PLAYCRAFT_SANDBOX_TOKEN ||
|
|
45
41
|
localConfig.token ||
|
|
46
42
|
globalConfig.token ||
|
|
@@ -51,147 +47,43 @@ export class AgentApiClient {
|
|
|
51
47
|
}
|
|
52
48
|
this.apiUrl = apiUrl;
|
|
53
49
|
this.token = token;
|
|
54
|
-
this.
|
|
55
|
-
this.playcraftEnv = (process.env.PLAYCRAFT_ENV ||
|
|
50
|
+
this.isPat = isPatToken(token);
|
|
51
|
+
this.playcraftEnv = (process.env.PLAYCRAFT_ENV ||
|
|
52
|
+
localConfig.env ||
|
|
53
|
+
'').trim();
|
|
56
54
|
}
|
|
57
55
|
/** 根据 token 类型构造鉴权 headers */
|
|
58
56
|
authHeaders() {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
try {
|
|
63
|
-
token = JSON.parse(readFileSync(this.credentialFile, 'utf8')).token || token;
|
|
64
|
-
}
|
|
65
|
-
catch { /* Keep the last credential if a local file is temporarily unavailable. */ }
|
|
66
|
-
}
|
|
67
|
-
const headers = isPatToken(token)
|
|
68
|
-
? { Authorization: `Bearer ${token}` }
|
|
69
|
-
: { 'X-Sandbox-Token': token };
|
|
57
|
+
const headers = this.isPat
|
|
58
|
+
? { Authorization: `Bearer ${this.token}` }
|
|
59
|
+
: { 'X-Sandbox-Token': this.token };
|
|
70
60
|
if (this.playcraftEnv) {
|
|
71
61
|
headers['playcraft-env'] = this.playcraftEnv;
|
|
72
62
|
}
|
|
73
63
|
return headers;
|
|
74
64
|
}
|
|
75
|
-
/**
|
|
65
|
+
/** Absolute pathname under /api/agent/tools (path may omit leading slash). */
|
|
76
66
|
toolsRequestUrl(path) {
|
|
77
67
|
const p = path.startsWith('/') ? path : `/${path}`;
|
|
78
|
-
return
|
|
68
|
+
return new URL(`/api/agent/tools${p}`, this.apiUrl);
|
|
79
69
|
}
|
|
80
|
-
async post(path, body
|
|
81
|
-
const url = this.toolsRequestUrl(path);
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
70
|
+
async post(path, body) {
|
|
71
|
+
const url = this.toolsRequestUrl(path).href;
|
|
72
|
+
const res = await fetch(url, {
|
|
73
|
+
method: 'POST',
|
|
74
|
+
headers: {
|
|
75
|
+
'Content-Type': 'application/json',
|
|
76
|
+
...this.authHeaders(),
|
|
77
|
+
},
|
|
78
|
+
body: JSON.stringify(body),
|
|
88
79
|
});
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
try {
|
|
93
|
-
try {
|
|
94
|
-
await options?.onPrepared?.({ requestId: operation.requestId, file: operation.file });
|
|
95
|
-
}
|
|
96
|
-
catch {
|
|
97
|
-
operation.reject();
|
|
98
|
-
throw new ToolRequestError('Tool request preparation failed; no operation was sent');
|
|
99
|
-
}
|
|
100
|
-
const capabilityResponse = await fetch(this.toolsRequestUrl(AGENT_TOOL_OPERATION_CAPABILITIES_PATH), {
|
|
101
|
-
headers: this.authHeaders(),
|
|
102
|
-
redirect: 'error',
|
|
103
|
-
signal: options?.signal
|
|
104
|
-
? AbortSignal.any([options.signal, AbortSignal.timeout(30_000)])
|
|
105
|
-
: AbortSignal.timeout(30_000),
|
|
106
|
-
});
|
|
107
|
-
if (!capabilityResponse.ok) {
|
|
108
|
-
if (capabilityResponse.status === 403) {
|
|
109
|
-
const pending = pendingAccountActivationError(403, parseErrorPayload(await capabilityResponse.clone().text().catch(() => '')));
|
|
110
|
-
if (pending) {
|
|
111
|
-
if (operation.createdNew && !operation.settledOnly)
|
|
112
|
-
operation.reject();
|
|
113
|
-
throw pending;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
await capabilityResponse.body?.cancel();
|
|
117
|
-
throw new ToolRequestError(`Business tool protocol unavailable (${capabilityResponse.status}); no operation was sent`);
|
|
118
|
-
}
|
|
119
|
-
const capabilities = (await capabilityResponse.json());
|
|
120
|
-
if (capabilities.protocol !== AGENT_TOOL_OPERATION_PROTOCOL ||
|
|
121
|
-
capabilities.settledOnly !== true)
|
|
122
|
-
throw new ToolRequestError('Business tool protocol is incompatible; no operation was sent');
|
|
123
|
-
const res = await fetch(url, {
|
|
124
|
-
method: 'POST',
|
|
125
|
-
redirect: 'error',
|
|
126
|
-
signal: options?.signal
|
|
127
|
-
? AbortSignal.any([options.signal, AbortSignal.timeout(30 * 60_000)])
|
|
128
|
-
: AbortSignal.timeout(30 * 60_000),
|
|
129
|
-
headers: {
|
|
130
|
-
'Content-Type': 'application/json',
|
|
131
|
-
...this.authHeaders(),
|
|
132
|
-
[AGENT_TOOL_OPERATION_HEADERS.protocol]: AGENT_TOOL_OPERATION_PROTOCOL,
|
|
133
|
-
[AGENT_TOOL_OPERATION_HEADERS.requestId]: operation.requestId,
|
|
134
|
-
...(operation.settledOnly ? { [AGENT_TOOL_OPERATION_HEADERS.settledOnly]: 'true' } : {}),
|
|
135
|
-
},
|
|
136
|
-
body: serializedBody,
|
|
137
|
-
});
|
|
138
|
-
if (res.headers.get(AGENT_TOOL_OPERATION_HEADERS.protocol) !== AGENT_TOOL_OPERATION_PROTOCOL ||
|
|
139
|
-
res.headers.get(AGENT_TOOL_OPERATION_HEADERS.requestId) !== operation.requestId) {
|
|
140
|
-
if (res.status === 403) {
|
|
141
|
-
const pending = pendingAccountActivationError(403, parseErrorPayload(await res.clone().text().catch(() => '')));
|
|
142
|
-
if (pending) {
|
|
143
|
-
if (operation.createdNew && !operation.settledOnly)
|
|
144
|
-
operation.reject();
|
|
145
|
-
throw pending;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
await res.body?.cancel();
|
|
149
|
-
// Possibly an instance that ignores identities: a rerun may only read the receipt.
|
|
150
|
-
operation.requireReceipt();
|
|
151
|
-
throw new Error('Business did not acknowledge a durable receipt; outcome remains unconfirmed');
|
|
152
|
-
}
|
|
153
|
-
if (!res.ok) {
|
|
154
|
-
const text = await res.text().catch(() => res.statusText);
|
|
155
|
-
const pending = pendingAccountActivationError(res.status, parseErrorPayload(text));
|
|
156
|
-
if (pending)
|
|
157
|
-
throw pending;
|
|
158
|
-
const code = errorCode(text);
|
|
159
|
-
if (res.status === 409 && code === 'business_operation_in_progress')
|
|
160
|
-
throw new ToolRequestError(`API 409: ${text}\nTool request ${operation.requestId} is still running. Rerun the ` +
|
|
161
|
-
'same command later to get its result.');
|
|
162
|
-
if (res.status === 409 && code === 'business_operation_requires_reconciliation')
|
|
163
|
-
throw new ToolRequestError(recoverId !== undefined
|
|
164
|
-
? // A receipt query never runs the request, even for a tool that can be safely redone.
|
|
165
|
-
`API 409: ${text}\nTool request ${operation.requestId} has no settled result yet. ` +
|
|
166
|
-
'Rerun the same command without PLAYCRAFT_TOOL_REQUEST_ID: a tool that can be ' +
|
|
167
|
-
'safely redone continues this request; any other tool then needs reconciliation.'
|
|
168
|
-
: `API 409: ${text}\nTool request ${operation.requestId} needs reconciliation: its ` +
|
|
169
|
-
'outcome is unknown, and rerunning the same command will not run it again. Only ' +
|
|
170
|
-
'after confirming it had no effect, rerun with PLAYCRAFT_TOOL_NEW_REQUEST=1 to ' +
|
|
171
|
-
'start a new operation.');
|
|
172
|
-
if (res.status >= 400 && res.status < 500) {
|
|
173
|
-
// The request itself was refused and not carried out: a rerun is a new operation.
|
|
174
|
-
operation.reject();
|
|
175
|
-
throw new ToolRequestError(`API ${res.status}: ${text}`);
|
|
176
|
-
}
|
|
177
|
-
throw new Error(`API ${res.status}: ${text}`);
|
|
178
|
-
}
|
|
179
|
-
const result = (await res.json());
|
|
180
|
-
operation.complete();
|
|
181
|
-
return result;
|
|
182
|
-
}
|
|
183
|
-
catch (error) {
|
|
184
|
-
if (error instanceof ToolRequestError || error instanceof AccountActivationError)
|
|
185
|
-
throw error;
|
|
186
|
-
throw new Error(`${error instanceof Error ? error.message : String(error)}\n${operation.settledOnly
|
|
187
|
-
? `Tool request ${operation.requestId}; record: ${operation.file}. Its settled result is not available yet.`
|
|
188
|
-
: unknownOutcome}`);
|
|
189
|
-
}
|
|
190
|
-
finally {
|
|
191
|
-
operation.release();
|
|
80
|
+
if (!res.ok) {
|
|
81
|
+
const text = await res.text().catch(() => res.statusText);
|
|
82
|
+
throw new Error(`API ${res.status}: ${text}`);
|
|
192
83
|
}
|
|
84
|
+
return res.json();
|
|
193
85
|
}
|
|
194
|
-
async get(path, params
|
|
86
|
+
async get(path, params) {
|
|
195
87
|
const url = this.toolsRequestUrl(path);
|
|
196
88
|
if (params) {
|
|
197
89
|
for (const [k, v] of Object.entries(params)) {
|
|
@@ -201,62 +93,27 @@ export class AgentApiClient {
|
|
|
201
93
|
}
|
|
202
94
|
const res = await fetch(url, {
|
|
203
95
|
headers: this.authHeaders(),
|
|
204
|
-
redirect: 'error',
|
|
205
|
-
signal: options?.signal ?? AbortSignal.timeout(30_000),
|
|
206
96
|
});
|
|
207
97
|
if (!res.ok) {
|
|
208
98
|
const text = await res.text().catch(() => res.statusText);
|
|
209
|
-
const pending = pendingAccountActivationError(res.status, parseErrorPayload(text));
|
|
210
|
-
if (pending)
|
|
211
|
-
throw pending;
|
|
212
99
|
throw new Error(`API ${res.status}: ${text}`);
|
|
213
100
|
}
|
|
214
101
|
return res.json();
|
|
215
102
|
}
|
|
216
|
-
/** Stream only to the authenticated, same-service video upload endpoint. */
|
|
217
|
-
async putVideoMedia(path, body, headers, signal) {
|
|
218
|
-
if (!/^\/video-media\/[a-f0-9-]{36}\/content\?/.test(path))
|
|
219
|
-
throw new Error('invalid_video_upload_target');
|
|
220
|
-
const url = this.toolsRequestUrl(path);
|
|
221
|
-
const keys = [...url.searchParams.keys()].sort();
|
|
222
|
-
if (keys.join(',') !== 'expires,signature,workspaceId')
|
|
223
|
-
throw new Error('invalid_video_upload_target');
|
|
224
|
-
const allowed = new Set(['content-type', 'content-md5', 'content-length']);
|
|
225
|
-
if (Object.keys(headers).some(key => !allowed.has(key.toLowerCase())))
|
|
226
|
-
throw new Error('invalid_video_upload_headers');
|
|
227
|
-
const response = await fetch(url, {
|
|
228
|
-
method: 'PUT', redirect: 'error', signal,
|
|
229
|
-
headers: { ...headers, ...this.authHeaders() },
|
|
230
|
-
body: body,
|
|
231
|
-
duplex: 'half',
|
|
232
|
-
});
|
|
233
|
-
if (!response.ok) {
|
|
234
|
-
await response.body?.cancel();
|
|
235
|
-
throw new Error(`video_upload_failed:${response.status}`);
|
|
236
|
-
}
|
|
237
|
-
await response.body?.cancel();
|
|
238
|
-
}
|
|
239
103
|
/**
|
|
240
104
|
* 按顺序搜索本地 .playcraft.json 文件(沙箱内或项目目录)。
|
|
241
105
|
* 与全局 login 配置(~/.playcraft/config.json)不同,前者专用于沙箱 token。
|
|
242
106
|
*/
|
|
243
107
|
static loadLocalConfig() {
|
|
244
|
-
const ancestors = [];
|
|
245
|
-
for (let directory = process.cwd();; directory = dirname(directory)) {
|
|
246
|
-
ancestors.push(join(directory, '.playcraft.json'));
|
|
247
|
-
if (dirname(directory) === directory)
|
|
248
|
-
break;
|
|
249
|
-
}
|
|
250
108
|
const searchPaths = [
|
|
251
|
-
process.
|
|
252
|
-
...ancestors,
|
|
109
|
+
join(process.cwd(), '.playcraft.json'),
|
|
253
110
|
'/project/.playcraft.json',
|
|
254
111
|
join(homedir(), '.playcraft.json'),
|
|
255
112
|
];
|
|
256
113
|
for (const p of searchPaths) {
|
|
257
114
|
if (existsSync(p)) {
|
|
258
115
|
try {
|
|
259
|
-
return
|
|
116
|
+
return JSON.parse(readFileSync(p, 'utf-8'));
|
|
260
117
|
}
|
|
261
118
|
catch {
|
|
262
119
|
continue;
|
|
@@ -266,15 +123,3 @@ export class AgentApiClient {
|
|
|
266
123
|
return { apiUrl: '', token: '' };
|
|
267
124
|
}
|
|
268
125
|
}
|
|
269
|
-
/** A failure whose meaning is settled; no recovery hint applies. */
|
|
270
|
-
class ToolRequestError extends Error {
|
|
271
|
-
}
|
|
272
|
-
function errorCode(text) {
|
|
273
|
-
try {
|
|
274
|
-
const message = JSON.parse(text).message;
|
|
275
|
-
return typeof message === 'string' ? message : undefined;
|
|
276
|
-
}
|
|
277
|
-
catch {
|
|
278
|
-
return undefined;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { existsSync, readFileSync, realpathSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import JSON5 from 'json5';
|
|
4
|
+
import sharp from 'sharp';
|
|
5
|
+
import { extractAssetFields, getByPath, resolveAiImageTargetConstraints, resolveImageBackgroundRequirement, THEME_SCHEMA_PATH, themeDataPath, } from '@playcraft/common/prefab';
|
|
6
|
+
/** Resolve only real files in this project, including legacy /project aliases. */
|
|
7
|
+
function projectFile(root, input) {
|
|
8
|
+
const mapped = input.startsWith('/project/') ? input.slice('/project/'.length) : input;
|
|
9
|
+
const file = path.resolve(root, mapped);
|
|
10
|
+
const prefix = path.resolve(root) + path.sep;
|
|
11
|
+
if (!file.startsWith(prefix))
|
|
12
|
+
throw new Error(`Image asset path is outside the project: ${input}`);
|
|
13
|
+
const real = realpathSync(file);
|
|
14
|
+
if (!real.startsWith(realpathSync(root) + path.sep))
|
|
15
|
+
throw new Error(`Image asset symlink is outside the project: ${input}`);
|
|
16
|
+
return file;
|
|
17
|
+
}
|
|
18
|
+
/** Read the same per-field constraints used by the asset image dialog. */
|
|
19
|
+
export async function readImageAssetContext(assetPath, projectDir = process.cwd(), options = {}) {
|
|
20
|
+
const root = path.resolve(projectDir);
|
|
21
|
+
const target = projectFile(root, assetPath);
|
|
22
|
+
const relativeTarget = path.relative(root, target).replace(/\\/g, '/');
|
|
23
|
+
const themeMatch = relativeTarget.match(/^src\/theme\/([^/]+)\/assets\//);
|
|
24
|
+
let field;
|
|
25
|
+
const schemaFile = path.join(root, THEME_SCHEMA_PATH);
|
|
26
|
+
if (themeMatch && existsSync(schemaFile)) {
|
|
27
|
+
const schema = JSON5.parse(readFileSync(projectFile(root, THEME_SCHEMA_PATH), 'utf8'));
|
|
28
|
+
const dataPath = themeDataPath(themeMatch[1]);
|
|
29
|
+
const data = existsSync(path.join(root, dataPath))
|
|
30
|
+
? JSON5.parse(readFileSync(projectFile(root, dataPath), 'utf8')) : {};
|
|
31
|
+
const themeRoot = path.dirname(path.join(root, dataPath));
|
|
32
|
+
const matches = extractAssetFields(schema, data).filter(candidate => {
|
|
33
|
+
let configured = getByPath(data, candidate.path);
|
|
34
|
+
if (configured === undefined && ['gameplay', 'gamePlay'].includes(candidate.path[0])) {
|
|
35
|
+
configured = getByPath(data, [candidate.path[0] === 'gameplay' ? 'gamePlay' : 'gameplay', ...candidate.path.slice(1)]);
|
|
36
|
+
}
|
|
37
|
+
const value = typeof configured === 'string' ? configured : candidate.schema.default;
|
|
38
|
+
if (typeof value !== 'string' || /^https?:\/\//i.test(value))
|
|
39
|
+
return false;
|
|
40
|
+
return path.resolve(themeRoot, value) === target;
|
|
41
|
+
});
|
|
42
|
+
if (matches.length > 1)
|
|
43
|
+
throw new Error('Multiple image fields use this asset; specify an unambiguous target asset.');
|
|
44
|
+
field = matches[0];
|
|
45
|
+
if (!field)
|
|
46
|
+
throw new Error(`No image schema field matches ${relativeTarget}; check theme.data.json5 before generating.`);
|
|
47
|
+
}
|
|
48
|
+
const xp = field?.schema.xplatform;
|
|
49
|
+
const ext = xp?.ext;
|
|
50
|
+
// Schema references follow the dialog's root/theme conventions; explicit tool paths do not change.
|
|
51
|
+
const schemaReferences = Array.isArray(ext?.reference_image)
|
|
52
|
+
? ext.reference_image.filter(ref => typeof ref === 'string' && ref.trim()).map(ref => {
|
|
53
|
+
const raw = ref.trim().replace(/\\/g, '/');
|
|
54
|
+
const normalized = raw.replace(/^\.\/+/, '').replace(/^\/+/, '').replace(/\/{2,}/g, '/');
|
|
55
|
+
if (/^\/?(?:assets|src|public)\//.test(raw) || normalized.startsWith('src/'))
|
|
56
|
+
return normalized;
|
|
57
|
+
if (!themeMatch || path.isAbsolute(raw) || /^https?:\/\//i.test(raw))
|
|
58
|
+
return raw;
|
|
59
|
+
return path.posix.join('src/theme', themeMatch[1], normalized);
|
|
60
|
+
}) : [];
|
|
61
|
+
const referenceImagePaths = options.referenceImagePaths?.length ? options.referenceImagePaths
|
|
62
|
+
: options.useTargetReference === false ? [] : schemaReferences.length ? schemaReferences : [relativeTarget];
|
|
63
|
+
if (referenceImagePaths.length > 8)
|
|
64
|
+
throw new Error('At most 8 reference images are allowed.');
|
|
65
|
+
for (const ref of referenceImagePaths) {
|
|
66
|
+
if (/^https?:\/\//i.test(ref))
|
|
67
|
+
throw new Error('Download the schema reference into the project before generating.');
|
|
68
|
+
await sharp(projectFile(root, ref)).metadata();
|
|
69
|
+
}
|
|
70
|
+
const targetMeta = await sharp(target).metadata();
|
|
71
|
+
const hasSchemaBackground = typeof ext?.remove_background === 'boolean';
|
|
72
|
+
const targetStats = !hasSchemaBackground && targetMeta.hasAlpha ? await sharp(target).stats() : undefined;
|
|
73
|
+
const targetHasTransparency = !!targetStats && targetStats.channels.at(-1).min < 250;
|
|
74
|
+
const removeBackground = resolveImageBackgroundRequirement({
|
|
75
|
+
prompt: options.prompt ?? '',
|
|
76
|
+
schemaRemoveBackground: hasSchemaBackground ? ext.remove_background : undefined,
|
|
77
|
+
removeBackground: options.removeBackground,
|
|
78
|
+
fallbackRemoveBackground: targetHasTransparency,
|
|
79
|
+
});
|
|
80
|
+
const delivery = resolveAiImageTargetConstraints({
|
|
81
|
+
schemaResolution: ext?.resolution,
|
|
82
|
+
schemaMimeType: xp?.mime_type,
|
|
83
|
+
schemaFitMode: xp?.fit_mode ?? ext?.fit_mode,
|
|
84
|
+
schemaRemoveBackground: removeBackground,
|
|
85
|
+
schemaPaddingColor: ext?.padding_color,
|
|
86
|
+
assetPath: relativeTarget,
|
|
87
|
+
referenceWidth: targetMeta.width,
|
|
88
|
+
referenceHeight: targetMeta.height,
|
|
89
|
+
referenceFormat: targetMeta.format,
|
|
90
|
+
});
|
|
91
|
+
if (!['png', 'webp', 'jpeg'].includes(delivery.format))
|
|
92
|
+
throw new Error('Unsupported image delivery format; use a dedicated animation or vector workflow.');
|
|
93
|
+
return {
|
|
94
|
+
targetAssetPath: relativeTarget,
|
|
95
|
+
fieldPath: field?.path,
|
|
96
|
+
referenceImagePaths,
|
|
97
|
+
width: delivery.width, height: delivery.height,
|
|
98
|
+
aspectRatio: typeof ext?.ratio === 'string' ? ext.ratio : `${delivery.width}:${delivery.height}`,
|
|
99
|
+
outputFormat: (removeBackground && delivery.format === 'jpeg' && !delivery.fromSchemaMimeType
|
|
100
|
+
? 'png' : delivery.format),
|
|
101
|
+
fitMode: delivery.fitMode, removeBackground: delivery.removeBackground, paddingColor: delivery.paddingColor,
|
|
102
|
+
removeBackgroundFromSchema: hasSchemaBackground,
|
|
103
|
+
imageModelRef: typeof ext?.imageModelRef === 'string' ? ext.imageModelRef : undefined,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { loadGlobalConfig } from '../config.js';
|
|
3
3
|
import { DEFAULT_PLAYCRAFT_CLOUD_BASE } from '../commands/login.js';
|
|
4
|
-
import { pendingAccountActivationError } from '../auth/account-activation.js';
|
|
5
4
|
export class PlayCraftApiError extends Error {
|
|
6
5
|
code;
|
|
7
6
|
status;
|
|
@@ -96,20 +95,19 @@ export class PlayCraftHttpClient {
|
|
|
96
95
|
}
|
|
97
96
|
if (!response.ok) {
|
|
98
97
|
const error = payload?.error;
|
|
99
|
-
const
|
|
100
|
-
const
|
|
101
|
-
const message = pending?.message ?? (typeof error?.message === 'string'
|
|
98
|
+
const code = typeof error?.code === 'string' ? error.code : statusCode(response.status);
|
|
99
|
+
const message = typeof error?.message === 'string'
|
|
102
100
|
? error.message
|
|
103
101
|
: typeof payload?.message === 'string'
|
|
104
102
|
? payload.message
|
|
105
103
|
: typeof payload === 'string'
|
|
106
104
|
? payload
|
|
107
|
-
: response.statusText || 'PlayCraft request failed'
|
|
105
|
+
: response.statusText || 'PlayCraft request failed';
|
|
108
106
|
throw new PlayCraftApiError({
|
|
109
107
|
code,
|
|
110
108
|
message,
|
|
111
109
|
status: response.status,
|
|
112
|
-
details:
|
|
110
|
+
details: error?.details ?? payload,
|
|
113
111
|
retryable: response.status >= 500,
|
|
114
112
|
});
|
|
115
113
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@playcraft/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.29",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
"dist",
|
|
15
15
|
"templates",
|
|
16
16
|
"project-template",
|
|
17
|
-
"project-template-v2",
|
|
18
17
|
"engine-packs",
|
|
19
18
|
"project-templates",
|
|
20
19
|
"REMIX.md",
|
|
@@ -22,9 +21,9 @@
|
|
|
22
21
|
],
|
|
23
22
|
"scripts": {
|
|
24
23
|
"dev": "tsc -w",
|
|
25
|
-
"build": "
|
|
24
|
+
"build": "tsc",
|
|
26
25
|
"start": "node dist/index.js",
|
|
27
|
-
"test": "
|
|
26
|
+
"test": "vitest run",
|
|
28
27
|
"test:agent": "node scripts/run-agent-tests.mjs --list",
|
|
29
28
|
"test:agent:designer": "node scripts/run-agent-tests.mjs game-designer",
|
|
30
29
|
"test:agent:developer": "node scripts/run-agent-tests.mjs developer",
|
|
@@ -36,10 +35,6 @@
|
|
|
36
35
|
"test:agent:gate": "node scripts/run-agent-tests.mjs gate",
|
|
37
36
|
"test:agent:vlm": "node scripts/run-agent-tests.mjs vlm",
|
|
38
37
|
"test:agent:stop": "node scripts/run-agent-tests.mjs stop",
|
|
39
|
-
"generate:platform-skills": "node scripts/generate-platform-skills.mjs",
|
|
40
|
-
"verify:platform-skills": "node scripts/generate-platform-skills.mjs --check",
|
|
41
|
-
"generate:video-skills": "node scripts/generate-video-skills.mjs",
|
|
42
|
-
"verify:video-skills": "node scripts/generate-video-skills.mjs --check && node --test scripts/generate-video-skills.test.mjs",
|
|
43
38
|
"verify:agent-stop": "node scripts/verify-agent-stop.mjs",
|
|
44
39
|
"verify-sprite-overlay": "node scripts/verify-sprite-overlay.mjs",
|
|
45
40
|
"link": "node scripts/bump-local.js && pnpm build && npm link",
|
|
@@ -50,9 +45,8 @@
|
|
|
50
45
|
"@gltf-transform/core": "^4.3.0",
|
|
51
46
|
"@gltf-transform/extensions": "^4.3.0",
|
|
52
47
|
"@gltf-transform/functions": "^4.3.0",
|
|
53
|
-
"@playcraft/build": "^0.1.
|
|
54
|
-
"@playcraft/common": "^0.1.
|
|
55
|
-
"better-sqlite3-pinned": "npm:better-sqlite3@13.0.3",
|
|
48
|
+
"@playcraft/build": "^0.1.28",
|
|
49
|
+
"@playcraft/common": "^0.1.28",
|
|
56
50
|
"chokidar": "^4.0.3",
|
|
57
51
|
"commander": "^13.1.0",
|
|
58
52
|
"cors": "^2.8.6",
|
|
@@ -68,10 +62,8 @@
|
|
|
68
62
|
"json5": "^2.2.3",
|
|
69
63
|
"latest-version": "^7.0.0",
|
|
70
64
|
"music-metadata": "^11.12.3",
|
|
71
|
-
"node-pty": "1.0.0",
|
|
72
65
|
"ora": "^8.2.0",
|
|
73
66
|
"picocolors": "^1.1.1",
|
|
74
|
-
"playwright-core": "1.52.0",
|
|
75
67
|
"sharp": "^0.34.5",
|
|
76
68
|
"update-notifier": "^7.3.1",
|
|
77
69
|
"ws": "^8.19.0",
|
|
@@ -87,7 +79,6 @@
|
|
|
87
79
|
"@types/sharp": "^0.32.0",
|
|
88
80
|
"@types/update-notifier": "^6.0.8",
|
|
89
81
|
"@types/ws": "^8.18.1",
|
|
90
|
-
"esbuild": "^0.28.1",
|
|
91
82
|
"typescript": "^5.9.3",
|
|
92
83
|
"vitest": "^3.2.4"
|
|
93
84
|
}
|