summer-engine 2.8.1 → 3.0.0
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/.claude-plugin/marketplace.json +27 -7
- package/.claude-plugin/plugin.json +99 -83
- package/.codex-plugin/plugin.json +112 -82
- package/.cursor-plugin/plugin.json +119 -83
- package/.factory-plugin/plugin.json +100 -3
- package/.mcp.json +6 -1
- package/.opencode/INSTALL.md +7 -4
- package/.opencode/plugins/summer.js +31 -18
- package/AGENTS.md +107 -34
- package/CHANGELOG.md +134 -41
- package/CLAUDE.md +4 -2
- package/GEMINI.md +7 -53
- package/NOTICE +31 -0
- package/README.md +159 -391
- package/assets/api-docs.json.gz +0 -0
- package/assets/autopilot/README.md +20 -6
- package/assets/autopilot/autopilot.gd +80 -26
- package/assets/autopilot/run.sh +132 -7
- package/assets/navigation/web-routes.json +719 -0
- package/commands/gameskill.md +10 -108
- package/commands/summer.md +72 -4
- package/dist/bin/summer.js +6 -87
- package/dist/cli/banner.d.ts +1 -0
- package/dist/cli/banner.js +33 -0
- package/dist/{commands → cli/commands}/config.js +1 -1
- package/dist/cli/commands/create.d.ts +30 -0
- package/dist/cli/commands/create.js +212 -0
- package/dist/{commands → cli/commands}/debug.js +2 -2
- package/dist/cli/commands/doctor.d.ts +2 -0
- package/dist/cli/commands/doctor.js +18 -0
- package/dist/cli/commands/events.d.ts +57 -0
- package/dist/cli/commands/events.js +158 -0
- package/dist/cli/commands/install.d.ts +50 -0
- package/dist/cli/commands/install.js +447 -0
- package/dist/cli/commands/list.js +72 -0
- package/dist/{commands → cli/commands}/login.js +33 -17
- package/dist/{commands → cli/commands}/logout.d.ts +1 -0
- package/dist/cli/commands/logout.js +19 -0
- package/dist/{commands → cli/commands}/memory.d.ts +1 -8
- package/dist/{commands → cli/commands}/memory.js +20 -11
- package/dist/cli/commands/open.d.ts +45 -0
- package/dist/cli/commands/open.js +216 -0
- package/dist/{commands → cli/commands}/plan.js +2 -2
- package/dist/{commands → cli/commands}/publish.js +1 -1
- package/dist/{commands → cli/commands}/releases.js +1 -1
- package/dist/cli/commands/run.d.ts +19 -0
- package/dist/cli/commands/run.js +255 -0
- package/dist/{commands → cli/commands}/setup.js +43 -89
- package/dist/{commands → cli/commands}/skills.js +85 -222
- package/dist/{commands → cli/commands}/status.d.ts +1 -0
- package/dist/cli/commands/status.js +62 -0
- package/dist/cli/commands/tool.d.ts +11 -0
- package/dist/cli/commands/tool.js +121 -0
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.js +89 -0
- package/dist/cli/root-action.d.ts +7 -0
- package/dist/cli/root-action.js +15 -0
- package/dist/{lib → core}/api-client.d.ts +106 -15
- package/dist/{lib → core}/api-client.js +267 -75
- package/dist/{lib → core}/async-op-lifecycle.d.ts +3 -4
- package/dist/{lib → core}/async-op-lifecycle.js +3 -4
- package/dist/{lib → core}/auth.d.ts +14 -6
- package/dist/{lib → core}/auth.js +56 -40
- package/dist/core/capabilities/agent-playbook.d.ts +20 -0
- package/dist/core/capabilities/agent-playbook.js +218 -0
- package/dist/core/capabilities/api-docs.d.ts +36 -0
- package/dist/core/capabilities/api-docs.js +118 -0
- package/dist/core/capabilities/asset-import.d.ts +49 -0
- package/dist/core/capabilities/asset-import.js +134 -0
- package/dist/core/capabilities/camera-view.d.ts +98 -0
- package/dist/core/capabilities/camera-view.js +222 -0
- package/dist/core/capabilities/capture.d.ts +63 -0
- package/dist/core/capabilities/capture.js +67 -0
- package/dist/core/capabilities/console-read.d.ts +17 -0
- package/dist/core/capabilities/console-read.js +21 -0
- package/dist/{lib → core/capabilities}/creator.d.ts +1 -29
- package/dist/{lib → core/capabilities}/creator.js +14 -33
- package/dist/{lib → core/capabilities}/debug-report.d.ts +1 -1
- package/dist/{lib → core/capabilities}/debug-report.js +12 -31
- package/dist/{commands → core/capabilities}/doctor.d.ts +7 -2
- package/dist/{commands → core/capabilities}/doctor.js +47 -73
- package/dist/core/capabilities/engine-fallbacks.d.ts +26 -0
- package/dist/core/capabilities/engine-fallbacks.js +36 -0
- package/dist/core/capabilities/engine-ops.d.ts +33 -0
- package/dist/core/capabilities/engine-ops.js +145 -0
- package/dist/core/capabilities/engine-receipt.d.ts +53 -0
- package/dist/core/capabilities/engine-receipt.js +134 -0
- package/dist/core/capabilities/events.d.ts +200 -0
- package/dist/core/capabilities/events.js +383 -0
- package/dist/core/capabilities/fabricate-mesh.d.ts +111 -0
- package/dist/core/capabilities/fabricate-mesh.js +165 -0
- package/dist/core/capabilities/frame-quality.d.ts +71 -0
- package/dist/core/capabilities/frame-quality.js +449 -0
- package/dist/core/capabilities/game-task-plan.d.ts +66 -0
- package/dist/{lib → core/capabilities}/game-task-plan.js +59 -8
- package/dist/core/capabilities/hdri-import.d.ts +90 -0
- package/dist/core/capabilities/hdri-import.js +250 -0
- package/dist/core/capabilities/image-generation.d.ts +24 -0
- package/dist/core/capabilities/image-generation.js +22 -0
- package/dist/core/capabilities/navigation/open.d.ts +156 -0
- package/dist/core/capabilities/navigation/open.js +567 -0
- package/dist/core/capabilities/navigation/render-product-map.d.ts +1 -0
- package/dist/core/capabilities/navigation/render-product-map.js +84 -0
- package/dist/core/capabilities/navigation/targets.d.ts +87 -0
- package/dist/core/capabilities/navigation/targets.js +250 -0
- package/dist/core/capabilities/play-determinism.d.ts +35 -0
- package/dist/core/capabilities/play-determinism.js +86 -0
- package/dist/core/capabilities/project-context.d.ts +114 -0
- package/dist/core/capabilities/project-context.js +249 -0
- package/dist/core/capabilities/runtime-control.d.ts +540 -0
- package/dist/core/capabilities/runtime-control.js +1011 -0
- package/dist/core/capabilities/scene-kind.d.ts +19 -0
- package/dist/core/capabilities/scene-kind.js +137 -0
- package/dist/core/capabilities/scene-script.d.ts +38 -0
- package/dist/core/capabilities/scene-script.js +45 -0
- package/dist/core/capabilities/tool-dispatch.d.ts +42 -0
- package/dist/core/capabilities/tool-dispatch.js +1490 -0
- package/dist/core/capabilities/ui-control.d.ts +179 -0
- package/dist/core/capabilities/ui-control.js +423 -0
- package/dist/core/capabilities/variant-types.d.ts +22 -0
- package/dist/core/capabilities/variant-types.js +101 -0
- package/dist/core/capability-skew.d.ts +205 -0
- package/dist/core/capability-skew.js +386 -0
- package/dist/{lib → core}/config.d.ts +11 -1
- package/dist/{lib → core}/config.js +13 -2
- package/dist/core/embeddings.d.ts +78 -0
- package/dist/core/embeddings.js +166 -0
- package/dist/core/engine-install.d.ts +105 -0
- package/dist/core/engine-install.js +190 -0
- package/dist/core/engine.d.ts +94 -0
- package/dist/{lib → core}/engine.js +74 -28
- package/dist/core/feedback/client.d.ts +88 -0
- package/dist/core/feedback/client.js +182 -0
- package/dist/{lib → core}/format.d.ts +0 -1
- package/dist/{lib → core}/format.js +1 -1
- package/dist/core/headless/connection.d.ts +86 -0
- package/dist/core/headless/connection.js +97 -0
- package/dist/core/headless/editor-connection.d.ts +26 -0
- package/dist/core/headless/editor-connection.js +81 -0
- package/dist/core/headless/mcp-routing.d.ts +38 -0
- package/dist/core/headless/mcp-routing.js +83 -0
- package/dist/core/headless/registry.d.ts +91 -0
- package/dist/core/headless/registry.js +226 -0
- package/dist/core/headless/resolve.d.ts +46 -0
- package/dist/core/headless/resolve.js +75 -0
- package/dist/core/headless/spawn.d.ts +46 -0
- package/dist/core/headless/spawn.js +205 -0
- package/dist/core/headless/worker-connection.d.ts +96 -0
- package/dist/core/headless/worker-connection.js +353 -0
- package/dist/core/headless/worker-engine-client.d.ts +58 -0
- package/dist/core/headless/worker-engine-client.js +246 -0
- package/dist/core/launch-posture.d.ts +170 -0
- package/dist/core/launch-posture.js +317 -0
- package/dist/core/library-read.d.ts +73 -0
- package/dist/core/library-read.js +279 -0
- package/dist/core/library-search.d.ts +143 -0
- package/dist/core/library-search.js +301 -0
- package/dist/{lib → core}/log-filters.js +4 -2
- package/dist/{lib → core}/mcp-log.js +2 -17
- package/dist/core/package-root.d.ts +9 -0
- package/dist/core/package-root.js +11 -0
- package/dist/core/redact.d.ts +20 -0
- package/dist/core/redact.js +64 -0
- package/dist/core/registry-search.d.ts +167 -0
- package/dist/core/registry-search.js +358 -0
- package/dist/core/skills-registry.d.ts +47 -0
- package/dist/core/skills-registry.js +83 -0
- package/dist/{lib → core}/store.js +11 -7
- package/dist/{lib → core}/summer-compatibility.js +3 -3
- package/dist/{lib → core}/telemetry.js +5 -2
- package/dist/core/templates.d.ts +98 -0
- package/dist/core/templates.js +241 -0
- package/dist/core/tool-errors.d.ts +30 -0
- package/dist/core/tool-errors.js +40 -0
- package/dist/core/trajectory.d.ts +80 -0
- package/dist/core/trajectory.js +307 -0
- package/dist/core/util/http.d.ts +13 -0
- package/dist/core/util/http.js +28 -0
- package/dist/core/util/json.d.ts +12 -0
- package/dist/core/util/json.js +21 -0
- package/dist/core/util/process.d.ts +3 -0
- package/dist/core/util/process.js +13 -0
- package/dist/core/util/sleep.d.ts +1 -0
- package/dist/core/util/sleep.js +3 -0
- package/dist/core/version.d.ts +3 -0
- package/dist/core/version.js +5 -0
- package/dist/{lib → installer}/agent-config.d.ts +20 -1
- package/dist/{lib → installer}/agent-config.js +148 -23
- package/dist/installer/legacy-skills.d.ts +26 -0
- package/dist/installer/legacy-skills.js +53 -0
- package/dist/installer/setup.d.ts +76 -0
- package/dist/installer/setup.js +146 -0
- package/dist/installer/skill-locations.d.ts +45 -0
- package/dist/installer/skill-locations.js +170 -0
- package/dist/installer/version-check.d.ts +174 -0
- package/dist/{lib → installer}/version-check.js +173 -42
- package/dist/{lib/mcp-boot-notice.d.ts → mcp/boot-notice.d.ts} +1 -1
- package/dist/{commands/mcp.js → mcp/command.js} +18 -6
- package/dist/mcp/server.d.ts +23 -3
- package/dist/mcp/server.js +122 -28
- package/dist/mcp/tools/asset-tools.js +62 -142
- package/dist/mcp/tools/creator-tools.js +5 -23
- package/dist/mcp/tools/debug-tools.js +61 -18
- package/dist/mcp/tools/event-tools.d.ts +14 -0
- package/dist/mcp/tools/event-tools.js +41 -0
- package/dist/mcp/tools/fabricate-tools.d.ts +2 -0
- package/dist/mcp/tools/fabricate-tools.js +28 -0
- package/dist/mcp/tools/feedback-tools.d.ts +77 -0
- package/dist/mcp/tools/feedback-tools.js +88 -0
- package/dist/mcp/tools/file-tools.js +6 -53
- package/dist/mcp/tools/generate-tools.js +37 -63
- package/dist/mcp/tools/library-tools.d.ts +11 -0
- package/dist/mcp/tools/library-tools.js +42 -0
- package/dist/mcp/tools/navigation-tools.d.ts +7 -0
- package/dist/mcp/tools/navigation-tools.js +37 -0
- package/dist/mcp/tools/perception-tools.d.ts +20 -0
- package/dist/mcp/tools/perception-tools.js +146 -0
- package/dist/mcp/tools/project-tools.d.ts +14 -0
- package/dist/mcp/tools/project-tools.js +72 -281
- package/dist/mcp/tools/runtime-tools.d.ts +2 -0
- package/dist/mcp/tools/runtime-tools.js +92 -0
- package/dist/mcp/tools/scene-tools.d.ts +3 -0
- package/dist/mcp/tools/scene-tools.js +68 -119
- package/dist/mcp/tools/script-tools.d.ts +3 -0
- package/dist/mcp/tools/script-tools.js +118 -0
- package/dist/mcp/tools/spatial-tools.d.ts +2 -0
- package/dist/mcp/tools/spatial-tools.js +485 -0
- package/dist/mcp/tools/text-json.d.ts +8 -0
- package/dist/mcp/tools/text-json.js +12 -0
- package/dist/mcp/tools/{cloud-tools.d.ts → ui-tools.d.ts} +1 -1
- package/dist/mcp/tools/ui-tools.js +82 -0
- package/dist/mcp/tools/visual-tools.d.ts +2 -7
- package/dist/mcp/tools/visual-tools.js +383 -101
- package/dist/mcp/tools/with-engine.d.ts +9 -15
- package/dist/mcp/tools/with-engine.js +60 -96
- package/dist/project-memory/project-manifest.d.ts +36 -0
- package/dist/project-memory/project-manifest.js +50 -0
- package/dist/project-memory/project-memory.d.ts +57 -0
- package/dist/{lib → project-memory}/project-memory.js +46 -0
- package/gemini-extension.json +103 -2
- package/hooks/hooks-cursor.json +2 -2
- package/hooks/hooks.json +2 -1
- package/hooks/pre-commit-doctor.sh +45 -39
- package/hooks/run-hook.cmd +30 -23
- package/hooks/run-hook.sh +20 -0
- package/hooks/session-start.sh +18 -7
- package/integrations/README.md +70 -0
- package/integrations/claude/README.md +19 -0
- package/integrations/claude/manifest-target.json +16 -0
- package/integrations/cline/README.md +13 -0
- package/integrations/cline/manifest-target.json +3 -0
- package/integrations/codex/README.md +15 -0
- package/integrations/codex/manifest-target.json +5 -0
- package/integrations/cursor/README.md +16 -0
- package/integrations/cursor/manifest-target.json +5 -0
- package/integrations/factory/README.md +26 -0
- package/integrations/factory/manifest-target.json +5 -0
- package/integrations/gemini/README.md +26 -0
- package/integrations/gemini/manifest-target.json +5 -0
- package/integrations/github-copilot/README.md +12 -0
- package/integrations/github-copilot/manifest-target.json +3 -0
- package/integrations/kilo-code/README.md +16 -0
- package/integrations/kilo-code/manifest-target.json +3 -0
- package/integrations/lm-studio/README.md +12 -0
- package/integrations/lm-studio/manifest-target.json +3 -0
- package/integrations/opencode/README.md +15 -0
- package/integrations/opencode/manifest-target.json +3 -0
- package/integrations/roo-code/README.md +13 -0
- package/integrations/roo-code/manifest-target.json +3 -0
- package/integrations/vscode-copilot/README.md +12 -0
- package/integrations/vscode-copilot/manifest-target.json +3 -0
- package/integrations/windsurf/README.md +13 -0
- package/integrations/windsurf/manifest-target.json +3 -0
- package/library/references/collaborative-protocol/resource.yaml +24 -0
- package/library/references/gd-style/resource.yaml +24 -0
- package/{references → library/references/godot-version}/godot-version.md +6 -6
- package/library/references/godot-version/resource.yaml +22 -0
- package/library/references/headless-routing/headless-routing.md +46 -0
- package/library/references/headless-routing/resource.yaml +24 -0
- package/library/references/mcp-fresh-chat-playbook/mcp-fresh-chat-playbook.md +49 -0
- package/library/references/mcp-fresh-chat-playbook/resource.yaml +23 -0
- package/library/references/mcp-tools-reference/mcp-tools-reference.md +271 -0
- package/library/references/mcp-tools-reference/resource.yaml +17 -0
- package/library/references/product-map/product-map.md +103 -0
- package/library/references/product-map/resource.yaml +33 -0
- package/{references → library/references/public-surface-language}/public-surface-language.md +5 -7
- package/library/references/public-surface-language/resource.yaml +17 -0
- package/library/references/summer-folder/resource.yaml +20 -0
- package/{references → library/references/summer-folder}/summer-folder.md +22 -21
- package/{skills/rendering-and-lighting → library/skills}/3d-lighting/SKILL.md +15 -11
- package/library/skills/3d-lighting/resource.yaml +27 -0
- package/{skills/audio → library/skills}/adaptive-music/SKILL.md +1 -1
- package/library/skills/adaptive-music/resource.yaml +28 -0
- package/library/skills/agent-playtesting/SKILL.md +148 -0
- package/library/skills/agent-playtesting/resource.yaml +52 -0
- package/library/skills/ambient-bed/resource.yaml +24 -0
- package/{skills/video → library/skills}/animated-loop/SKILL.md +1 -1
- package/library/skills/animated-loop/resource.yaml +27 -0
- package/{skills/animation → library/skills}/animation-tree/SKILL.md +29 -14
- package/library/skills/animation-tree/resource.yaml +33 -0
- package/{skills/rendering-and-lighting → library/skills}/art-direction/SKILL.md +3 -3
- package/library/skills/art-direction/resource.yaml +29 -0
- package/{skills/asset-pipeline → library/skills}/asset-strategy/SKILL.md +44 -44
- package/library/skills/asset-strategy/resource.yaml +63 -0
- package/{skills/audio → library/skills}/audio-direction/SKILL.md +7 -7
- package/library/skills/audio-direction/resource.yaml +32 -0
- package/library/skills/auto-fire-targeting/resource.yaml +22 -0
- package/{skills/scene-and-project → library/skills}/brainstorm-game/SKILL.md +8 -8
- package/library/skills/brainstorm-game/resource.yaml +30 -0
- package/{skills/workflow → library/skills}/brainstorming/SKILL.md +2 -22
- package/library/skills/brainstorming/resource.yaml +23 -0
- package/{skills/workflow → library/skills}/brainstorming/spec-document-reviewer-prompt.md +1 -1
- package/{skills/scene-and-project → library/skills}/browse-templates/SKILL.md +18 -18
- package/library/skills/browse-templates/resource.yaml +23 -0
- package/library/skills/celeste-momentum-platforming/SKILL.md +366 -0
- package/library/skills/celeste-momentum-platforming/resource.yaml +33 -0
- package/library/skills/character-animation-wiring/SKILL.md +249 -0
- package/library/skills/character-animation-wiring/resource.yaml +39 -0
- package/{skills/3d-assets → library/skills}/character-model/SKILL.md +25 -25
- package/library/skills/character-model/resource.yaml +36 -0
- package/{skills/2d-assets → library/skills}/character-portrait/SKILL.md +14 -14
- package/library/skills/character-portrait/resource.yaml +30 -0
- package/{skills/video → library/skills}/cinematic-cutscene/SKILL.md +2 -2
- package/library/skills/cinematic-cutscene/resource.yaml +29 -0
- package/{skills/2d-assets → library/skills}/concept-art/SKILL.md +15 -15
- package/library/skills/concept-art/resource.yaml +34 -0
- package/{skills/2d-assets → library/skills}/create-asset-sheet/SKILL.md +8 -8
- package/library/skills/create-asset-sheet/resource.yaml +33 -0
- package/{skills/debugging → library/skills}/debug/SKILL.md +3 -3
- package/library/skills/debug/resource.yaml +31 -0
- package/{skills/workflow → library/skills}/debugging-game-feel/SKILL.md +11 -11
- package/library/skills/debugging-game-feel/resource.yaml +25 -0
- package/{skills/level-design → library/skills}/design-level/SKILL.md +6 -6
- package/library/skills/design-level/resource.yaml +31 -0
- package/{skills/gameplay-mechanics → library/skills}/design-mechanic/SKILL.md +3 -3
- package/library/skills/design-mechanic/resource.yaml +31 -0
- package/{skills/ai-and-npcs → library/skills}/design-npc/SKILL.md +7 -3
- package/library/skills/design-npc/resource.yaml +29 -0
- package/{skills/workflow → library/skills}/diagnosing-perf-regressions/SKILL.md +10 -10
- package/library/skills/diagnosing-perf-regressions/resource.yaml +25 -0
- package/{skills/workflow → library/skills}/dispatching-parallel-agents/SKILL.md +8 -8
- package/library/skills/dispatching-parallel-agents/resource.yaml +23 -0
- package/library/skills/driving-the-editor-ui/SKILL.md +85 -0
- package/library/skills/driving-the-editor-ui/resource.yaml +46 -0
- package/{skills/3d-assets → library/skills}/environment-kit/SKILL.md +11 -11
- package/library/skills/environment-kit/resource.yaml +29 -0
- package/{skills/deployment → library/skills}/export-and-ship/SKILL.md +5 -5
- package/library/skills/export-and-ship/resource.yaml +32 -0
- package/library/skills/fabricating-assets/SKILL.md +195 -0
- package/library/skills/fabricating-assets/resource.yaml +52 -0
- package/{skills/animation → library/skills}/facial-and-lipsync/SKILL.md +23 -11
- package/library/skills/facial-and-lipsync/resource.yaml +36 -0
- package/{skills/character-controllers → library/skills}/fps-controller/SKILL.md +8 -4
- package/library/skills/fps-controller/resource.yaml +29 -0
- package/{skills/visual-effects → library/skills}/game-feel/SKILL.md +7 -7
- package/library/skills/game-feel/resource.yaml +27 -0
- package/library/skills/gameskill/SKILL.md +64 -0
- package/library/skills/gameskill/resource.yaml +22 -0
- package/library/skills/gdscript-patterns/resource.yaml +23 -0
- package/{skills/animation → library/skills}/generate-motion/SKILL.md +16 -16
- package/library/skills/generate-motion/resource.yaml +34 -0
- package/library/skills/godogen-visual-proof-game-generation/SKILL.md +223 -0
- package/library/skills/godogen-visual-proof-game-generation/resource.yaml +33 -0
- package/{skills/workflow → library/skills}/headless-scripting/SKILL.md +14 -7
- package/library/skills/headless-scripting/resource.yaml +26 -0
- package/{skills/multiplayer-and-networking → library/skills}/host-authoritative-state/SKILL.md +1 -1
- package/library/skills/host-authoritative-state/resource.yaml +28 -0
- package/{skills/2d-assets → library/skills}/instantiate-asset-pack/SKILL.md +10 -12
- package/library/skills/instantiate-asset-pack/resource.yaml +29 -0
- package/{skills/workflow → library/skills}/investigating-bugs/SKILL.md +4 -4
- package/{skills/workflow → library/skills}/investigating-bugs/condition-based-waiting.md +8 -8
- package/library/skills/investigating-bugs/resource.yaml +24 -0
- package/{skills/workflow → library/skills}/investigating-bugs/root-cause-tracing.md +1 -7
- package/library/skills/lumera-single-image-scene-reconstruction/SKILL.md +164 -0
- package/library/skills/lumera-single-image-scene-reconstruction/resource.yaml +35 -0
- package/{skills/scene-and-project → library/skills}/make-game/SKILL.md +23 -23
- package/library/skills/make-game/resource.yaml +35 -0
- package/library/skills/music-track/resource.yaml +28 -0
- package/library/skills/navigate-summer/SKILL.md +61 -0
- package/library/skills/navigate-summer/resource.yaml +35 -0
- package/{skills/scene-and-project → library/skills}/new-project/SKILL.md +10 -10
- package/library/skills/new-project/resource.yaml +28 -0
- package/{skills/3d-assets → library/skills}/organic-model/SKILL.md +16 -16
- package/library/skills/organic-model/resource.yaml +32 -0
- package/{skills/multiplayer-and-networking → library/skills}/peer-to-peer-multiplayer/SKILL.md +2 -2
- package/library/skills/peer-to-peer-multiplayer/resource.yaml +28 -0
- package/{skills/2d-assets → library/skills}/pixel-art/SKILL.md +13 -13
- package/library/skills/pixel-art/resource.yaml +31 -0
- package/library/skills/play/resource.yaml +26 -0
- package/{skills/workflow → library/skills}/playtesting-a-feature/SKILL.md +41 -22
- package/library/skills/playtesting-a-feature/resource.yaml +31 -0
- package/{skills/animation → library/skills}/procedural-animation/SKILL.md +25 -10
- package/library/skills/procedural-animation/resource.yaml +33 -0
- package/{skills/3d-assets → library/skills}/prop-model/SKILL.md +13 -13
- package/library/skills/prop-model/resource.yaml +33 -0
- package/library/skills/psx-retro-rendering/SKILL.md +416 -0
- package/library/skills/psx-retro-rendering/resource.yaml +36 -0
- package/library/skills/realtime-wet-surfaces/SKILL.md +189 -0
- package/library/skills/realtime-wet-surfaces/resource.yaml +31 -0
- package/{skills/deployment → library/skills}/remote-deploy/SKILL.md +3 -3
- package/library/skills/remote-deploy/resource.yaml +23 -0
- package/{skills/animation → library/skills}/retarget/SKILL.md +15 -14
- package/library/skills/retarget/resource.yaml +33 -0
- package/library/skills/running-in-the-cloud/SKILL.md +103 -0
- package/library/skills/running-in-the-cloud/resource.yaml +33 -0
- package/{skills/scene-and-project → library/skills}/scene-composition/SKILL.md +9 -1
- package/library/skills/scene-composition/resource.yaml +27 -0
- package/library/skills/scene-hierarchy-design/SKILL.md +102 -0
- package/library/skills/scene-hierarchy-design/resource.yaml +31 -0
- package/library/skills/scene-scripting/SKILL.md +764 -0
- package/library/skills/scene-scripting/resource.yaml +58 -0
- package/{skills/level-design → library/skills}/scene-to-level/SKILL.md +16 -17
- package/library/skills/scene-to-level/resource.yaml +33 -0
- package/{skills/multiplayer-and-networking → library/skills}/setup-multiplayer/SKILL.md +1 -1
- package/library/skills/setup-multiplayer/resource.yaml +28 -0
- package/library/skills/skill-create/SKILL.md +138 -0
- package/library/skills/skill-create/resource.yaml +25 -0
- package/{skills/workflow → library/skills}/skill-improve/SKILL.md +2 -2
- package/library/skills/skill-improve/resource.yaml +25 -0
- package/{skills/workflow → library/skills}/skill-test/SKILL.md +4 -4
- package/library/skills/skill-test/resource.yaml +26 -0
- package/library/skills/skintokens-auto-rigging/SKILL.md +200 -0
- package/library/skills/skintokens-auto-rigging/resource.yaml +38 -0
- package/{skills/2d-assets → library/skills}/skybox-panorama/SKILL.md +8 -8
- package/library/skills/skybox-panorama/resource.yaml +28 -0
- package/{skills/audio → library/skills}/sound-effect/SKILL.md +2 -2
- package/library/skills/sound-effect/resource.yaml +27 -0
- package/library/skills/spatial-placement/SKILL.md +74 -0
- package/library/skills/spatial-placement/resource.yaml +42 -0
- package/library/skills/spatial-placement/tests/spec.md +65 -0
- package/{skills/2d-assets → library/skills}/sprite-sheet/SKILL.md +12 -12
- package/library/skills/sprite-sheet/resource.yaml +32 -0
- package/{skills/2d-assets → library/skills}/tileable-texture/SKILL.md +9 -9
- package/library/skills/tileable-texture/resource.yaml +31 -0
- package/{skills/video → library/skills}/trailer-shot/SKILL.md +1 -1
- package/library/skills/trailer-shot/resource.yaml +27 -0
- package/{skills/performance → library/skills}/tune-performance/SKILL.md +6 -6
- package/library/skills/tune-performance/resource.yaml +31 -0
- package/{skills/ui-and-ux → library/skills}/ui-basics/SKILL.md +1 -1
- package/library/skills/ui-basics/resource.yaml +25 -0
- package/{skills/2d-assets → library/skills}/ui-graphics/SKILL.md +11 -11
- package/library/skills/ui-graphics/resource.yaml +29 -0
- package/{skills/2d-assets → library/skills}/use-widget-asset/SKILL.md +4 -4
- package/library/skills/use-widget-asset/resource.yaml +29 -0
- package/{skills/workflow → library/skills}/using-summer/SKILL.md +12 -9
- package/library/skills/using-summer/resource.yaml +41 -0
- package/{skills/3d-assets → library/skills}/vehicle-model/SKILL.md +18 -18
- package/library/skills/vehicle-model/resource.yaml +34 -0
- package/{skills/workflow → library/skills}/verification-before-completion/SKILL.md +10 -10
- package/library/skills/verification-before-completion/resource.yaml +23 -0
- package/library/skills/verifying-scenes/SKILL.md +98 -0
- package/library/skills/verifying-scenes/resource.yaml +42 -0
- package/{skills/visual-effects/recipes/dissolve → library/skills/vfx-dissolve}/SKILL.md +31 -11
- package/library/skills/vfx-dissolve/resource.yaml +33 -0
- package/{skills/visual-effects/recipes/fire → library/skills/vfx-fire}/SKILL.md +43 -12
- package/library/skills/vfx-fire/_building-blocks/noise-3d-fbm.gdshaderinc +45 -0
- package/library/skills/vfx-fire/resource.yaml +35 -0
- package/{skills/visual-effects/recipes/hit-spark → library/skills/vfx-hit-spark}/SKILL.md +16 -10
- package/library/skills/vfx-hit-spark/_building-blocks/additive-billboard-particles.md +37 -0
- package/library/skills/vfx-hit-spark/resource.yaml +34 -0
- package/{skills/visual-effects/recipes/lightning → library/skills/vfx-lightning}/SKILL.md +24 -11
- package/library/skills/vfx-lightning/_building-blocks/additive-billboard-particles.md +37 -0
- package/library/skills/vfx-lightning/resource.yaml +33 -0
- package/{skills/visual-effects/recipes/magic-glow → library/skills/vfx-magic-glow}/SKILL.md +31 -11
- package/library/skills/vfx-magic-glow/_building-blocks/additive-billboard-particles.md +37 -0
- package/library/skills/vfx-magic-glow/resource.yaml +34 -0
- package/{skills/visual-effects/recipes/muzzle-flash → library/skills/vfx-muzzle-flash}/SKILL.md +29 -9
- package/library/skills/vfx-muzzle-flash/_building-blocks/additive-billboard-particles.md +37 -0
- package/library/skills/vfx-muzzle-flash/_building-blocks/trauma-shake-snippet.md +53 -0
- package/library/skills/vfx-muzzle-flash/resource.yaml +35 -0
- package/{skills/visual-effects/recipes/smoke → library/skills/vfx-smoke}/SKILL.md +35 -9
- package/library/skills/vfx-smoke/_building-blocks/noise-3d-fbm.gdshaderinc +45 -0
- package/library/skills/vfx-smoke/resource.yaml +32 -0
- package/{skills/visual-effects/recipes/water-ripple → library/skills/vfx-water-ripple}/SKILL.md +31 -9
- package/library/skills/vfx-water-ripple/_building-blocks/additive-billboard-particles.md +37 -0
- package/library/skills/vfx-water-ripple/resource.yaml +31 -0
- package/library/skills/voice-line/resource.yaml +27 -0
- package/library/skills/world-building-3d/SKILL.md +105 -0
- package/library/skills/world-building-3d/references/spatial-tools.md +50 -0
- package/library/skills/world-building-3d/resource.yaml +44 -0
- package/library/skills/world-building-3d/tests/spec.md +48 -0
- package/{skills/workflow → library/skills}/writing-plans/SKILL.md +19 -14
- package/library/skills/writing-plans/resource.yaml +23 -0
- package/{skills/workflow → library/skills}/writing-skills/SKILL.md +38 -44
- package/library/skills/writing-skills/resource.yaml +29 -0
- package/{skills/workflow → library/skills}/writing-skills/testing-skills-with-subagents.md +13 -14
- package/library/templates/2d-brario-platformer/resource.yaml +21 -0
- package/library/templates/2d-dungeon-roguelike/resource.yaml +23 -0
- package/library/templates/2d-grid-puzzle/resource.yaml +21 -0
- package/library/templates/2d-plants-and-zombies-tower-defense/resource.yaml +21 -0
- package/library/templates/2d-platformer/resource.yaml +24 -0
- package/library/templates/2d-rpg/resource.yaml +21 -0
- package/library/templates/2d-vampire-survivor-roguelike/resource.yaml +21 -0
- package/library/templates/3d-basic/resource.yaml +16 -0
- package/library/templates/3d-city-kit/resource.yaml +24 -0
- package/library/templates/3d-fps-old-school/resource.yaml +21 -0
- package/library/templates/3d-fps-simple-animated-npc/resource.yaml +21 -0
- package/library/templates/3d-lan-multiplayer-starter/resource.yaml +22 -0
- package/library/templates/3d-open-world-explore-tps/resource.yaml +21 -0
- package/library/templates/3d-procedural-road-world/resource.yaml +21 -0
- package/library/templates/3d-racing-game/resource.yaml +21 -0
- package/library/templates/3d-royale-clash-type/resource.yaml +21 -0
- package/library/templates/3d-third-person-controller/resource.yaml +21 -0
- package/library/templates/3d-voxel-sandbox/resource.yaml +24 -0
- package/library/templates/README.md +94 -0
- package/library/templates/empty/resource.yaml +16 -0
- package/library/tools/add-node/resource.yaml +60 -0
- package/library/tools/align-distribute-3d/resource.yaml +87 -0
- package/library/tools/api-docs/resource.yaml +57 -0
- package/library/tools/batch/resource.yaml +52 -0
- package/library/tools/camera-bookmark/resource.yaml +73 -0
- package/library/tools/check-job/resource.yaml +45 -0
- package/library/tools/clear-console/resource.yaml +40 -0
- package/library/tools/connect-signal/resource.yaml +63 -0
- package/library/tools/create-debug-report/resource.yaml +67 -0
- package/library/tools/create-scene/resource.yaml +59 -0
- package/library/tools/creator-config/resource.yaml +63 -0
- package/library/tools/creator-publish/resource.yaml +73 -0
- package/library/tools/creator-releases/resource.yaml +53 -0
- package/library/tools/fabricate-3d/resource.yaml +108 -0
- package/library/tools/game-control/resource.yaml +84 -0
- package/library/tools/game-input/resource.yaml +159 -0
- package/library/tools/game-probe/resource.yaml +90 -0
- package/library/tools/generate-3d/resource.yaml +112 -0
- package/library/tools/generate-audio/resource.yaml +80 -0
- package/library/tools/generate-image/resource.yaml +62 -0
- package/library/tools/generate-motion/resource.yaml +66 -0
- package/library/tools/generate-video/resource.yaml +66 -0
- package/library/tools/get-agent-playbook/resource.yaml +40 -0
- package/library/tools/get-asset/resource.yaml +42 -0
- package/library/tools/get-asset-download-url/resource.yaml +52 -0
- package/library/tools/get-console/resource.yaml +69 -0
- package/library/tools/get-debugger-errors/resource.yaml +56 -0
- package/library/tools/get-debugger-warnings/resource.yaml +52 -0
- package/library/tools/get-diagnostics/resource.yaml +42 -0
- package/library/tools/get-project-context/resource.yaml +45 -0
- package/library/tools/get-runtime-tree/resource.yaml +62 -0
- package/library/tools/get-scene-tree/resource.yaml +52 -0
- package/library/tools/get-script-errors/resource.yaml +45 -0
- package/library/tools/get-studio-workflow/resource.yaml +43 -0
- package/library/tools/import-asset/resource.yaml +73 -0
- package/library/tools/import-asset-by-id/resource.yaml +56 -0
- package/library/tools/import-from-url/resource.yaml +51 -0
- package/library/tools/import-from-url-batch/resource.yaml +60 -0
- package/library/tools/import-hdri/resource.yaml +69 -0
- package/library/tools/input-map-bind/resource.yaml +52 -0
- package/library/tools/inspect-node/resource.yaml +46 -0
- package/library/tools/inspect-resource/resource.yaml +45 -0
- package/library/tools/inspect-runtime-node/resource.yaml +54 -0
- package/library/tools/instantiate-scene/resource.yaml +62 -0
- package/library/tools/is-running/resource.yaml +40 -0
- package/library/tools/library-feedback/resource.yaml +89 -0
- package/library/tools/list-my-assets/resource.yaml +56 -0
- package/library/tools/navigation-probe/resource.yaml +85 -0
- package/library/tools/open/resource.yaml +80 -0
- package/library/tools/open-main-scene/resource.yaml +40 -0
- package/library/tools/open-scene/resource.yaml +46 -0
- package/library/tools/play/resource.yaml +91 -0
- package/library/tools/project-setting/resource.yaml +53 -0
- package/library/tools/read-file/resource.yaml +47 -0
- package/library/tools/read-library/resource.yaml +67 -0
- package/library/tools/recent-events/resource.yaml +71 -0
- package/library/tools/remove-node/resource.yaml +51 -0
- package/library/tools/replace-node/resource.yaml +57 -0
- package/library/tools/replace-text/resource.yaml +61 -0
- package/library/tools/run-editor-script/resource.yaml +61 -0
- package/library/tools/run-script/resource.yaml +73 -0
- package/library/tools/runtime-animate/resource.yaml +140 -0
- package/library/tools/runtime-call/resource.yaml +74 -0
- package/library/tools/runtime-set/resource.yaml +80 -0
- package/library/tools/runtime-spawn/resource.yaml +95 -0
- package/library/tools/save-scene/resource.yaml +50 -0
- package/library/tools/screenshot/resource.yaml +112 -0
- package/library/tools/search-assets/resource.yaml +67 -0
- package/library/tools/search-library/resource.yaml +81 -0
- package/library/tools/select-node/resource.yaml +48 -0
- package/library/tools/set-prop/resource.yaml +64 -0
- package/library/tools/set-resource-property/resource.yaml +66 -0
- package/library/tools/slice-asset-sheet/resource.yaml +47 -0
- package/library/tools/snap-to-surface/resource.yaml +90 -0
- package/library/tools/snapshot-diff/resource.yaml +58 -0
- package/library/tools/starcast/resource.yaml +120 -0
- package/library/tools/start-game-task/resource.yaml +91 -0
- package/library/tools/stop/resource.yaml +51 -0
- package/library/tools/test-placement/resource.yaml +109 -0
- package/library/tools/ui-actions/resource.yaml +77 -0
- package/library/tools/ui-activate/resource.yaml +88 -0
- package/library/tools/ui-screenshot/resource.yaml +63 -0
- package/library/tools/ui-tree/resource.yaml +69 -0
- package/library/tools/wait-for-event/resource.yaml +84 -0
- package/library/tools/world-snapshot/resource.yaml +60 -0
- package/library/tools/write-file/resource.yaml +54 -0
- package/package.json +22 -16
- package/registry/generated/aliases.json +207 -0
- package/registry/generated/counts.json +12 -0
- package/registry/generated/gemini-extension.json +122 -0
- package/registry/generated/index.json +7709 -0
- package/registry/generated/marketplace.claude.json +44 -0
- package/registry/generated/mcp.json +13 -0
- package/registry/generated/plugin.claude.json +135 -0
- package/registry/generated/plugin.codex.json +144 -0
- package/registry/generated/plugin.cursor.json +134 -0
- package/registry/generated/plugin.factory.json +117 -0
- package/registry/generated/skills-registry.json +851 -0
- package/registry/generated/templates-registry.json +455 -0
- package/registry/schemas/allowed-hosts.json +19 -0
- package/registry/schemas/collection.schema.json +68 -0
- package/registry/schemas/domains.json +96 -0
- package/registry/schemas/example.schema.json +11 -0
- package/registry/schemas/reference.schema.json +10 -0
- package/registry/schemas/resource.schema.json +154 -0
- package/registry/schemas/skill.schema.json +14 -0
- package/registry/schemas/template.schema.json +46 -0
- package/registry/schemas/tool.schema.json +61 -0
- package/_persona/summer/SKILL.md +0 -113
- package/dist/bin/postinstall.d.ts +0 -2
- package/dist/bin/postinstall.js +0 -3
- package/dist/commands/cloud.d.ts +0 -2
- package/dist/commands/cloud.js +0 -80
- package/dist/commands/create.d.ts +0 -3
- package/dist/commands/create.js +0 -171
- package/dist/commands/install.d.ts +0 -19
- package/dist/commands/install.js +0 -194
- package/dist/commands/list.js +0 -67
- package/dist/commands/logout.js +0 -13
- package/dist/commands/logs.d.ts +0 -2
- package/dist/commands/logs.js +0 -19
- package/dist/commands/open.d.ts +0 -2
- package/dist/commands/open.js +0 -32
- package/dist/commands/orchestrator.d.ts +0 -8
- package/dist/commands/orchestrator.js +0 -143
- package/dist/commands/run.d.ts +0 -2
- package/dist/commands/run.js +0 -167
- package/dist/commands/status.js +0 -46
- package/dist/lib/banner.d.ts +0 -4
- package/dist/lib/banner.js +0 -122
- package/dist/lib/cloud/api.d.ts +0 -79
- package/dist/lib/cloud/api.js +0 -107
- package/dist/lib/cloud/apply.d.ts +0 -32
- package/dist/lib/cloud/apply.js +0 -294
- package/dist/lib/cloud/checkpoint.d.ts +0 -26
- package/dist/lib/cloud/checkpoint.js +0 -142
- package/dist/lib/cloud/conflicts.d.ts +0 -55
- package/dist/lib/cloud/conflicts.js +0 -131
- package/dist/lib/cloud/containment.d.ts +0 -8
- package/dist/lib/cloud/containment.js +0 -52
- package/dist/lib/cloud/diff.d.ts +0 -39
- package/dist/lib/cloud/diff.js +0 -138
- package/dist/lib/cloud/engine-bridge.d.ts +0 -34
- package/dist/lib/cloud/engine-bridge.js +0 -139
- package/dist/lib/cloud/hash-cache.d.ts +0 -23
- package/dist/lib/cloud/hash-cache.js +0 -44
- package/dist/lib/cloud/hash.d.ts +0 -10
- package/dist/lib/cloud/hash.js +0 -111
- package/dist/lib/cloud/http.d.ts +0 -17
- package/dist/lib/cloud/http.js +0 -47
- package/dist/lib/cloud/lock-path.d.ts +0 -1
- package/dist/lib/cloud/lock-path.js +0 -5
- package/dist/lib/cloud/lock.d.ts +0 -14
- package/dist/lib/cloud/lock.js +0 -143
- package/dist/lib/cloud/manifest.d.ts +0 -6
- package/dist/lib/cloud/manifest.js +0 -41
- package/dist/lib/cloud/paths.d.ts +0 -20
- package/dist/lib/cloud/paths.js +0 -90
- package/dist/lib/cloud/project-godot-merge.d.ts +0 -32
- package/dist/lib/cloud/project-godot-merge.js +0 -185
- package/dist/lib/cloud/rules.d.ts +0 -39
- package/dist/lib/cloud/rules.js +0 -159
- package/dist/lib/cloud/sync.d.ts +0 -21
- package/dist/lib/cloud/sync.js +0 -518
- package/dist/lib/cloud/transfer.d.ts +0 -23
- package/dist/lib/cloud/transfer.js +0 -184
- package/dist/lib/cloud/types.d.ts +0 -62
- package/dist/lib/cloud/types.js +0 -1
- package/dist/lib/cloud/validate-path.d.ts +0 -23
- package/dist/lib/cloud/validate-path.js +0 -103
- package/dist/lib/engine.d.ts +0 -51
- package/dist/lib/game-task-plan.d.ts +0 -42
- package/dist/lib/project-memory.d.ts +0 -33
- package/dist/lib/public-surface-paths.d.ts +0 -13
- package/dist/lib/public-surface-paths.js +0 -42
- package/dist/lib/remote-templates.d.ts +0 -25
- package/dist/lib/remote-templates.js +0 -86
- package/dist/lib/skills-registry.d.ts +0 -572
- package/dist/lib/skills-registry.js +0 -1061
- package/dist/lib/version-check.d.ts +0 -106
- package/dist/mcp/tools/cloud-tools.js +0 -42
- package/references/mcp-tools-reference.md +0 -199
- package/references/template-registry.md +0 -73
- package/skills/README.md +0 -103
- package/skills/scene-and-project/summer-cloud/SKILL.md +0 -92
- package/skills/workflow/brainstorming/scripts/frame-template.html +0 -214
- package/skills/workflow/brainstorming/scripts/helper.js +0 -88
- package/skills/workflow/brainstorming/scripts/server.cjs +0 -354
- package/skills/workflow/brainstorming/scripts/start-server.sh +0 -148
- package/skills/workflow/brainstorming/scripts/stop-server.sh +0 -56
- package/skills/workflow/brainstorming/visual-companion.md +0 -287
- package/skills/workflow/gameskill/SKILL.md +0 -120
- package/skills/workflow/investigating-bugs/CREATION-LOG.md +0 -119
- package/skills/workflow/investigating-bugs/condition-based-waiting-example.ts +0 -158
- package/skills/workflow/investigating-bugs/find-polluter.sh +0 -63
- package/skills/workflow/investigating-bugs/test-academic.md +0 -14
- package/skills/workflow/investigating-bugs/test-pressure-1.md +0 -58
- package/skills/workflow/investigating-bugs/test-pressure-2.md +0 -68
- package/skills/workflow/investigating-bugs/test-pressure-3.md +0 -69
- package/skills/workflow/mcpupdate/SKILL.md +0 -134
- package/skills/workflow/skill-create/SKILL.md +0 -153
- package/skills/workflow/writing-skills/anthropic-best-practices.md +0 -1150
- package/skills/workflow/writing-skills/examples/CLAUDE_MD_TESTING.md +0 -189
- package/skills/workflow/writing-skills/graphviz-conventions.dot +0 -172
- package/skills/workflow/writing-skills/persuasion-principles.md +0 -187
- package/skills/workflow/writing-skills/render-graphs.js +0 -168
- /package/dist/{commands → cli/commands}/config.d.ts +0 -0
- /package/dist/{commands → cli/commands}/debug.d.ts +0 -0
- /package/dist/{commands → cli/commands}/list.d.ts +0 -0
- /package/dist/{commands → cli/commands}/login.d.ts +0 -0
- /package/dist/{commands → cli/commands}/plan.d.ts +0 -0
- /package/dist/{commands → cli/commands}/publish.d.ts +0 -0
- /package/dist/{commands → cli/commands}/releases.d.ts +0 -0
- /package/dist/{commands → cli/commands}/setup.d.ts +0 -0
- /package/dist/{commands → cli/commands}/skills.d.ts +0 -0
- /package/dist/{lib → core}/log-filters.d.ts +0 -0
- /package/dist/{lib → core}/mcp-log.d.ts +0 -0
- /package/dist/{lib → core}/store.d.ts +0 -0
- /package/dist/{lib → core}/summer-compatibility.d.ts +0 -0
- /package/dist/{lib → core}/telemetry.d.ts +0 -0
- /package/dist/{lib/mcp-boot-notice.js → mcp/boot-notice.js} +0 -0
- /package/dist/{commands/mcp.d.ts → mcp/command.d.ts} +0 -0
- /package/{references → library/references/collaborative-protocol}/collaborative-protocol.md +0 -0
- /package/{references → library/references/gd-style}/gd-style.md +0 -0
- /package/{skills/audio → library/skills}/ambient-bed/SKILL.md +0 -0
- /package/{skills/gameplay-mechanics → library/skills}/auto-fire-targeting/SKILL.md +0 -0
- /package/{skills/scripting-patterns → library/skills}/gdscript-patterns/SKILL.md +0 -0
- /package/{skills/scripting-patterns → library/skills}/gdscript-patterns/reference.md +0 -0
- /package/{skills/workflow → library/skills}/investigating-bugs/defense-in-depth.md +0 -0
- /package/{skills/audio → library/skills}/music-track/SKILL.md +0 -0
- /package/{skills/scene-and-project → library/skills}/play/SKILL.md +0 -0
- /package/{skills/visual-effects → library/skills/vfx-dissolve}/_building-blocks/noise-3d-fbm.gdshaderinc +0 -0
- /package/{skills/visual-effects → library/skills/vfx-fire}/_building-blocks/additive-billboard-particles.md +0 -0
- /package/{skills/visual-effects → library/skills/vfx-lightning}/_building-blocks/trauma-shake-snippet.md +0 -0
- /package/{skills/audio → library/skills}/voice-line/SKILL.md +0 -0
- /package/{skills/workflow → library/skills}/writing-plans/plan-document-reviewer-prompt.md +0 -0
package/dist/lib/cloud/apply.js
DELETED
|
@@ -1,294 +0,0 @@
|
|
|
1
|
-
import { chmod, copyFile, lstat, readFile, rename, rm, stat, writeFile } from "fs/promises";
|
|
2
|
-
import { basename, dirname, join } from "path";
|
|
3
|
-
import { containedProjectPath } from "./containment.js";
|
|
4
|
-
import { mergeProjectGodot } from "./project-godot-merge.js";
|
|
5
|
-
import { casefoldKey } from "./validate-path.js";
|
|
6
|
-
const RENAME_RETRIES = 7;
|
|
7
|
-
const RENAME_BACKOFF_MS = 50;
|
|
8
|
-
/**
|
|
9
|
-
* Two-phase pull, phase 2 (spec 8.7). Fixed order: renames first (case-only
|
|
10
|
-
* renames as two-step), then writes (project.godot and *.tscn last), then
|
|
11
|
-
* deletes. Every write is an atomic rename from staging; every modify or
|
|
12
|
-
* delete is preceded by exactly one full-tree checkpoint and a pre-image
|
|
13
|
-
* stat check that routes drifted files to conflicts instead of overwriting.
|
|
14
|
-
*/
|
|
15
|
-
export async function applyRemotePlan(projectRoot, plan, remote, context) {
|
|
16
|
-
const result = { appliedPaths: [], notices: [], preservedLocalHashes: new Map() };
|
|
17
|
-
const decisionByPath = new Map(plan.decisions.map((d) => [d.path, d]));
|
|
18
|
-
let writes = [...plan.pullPaths, ...plan.conflictPaths].filter((path) => remote.files[path]);
|
|
19
|
-
let deletes = [...plan.deleteLocalPaths];
|
|
20
|
-
if (!writes.length && !deletes.length)
|
|
21
|
-
return result;
|
|
22
|
-
// Checkpoint before ANY destructive apply (spec 11): a modify of an
|
|
23
|
-
// existing file or a delete.
|
|
24
|
-
let checkpointed = false;
|
|
25
|
-
const ensureCheckpoint = async () => {
|
|
26
|
-
if (checkpointed)
|
|
27
|
-
return;
|
|
28
|
-
checkpointed = true;
|
|
29
|
-
await context.onBeforeDestructive();
|
|
30
|
-
};
|
|
31
|
-
for (const path of writes) {
|
|
32
|
-
if (await pathExistsOnDisk(projectRoot, path, context)) {
|
|
33
|
-
await ensureCheckpoint();
|
|
34
|
-
break;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
if (!checkpointed && deletes.length)
|
|
38
|
-
await ensureCheckpoint();
|
|
39
|
-
// Phase: renames. A delete-local plus pull pair with the same content hash
|
|
40
|
-
// and casefold-equal keys is a case-only rename, executed as a two-step
|
|
41
|
-
// rename so case-insensitive volumes never lose the file (spec 8.7).
|
|
42
|
-
const renamed = await applyCaseOnlyRenames(projectRoot, plan, remote, context, decisionByPath, result);
|
|
43
|
-
writes = writes.filter((path) => !renamed.has(path));
|
|
44
|
-
deletes = deletes.filter((path) => !renamed.has(path));
|
|
45
|
-
// Phase: writes, with project.godot and *.tscn last so a partially
|
|
46
|
-
// hydrated project is never scanned with dangling scene dependencies.
|
|
47
|
-
const stagedUseCount = new Map();
|
|
48
|
-
for (const path of writes) {
|
|
49
|
-
const hash = remote.files[path].sha256;
|
|
50
|
-
stagedUseCount.set(hash, (stagedUseCount.get(hash) ?? 0) + 1);
|
|
51
|
-
}
|
|
52
|
-
writes.sort((a, b) => writeOrderRank(a) - writeOrderRank(b) || (a < b ? -1 : a > b ? 1 : 0));
|
|
53
|
-
for (const path of writes) {
|
|
54
|
-
const decision = decisionByPath.get(path);
|
|
55
|
-
const remoteFile = remote.files[path];
|
|
56
|
-
const isConflict = plan.conflictPaths.includes(path);
|
|
57
|
-
// Pre-image stat check (spec 8.7): a file that changed between diff and
|
|
58
|
-
// apply is routed to conflicts instead of being blindly overwritten.
|
|
59
|
-
const drifted = await driftedSinceDiff(projectRoot, path, context);
|
|
60
|
-
if (isConflict || drifted) {
|
|
61
|
-
await preserveLoser(projectRoot, path, decision, remoteFile.sha256, context, result, drifted && !isConflict);
|
|
62
|
-
}
|
|
63
|
-
if (path === "project.godot" && isConflict) {
|
|
64
|
-
const merged = await mergeProjectGodotFromContext(projectRoot, path, decision, remote, context, result);
|
|
65
|
-
if (merged) {
|
|
66
|
-
result.appliedPaths.push(path);
|
|
67
|
-
continue;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
const stagedPath = context.staged.get(remoteFile.sha256);
|
|
71
|
-
if (!stagedPath)
|
|
72
|
-
throw new Error(`Missing staged blob for ${path} (${remoteFile.sha256})`);
|
|
73
|
-
const remaining = stagedUseCount.get(remoteFile.sha256) - 1;
|
|
74
|
-
stagedUseCount.set(remoteFile.sha256, remaining);
|
|
75
|
-
await placeFromStaging(projectRoot, path, stagedPath, remaining > 0, context);
|
|
76
|
-
result.appliedPaths.push(path);
|
|
77
|
-
}
|
|
78
|
-
// Phase: deletes.
|
|
79
|
-
const survivingFold = new Map();
|
|
80
|
-
for (const key of Object.keys(remote.files))
|
|
81
|
-
survivingFold.set(casefoldKey(key), key);
|
|
82
|
-
for (const path of deletes) {
|
|
83
|
-
const decision = decisionByPath.get(path);
|
|
84
|
-
const onDisk = context.diskPathByKey.get(path) ?? join(projectRoot, path);
|
|
85
|
-
// Pre-image check: a delete target edited since the diff is row 14 now
|
|
86
|
-
// (edit beats delete); keep the local file and surface it.
|
|
87
|
-
if (await driftedSinceDiff(projectRoot, path, context)) {
|
|
88
|
-
result.notices.push(`${path}: changed during sync; kept local file (edit beats delete)`);
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
|
-
// Inode-gated casefold skip (spec 8.7): a delete whose casefolded path
|
|
92
|
-
// equals a surviving manifest key is skipped only when a samefile check
|
|
93
|
-
// proves both names map to one on-disk file.
|
|
94
|
-
const survivor = survivingFold.get(casefoldKey(path));
|
|
95
|
-
if (survivor && survivor !== path) {
|
|
96
|
-
if (await isSameFile(onDisk, join(projectRoot, survivor))) {
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
if (decision?.local?.sha256) {
|
|
101
|
-
result.preservedLocalHashes.set(decision.local.sha256, onDisk);
|
|
102
|
-
}
|
|
103
|
-
await rm(onDisk, { force: true });
|
|
104
|
-
result.appliedPaths.push(path);
|
|
105
|
-
}
|
|
106
|
-
for (const path of plan.keepLocalPaths) {
|
|
107
|
-
result.notices.push(`${path}: deleted in cloud but edited here; keeping local file (edit beats delete)`);
|
|
108
|
-
}
|
|
109
|
-
for (const path of plan.restoredRemotePaths) {
|
|
110
|
-
result.notices.push(`${path}: deleted here but edited in cloud; restored the cloud file (edit beats delete)`);
|
|
111
|
-
}
|
|
112
|
-
return result;
|
|
113
|
-
}
|
|
114
|
-
function writeOrderRank(path) {
|
|
115
|
-
if (path === "project.godot")
|
|
116
|
-
return 2;
|
|
117
|
-
if (path.endsWith(".tscn"))
|
|
118
|
-
return 1;
|
|
119
|
-
return 0;
|
|
120
|
-
}
|
|
121
|
-
async function pathExistsOnDisk(projectRoot, path, context) {
|
|
122
|
-
const onDisk = context.diskPathByKey.get(path) ?? join(projectRoot, path);
|
|
123
|
-
try {
|
|
124
|
-
await lstat(onDisk);
|
|
125
|
-
return true;
|
|
126
|
-
}
|
|
127
|
-
catch {
|
|
128
|
-
return false;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
async function driftedSinceDiff(projectRoot, path, context) {
|
|
132
|
-
const recorded = context.statByKey.get(path);
|
|
133
|
-
if (!recorded)
|
|
134
|
-
return false;
|
|
135
|
-
const onDisk = context.diskPathByKey.get(path) ?? join(projectRoot, path);
|
|
136
|
-
try {
|
|
137
|
-
const info = await lstat(onDisk, { bigint: true });
|
|
138
|
-
return Number(info.size) !== recorded.size || info.mtimeNs.toString() !== recorded.mtimeNs;
|
|
139
|
-
}
|
|
140
|
-
catch {
|
|
141
|
-
return false; // Gone since the diff; nothing to preserve.
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
async function preserveLoser(projectRoot, path, decision, remoteSha256, context, result, drifted) {
|
|
145
|
-
const onDisk = context.diskPathByKey.get(path) ?? join(projectRoot, path);
|
|
146
|
-
const localSha = decision?.local?.sha256;
|
|
147
|
-
const preserved = await context.conflicts.preserve(path, {
|
|
148
|
-
localSha256: localSha,
|
|
149
|
-
remoteSha256,
|
|
150
|
-
winner: "remote",
|
|
151
|
-
note: drifted ? "changed between diff and apply" : undefined,
|
|
152
|
-
}, onDisk);
|
|
153
|
-
if (preserved) {
|
|
154
|
-
if (localSha)
|
|
155
|
-
result.preservedLocalHashes.set(localSha, join(context.conflicts.setDir, path));
|
|
156
|
-
result.notices.push(`${path}: cloud version won; your bytes are preserved (summer cloud conflicts restore ${path})`);
|
|
157
|
-
// Sidecar bytes ride inside the conflict set for reference, never as a
|
|
158
|
-
// second conflict copy in the scanned tree (spec 8.4).
|
|
159
|
-
for (const suffix of [".import", ".uid"]) {
|
|
160
|
-
const sidecar = `${path}${suffix}`;
|
|
161
|
-
const sidecarOnDisk = context.diskPathByKey.get(sidecar) ?? join(projectRoot, sidecar);
|
|
162
|
-
await context.conflicts.preserve(sidecar, { winner: "remote", sidecar: true }, sidecarOnDisk);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
async function mergeProjectGodotFromContext(projectRoot, path, decision, remote, context, result) {
|
|
167
|
-
const baseHash = context.base?.files[path]?.sha256;
|
|
168
|
-
const baseStaged = baseHash ? context.staged.get(baseHash) : undefined;
|
|
169
|
-
const remoteStaged = context.staged.get(remote.files[path].sha256);
|
|
170
|
-
const onDisk = context.diskPathByKey.get(path) ?? join(projectRoot, path);
|
|
171
|
-
if (!remoteStaged)
|
|
172
|
-
return false;
|
|
173
|
-
let baseText = "";
|
|
174
|
-
let localText = "";
|
|
175
|
-
let remoteText = "";
|
|
176
|
-
try {
|
|
177
|
-
baseText = baseStaged ? await readFile(baseStaged, "utf8") : "";
|
|
178
|
-
localText = await readFile(onDisk, "utf8");
|
|
179
|
-
remoteText = await readFile(remoteStaged, "utf8");
|
|
180
|
-
}
|
|
181
|
-
catch {
|
|
182
|
-
return false; // Fall through to whole-file remote-wins via the caller.
|
|
183
|
-
}
|
|
184
|
-
const merged = mergeProjectGodot(baseText, localText, remoteText);
|
|
185
|
-
if (merged.fallback) {
|
|
186
|
-
result.notices.push("project.godot: could not parse all three versions; cloud file won whole-file, local copy preserved");
|
|
187
|
-
return false;
|
|
188
|
-
}
|
|
189
|
-
for (const losing of merged.losingValues) {
|
|
190
|
-
const where = losing.section ? `[${losing.section}] ` : "";
|
|
191
|
-
result.notices.push(`project.godot: ${where}${losing.key}: cloud value won; local value was: ${losing.localValue}`);
|
|
192
|
-
}
|
|
193
|
-
const target = await containedProjectPath(projectRoot, path);
|
|
194
|
-
const tmp = join(dirname(target), `.${basename(target)}.summer-cloud-tmp`);
|
|
195
|
-
await writeFile(tmp, merged.merged, "utf8");
|
|
196
|
-
await renameWithRetry(tmp, target);
|
|
197
|
-
return true;
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* Atomic placement from staging (spec 8.7): clear a read-only attribute on
|
|
201
|
-
* the destination, then rename from staging into place (same volume). When
|
|
202
|
-
* the same blob lands at several paths, all but the last use copy.
|
|
203
|
-
*/
|
|
204
|
-
async function placeFromStaging(projectRoot, path, stagedPath, keepStaged, context) {
|
|
205
|
-
const target = await containedProjectPath(projectRoot, path);
|
|
206
|
-
await clearReadOnly(target);
|
|
207
|
-
// The walker's byte-name map may point at an NFD or different-case name for
|
|
208
|
-
// this key; replace that exact on-disk file so we never strand a twin.
|
|
209
|
-
const onDisk = context.diskPathByKey.get(path);
|
|
210
|
-
if (onDisk && onDisk !== target) {
|
|
211
|
-
await clearReadOnly(onDisk);
|
|
212
|
-
await rm(onDisk, { force: true });
|
|
213
|
-
}
|
|
214
|
-
if (keepStaged) {
|
|
215
|
-
const tmp = join(dirname(target), `.${basename(target)}.summer-cloud-tmp`);
|
|
216
|
-
await copyFile(stagedPath, tmp);
|
|
217
|
-
await renameWithRetry(tmp, target);
|
|
218
|
-
}
|
|
219
|
-
else {
|
|
220
|
-
await renameWithRetry(stagedPath, target);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
async function clearReadOnly(path) {
|
|
224
|
-
try {
|
|
225
|
-
const info = await stat(path);
|
|
226
|
-
if ((info.mode & 0o200) === 0) {
|
|
227
|
-
await chmod(path, info.mode | 0o200);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
catch {
|
|
231
|
-
// Missing file: nothing to clear.
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
/** Windows retry ladder (spec 8.7): EPERM/EBUSY/EACCES, 50 ms doubling, 7 tries. */
|
|
235
|
-
async function renameWithRetry(from, to) {
|
|
236
|
-
let delay = RENAME_BACKOFF_MS;
|
|
237
|
-
for (let attempt = 0;; attempt += 1) {
|
|
238
|
-
try {
|
|
239
|
-
await rename(from, to);
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
catch (err) {
|
|
243
|
-
const code = err.code;
|
|
244
|
-
const retryable = code === "EPERM" || code === "EBUSY" || code === "EACCES";
|
|
245
|
-
if (!retryable || attempt >= RENAME_RETRIES - 1)
|
|
246
|
-
throw err;
|
|
247
|
-
await sleep(delay);
|
|
248
|
-
delay *= 2;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
async function applyCaseOnlyRenames(projectRoot, plan, remote, context, decisionByPath, result) {
|
|
253
|
-
const done = new Set();
|
|
254
|
-
const deleteByFold = new Map();
|
|
255
|
-
for (const path of plan.deleteLocalPaths)
|
|
256
|
-
deleteByFold.set(casefoldKey(path), path);
|
|
257
|
-
for (const pullPath of plan.pullPaths) {
|
|
258
|
-
const oldPath = deleteByFold.get(casefoldKey(pullPath));
|
|
259
|
-
if (!oldPath || oldPath === pullPath)
|
|
260
|
-
continue;
|
|
261
|
-
const oldDecision = decisionByPath.get(oldPath);
|
|
262
|
-
const remoteFile = remote.files[pullPath];
|
|
263
|
-
if (!remoteFile || oldDecision?.local?.sha256 !== remoteFile.sha256)
|
|
264
|
-
continue;
|
|
265
|
-
if (await driftedSinceDiff(projectRoot, oldPath, context))
|
|
266
|
-
continue;
|
|
267
|
-
const source = context.diskPathByKey.get(oldPath) ?? join(projectRoot, oldPath);
|
|
268
|
-
const target = await containedProjectPath(projectRoot, pullPath);
|
|
269
|
-
const tmp = join(dirname(target), `.${basename(target)}.summer-cloud-rename-tmp`);
|
|
270
|
-
try {
|
|
271
|
-
await renameWithRetry(source, tmp);
|
|
272
|
-
await renameWithRetry(tmp, target);
|
|
273
|
-
}
|
|
274
|
-
catch {
|
|
275
|
-
continue; // Fall back to download-and-delete handling for this pair.
|
|
276
|
-
}
|
|
277
|
-
done.add(pullPath);
|
|
278
|
-
done.add(oldPath);
|
|
279
|
-
result.appliedPaths.push(pullPath);
|
|
280
|
-
}
|
|
281
|
-
return done;
|
|
282
|
-
}
|
|
283
|
-
async function isSameFile(a, b) {
|
|
284
|
-
try {
|
|
285
|
-
const [ia, ib] = await Promise.all([stat(a, { bigint: true }), stat(b, { bigint: true })]);
|
|
286
|
-
return ia.dev === ib.dev && ia.ino === ib.ino;
|
|
287
|
-
}
|
|
288
|
-
catch {
|
|
289
|
-
return false;
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
function sleep(ms) {
|
|
293
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
294
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
export interface CheckpointResult {
|
|
2
|
-
ref: string;
|
|
3
|
-
commit: string;
|
|
4
|
-
}
|
|
5
|
-
export declare function summerGitDir(projectRoot: string): string;
|
|
6
|
-
export declare function isGitAvailable(): Promise<boolean>;
|
|
7
|
-
export declare function checkpointStamp(date?: Date): string;
|
|
8
|
-
/**
|
|
9
|
-
* Full-tree SummerGit checkpoint before any destructive apply (spec 11).
|
|
10
|
-
* Plumbing only: stage all into a private index, write-tree, commit-tree,
|
|
11
|
-
* update-ref. Keeps the last KEEP_CHECKPOINTS refs.
|
|
12
|
-
*/
|
|
13
|
-
export declare function createCheckpoint(projectRoot: string, projectId: string): Promise<CheckpointResult>;
|
|
14
|
-
export declare function listCheckpoints(projectRoot: string, projectId: string): Promise<string[]>;
|
|
15
|
-
export interface CheckpointRestoreResult {
|
|
16
|
-
ref: string;
|
|
17
|
-
restoredFiles: string[];
|
|
18
|
-
/** Files present on disk but not in the checkpoint; restore does not delete them. */
|
|
19
|
-
extraneousFiles: string[];
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Restores a checkpoint's bytes (spec 11). checkout-index restores bytes but
|
|
23
|
-
* does not delete files a bad sync ADDED, so the result lists extraneous
|
|
24
|
-
* files for the user or agent to remove.
|
|
25
|
-
*/
|
|
26
|
-
export declare function restoreCheckpoint(projectRoot: string, projectId: string, refOrStamp: string, currentTrackedFiles: readonly string[]): Promise<CheckpointRestoreResult>;
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import { execFile } from "child_process";
|
|
2
|
-
import { mkdir, readFile, rm, writeFile } from "fs/promises";
|
|
3
|
-
import { existsSync } from "fs";
|
|
4
|
-
import { join } from "path";
|
|
5
|
-
import { promisify } from "util";
|
|
6
|
-
import { localCloudDir } from "./paths.js";
|
|
7
|
-
const execFileAsync = promisify(execFile);
|
|
8
|
-
/** Timestamped refs (spec 11): refs/gitsummer/<projectId>/cloud-sync-<utcstamp>. */
|
|
9
|
-
const KEEP_CHECKPOINTS = 20;
|
|
10
|
-
export function summerGitDir(projectRoot) {
|
|
11
|
-
return join(projectRoot, ".summer", "local", "git");
|
|
12
|
-
}
|
|
13
|
-
export async function isGitAvailable() {
|
|
14
|
-
try {
|
|
15
|
-
await execFileAsync("git", ["--version"]);
|
|
16
|
-
return true;
|
|
17
|
-
}
|
|
18
|
-
catch {
|
|
19
|
-
return false;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
async function git(projectRoot, args, env = {}) {
|
|
23
|
-
const gitDir = summerGitDir(projectRoot);
|
|
24
|
-
const { stdout } = await execFileAsync("git", ["--git-dir", gitDir, "--work-tree", projectRoot, "-c", "core.quotepath=false", "-c", "core.bare=false", ...args], {
|
|
25
|
-
cwd: projectRoot,
|
|
26
|
-
maxBuffer: 64 * 1024 * 1024,
|
|
27
|
-
env: {
|
|
28
|
-
...process.env,
|
|
29
|
-
GIT_AUTHOR_NAME: "Summer Cloud",
|
|
30
|
-
GIT_AUTHOR_EMAIL: "cloud@summerengine.com",
|
|
31
|
-
GIT_COMMITTER_NAME: "Summer Cloud",
|
|
32
|
-
GIT_COMMITTER_EMAIL: "cloud@summerengine.com",
|
|
33
|
-
...env,
|
|
34
|
-
},
|
|
35
|
-
});
|
|
36
|
-
return stdout.trim();
|
|
37
|
-
}
|
|
38
|
-
async function ensureBareRepo(projectRoot) {
|
|
39
|
-
const gitDir = summerGitDir(projectRoot);
|
|
40
|
-
if (!existsSync(join(gitDir, "HEAD"))) {
|
|
41
|
-
await mkdir(join(projectRoot, ".summer", "local"), { recursive: true });
|
|
42
|
-
await execFileAsync("git", ["init", "--bare", gitDir], { cwd: projectRoot });
|
|
43
|
-
}
|
|
44
|
-
await ensureExclude(gitDir);
|
|
45
|
-
}
|
|
46
|
-
/** Mirrors GitOps::_ensure_summergit_exclude so checkpoints skip SummerGit's own state. */
|
|
47
|
-
async function ensureExclude(gitDir) {
|
|
48
|
-
const excludePath = join(gitDir, "info", "exclude");
|
|
49
|
-
const sentinelBegin = "# >>> Summer Engine BEGIN (do not edit between sentinels)";
|
|
50
|
-
let existing = "";
|
|
51
|
-
try {
|
|
52
|
-
existing = await readFile(excludePath, "utf8");
|
|
53
|
-
if (existing.includes(sentinelBegin))
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
catch {
|
|
57
|
-
// info/ exists after git init --bare; file may not.
|
|
58
|
-
}
|
|
59
|
-
if (existing && !existing.endsWith("\n"))
|
|
60
|
-
existing += "\n";
|
|
61
|
-
existing += `${sentinelBegin}\n.summer/local/\n.godot/\n# <<< Summer Engine END\n`;
|
|
62
|
-
await mkdir(join(gitDir, "info"), { recursive: true });
|
|
63
|
-
await writeFile(excludePath, existing, "utf8");
|
|
64
|
-
}
|
|
65
|
-
function checkpointIndexFile(projectRoot) {
|
|
66
|
-
return join(localCloudDir(projectRoot), "checkpoint-index");
|
|
67
|
-
}
|
|
68
|
-
export function checkpointStamp(date = new Date()) {
|
|
69
|
-
return date.toISOString().replace(/[-:]/g, "").replace(/\.\d{3}Z$/, "Z");
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Full-tree SummerGit checkpoint before any destructive apply (spec 11).
|
|
73
|
-
* Plumbing only: stage all into a private index, write-tree, commit-tree,
|
|
74
|
-
* update-ref. Keeps the last KEEP_CHECKPOINTS refs.
|
|
75
|
-
*/
|
|
76
|
-
export async function createCheckpoint(projectRoot, projectId) {
|
|
77
|
-
if (!(await isGitAvailable())) {
|
|
78
|
-
throw new Error("git is required for the pre-sync safety checkpoint and was not found on PATH. Install git (run summer doctor to verify), then retry.");
|
|
79
|
-
}
|
|
80
|
-
await ensureBareRepo(projectRoot);
|
|
81
|
-
await mkdir(localCloudDir(projectRoot), { recursive: true, mode: 0o700 });
|
|
82
|
-
// A private index file so checkpoints never fight the engine's own index.
|
|
83
|
-
const indexFile = checkpointIndexFile(projectRoot);
|
|
84
|
-
await rm(indexFile, { force: true });
|
|
85
|
-
const env = { GIT_INDEX_FILE: indexFile };
|
|
86
|
-
await git(projectRoot, ["add", "-A", "--", "."], env);
|
|
87
|
-
const tree = await git(projectRoot, ["write-tree"], env);
|
|
88
|
-
const stamp = checkpointStamp();
|
|
89
|
-
const commit = await git(projectRoot, ["commit-tree", tree, "-m", `Summer Cloud pre-sync checkpoint ${stamp}`], env);
|
|
90
|
-
const ref = `refs/gitsummer/${projectId}/cloud-sync-${stamp}`;
|
|
91
|
-
await git(projectRoot, ["update-ref", ref, commit]);
|
|
92
|
-
await rm(indexFile, { force: true });
|
|
93
|
-
await pruneCheckpoints(projectRoot, projectId);
|
|
94
|
-
return { ref, commit };
|
|
95
|
-
}
|
|
96
|
-
export async function listCheckpoints(projectRoot, projectId) {
|
|
97
|
-
try {
|
|
98
|
-
const out = await git(projectRoot, [
|
|
99
|
-
"for-each-ref",
|
|
100
|
-
"--format=%(refname)",
|
|
101
|
-
`refs/gitsummer/${projectId}/`,
|
|
102
|
-
]);
|
|
103
|
-
return out
|
|
104
|
-
.split("\n")
|
|
105
|
-
.map((line) => line.trim())
|
|
106
|
-
.filter((ref) => ref.includes("/cloud-sync-"))
|
|
107
|
-
.sort();
|
|
108
|
-
}
|
|
109
|
-
catch {
|
|
110
|
-
return [];
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
async function pruneCheckpoints(projectRoot, projectId) {
|
|
114
|
-
const refs = await listCheckpoints(projectRoot, projectId);
|
|
115
|
-
const excess = refs.slice(0, Math.max(0, refs.length - KEEP_CHECKPOINTS));
|
|
116
|
-
for (const ref of excess) {
|
|
117
|
-
await git(projectRoot, ["update-ref", "-d", ref]).catch(() => { });
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Restores a checkpoint's bytes (spec 11). checkout-index restores bytes but
|
|
122
|
-
* does not delete files a bad sync ADDED, so the result lists extraneous
|
|
123
|
-
* files for the user or agent to remove.
|
|
124
|
-
*/
|
|
125
|
-
export async function restoreCheckpoint(projectRoot, projectId, refOrStamp, currentTrackedFiles) {
|
|
126
|
-
if (!(await isGitAvailable())) {
|
|
127
|
-
throw new Error("git is required to restore checkpoints and was not found on PATH.");
|
|
128
|
-
}
|
|
129
|
-
const ref = refOrStamp.startsWith("refs/")
|
|
130
|
-
? refOrStamp
|
|
131
|
-
: `refs/gitsummer/${projectId}/cloud-sync-${refOrStamp}`;
|
|
132
|
-
const indexFile = checkpointIndexFile(projectRoot);
|
|
133
|
-
await rm(indexFile, { force: true });
|
|
134
|
-
const env = { GIT_INDEX_FILE: indexFile };
|
|
135
|
-
await git(projectRoot, ["read-tree", ref], env);
|
|
136
|
-
await git(projectRoot, ["checkout-index", "-a", "-f"], env);
|
|
137
|
-
await rm(indexFile, { force: true });
|
|
138
|
-
const inCheckpoint = new Set((await git(projectRoot, ["ls-tree", "-r", "--name-only", ref])).split("\n").filter(Boolean));
|
|
139
|
-
const restoredFiles = [...inCheckpoint].sort();
|
|
140
|
-
const extraneousFiles = currentTrackedFiles.filter((path) => !inCheckpoint.has(path)).sort();
|
|
141
|
-
return { ref, restoredFiles, extraneousFiles };
|
|
142
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Conflict sets (spec 10.1). Losing bytes never enter the synced tree; they
|
|
3
|
-
* live under .summer/local/cloud/conflicts/<utcstamp>/<original relative
|
|
4
|
-
* path> plus meta.json, and the losing blob is also pushed to R2 (blob-only,
|
|
5
|
-
* granted, unreferenced) so recovery survives the machine.
|
|
6
|
-
*/
|
|
7
|
-
export interface ConflictEntry {
|
|
8
|
-
path: string;
|
|
9
|
-
localSha256?: string;
|
|
10
|
-
remoteSha256?: string;
|
|
11
|
-
winner: "remote" | "local";
|
|
12
|
-
/** True when this entry is sidecar bytes kept for reference inside the set. */
|
|
13
|
-
sidecar?: boolean;
|
|
14
|
-
note?: string;
|
|
15
|
-
}
|
|
16
|
-
export interface ConflictMeta {
|
|
17
|
-
schemaVersion: 1;
|
|
18
|
-
stamp: string;
|
|
19
|
-
projectId: string;
|
|
20
|
-
baseVersion: number | null;
|
|
21
|
-
targetVersion: number | null;
|
|
22
|
-
entries: ConflictEntry[];
|
|
23
|
-
}
|
|
24
|
-
export declare class ConflictSetWriter {
|
|
25
|
-
private readonly projectRoot;
|
|
26
|
-
readonly stamp: string;
|
|
27
|
-
private readonly projectId;
|
|
28
|
-
private readonly baseVersion;
|
|
29
|
-
private readonly targetVersion;
|
|
30
|
-
private entries;
|
|
31
|
-
private wrotePaths;
|
|
32
|
-
constructor(projectRoot: string, stamp: string, projectId: string, baseVersion: number | null, targetVersion: number | null);
|
|
33
|
-
get setDir(): string;
|
|
34
|
-
/** Preserves the current on-disk bytes of `path` into the conflict set. */
|
|
35
|
-
preserve(path: string, entry: Omit<ConflictEntry, "path">, sourcePath?: string): Promise<boolean>;
|
|
36
|
-
hasEntries(): boolean;
|
|
37
|
-
listEntries(): ConflictEntry[];
|
|
38
|
-
finalize(): Promise<void>;
|
|
39
|
-
}
|
|
40
|
-
export declare function conflictStamp(date?: Date): string;
|
|
41
|
-
export declare function listConflictSets(projectRoot: string): Promise<Array<{
|
|
42
|
-
stamp: string;
|
|
43
|
-
meta: ConflictMeta | null;
|
|
44
|
-
}>>;
|
|
45
|
-
/** Retention (spec 6.2): last 20 conflict sets or 30 days, whichever is more. */
|
|
46
|
-
export declare function pruneConflictSets(projectRoot: string): Promise<void>;
|
|
47
|
-
export interface ConflictRestoreResult {
|
|
48
|
-
path: string;
|
|
49
|
-
stamp: string;
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* `summer cloud conflicts restore <path>`: copies the preserved bytes back
|
|
53
|
-
* into the project tree as a fresh edit (next push syncs it normally).
|
|
54
|
-
*/
|
|
55
|
-
export declare function restoreConflictPath(projectRoot: string, path: string, stamp?: string): Promise<ConflictRestoreResult>;
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { copyFile, mkdir, readdir, readFile, rm, stat, writeFile } from "fs/promises";
|
|
2
|
-
import { dirname, join } from "path";
|
|
3
|
-
import { conflictsDir, writeJsonAtomic } from "./paths.js";
|
|
4
|
-
import { containedProjectPath } from "./containment.js";
|
|
5
|
-
const KEEP_SETS = 20;
|
|
6
|
-
const KEEP_DAYS = 30;
|
|
7
|
-
export class ConflictSetWriter {
|
|
8
|
-
projectRoot;
|
|
9
|
-
stamp;
|
|
10
|
-
projectId;
|
|
11
|
-
baseVersion;
|
|
12
|
-
targetVersion;
|
|
13
|
-
entries = [];
|
|
14
|
-
wrotePaths = new Set();
|
|
15
|
-
constructor(projectRoot, stamp, projectId, baseVersion, targetVersion) {
|
|
16
|
-
this.projectRoot = projectRoot;
|
|
17
|
-
this.stamp = stamp;
|
|
18
|
-
this.projectId = projectId;
|
|
19
|
-
this.baseVersion = baseVersion;
|
|
20
|
-
this.targetVersion = targetVersion;
|
|
21
|
-
}
|
|
22
|
-
get setDir() {
|
|
23
|
-
return join(conflictsDir(this.projectRoot), this.stamp);
|
|
24
|
-
}
|
|
25
|
-
/** Preserves the current on-disk bytes of `path` into the conflict set. */
|
|
26
|
-
async preserve(path, entry, sourcePath) {
|
|
27
|
-
const source = sourcePath ?? join(this.projectRoot, path);
|
|
28
|
-
const target = join(this.setDir, path);
|
|
29
|
-
try {
|
|
30
|
-
await mkdir(dirname(target), { recursive: true, mode: 0o700 });
|
|
31
|
-
await copyFile(source, target);
|
|
32
|
-
}
|
|
33
|
-
catch {
|
|
34
|
-
return false; // Nothing local to preserve.
|
|
35
|
-
}
|
|
36
|
-
if (!this.wrotePaths.has(path)) {
|
|
37
|
-
this.wrotePaths.add(path);
|
|
38
|
-
this.entries.push({ path, ...entry });
|
|
39
|
-
}
|
|
40
|
-
return true;
|
|
41
|
-
}
|
|
42
|
-
hasEntries() {
|
|
43
|
-
return this.entries.length > 0;
|
|
44
|
-
}
|
|
45
|
-
listEntries() {
|
|
46
|
-
return [...this.entries];
|
|
47
|
-
}
|
|
48
|
-
async finalize() {
|
|
49
|
-
if (!this.entries.length)
|
|
50
|
-
return;
|
|
51
|
-
const meta = {
|
|
52
|
-
schemaVersion: 1,
|
|
53
|
-
stamp: this.stamp,
|
|
54
|
-
projectId: this.projectId,
|
|
55
|
-
baseVersion: this.baseVersion,
|
|
56
|
-
targetVersion: this.targetVersion,
|
|
57
|
-
entries: this.entries,
|
|
58
|
-
};
|
|
59
|
-
await writeJsonAtomic(join(this.setDir, "meta.json"), meta);
|
|
60
|
-
await pruneConflictSets(this.projectRoot);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
export function conflictStamp(date = new Date()) {
|
|
64
|
-
return date.toISOString().replace(/[-:]/g, "").replace(/\.\d{3}Z$/, "Z");
|
|
65
|
-
}
|
|
66
|
-
export async function listConflictSets(projectRoot) {
|
|
67
|
-
let names = [];
|
|
68
|
-
try {
|
|
69
|
-
names = (await readdir(conflictsDir(projectRoot), { withFileTypes: true }))
|
|
70
|
-
.filter((entry) => entry.isDirectory())
|
|
71
|
-
.map((entry) => entry.name)
|
|
72
|
-
.sort();
|
|
73
|
-
}
|
|
74
|
-
catch {
|
|
75
|
-
return [];
|
|
76
|
-
}
|
|
77
|
-
const sets = [];
|
|
78
|
-
for (const stamp of names) {
|
|
79
|
-
let meta = null;
|
|
80
|
-
try {
|
|
81
|
-
meta = JSON.parse(await readFile(join(conflictsDir(projectRoot), stamp, "meta.json"), "utf8"));
|
|
82
|
-
}
|
|
83
|
-
catch {
|
|
84
|
-
meta = null;
|
|
85
|
-
}
|
|
86
|
-
sets.push({ stamp, meta });
|
|
87
|
-
}
|
|
88
|
-
return sets;
|
|
89
|
-
}
|
|
90
|
-
/** Retention (spec 6.2): last 20 conflict sets or 30 days, whichever is more. */
|
|
91
|
-
export async function pruneConflictSets(projectRoot) {
|
|
92
|
-
const sets = await listConflictSets(projectRoot);
|
|
93
|
-
if (sets.length <= KEEP_SETS)
|
|
94
|
-
return;
|
|
95
|
-
const cutoffMs = Date.now() - KEEP_DAYS * 24 * 60 * 60 * 1000;
|
|
96
|
-
const excess = sets.slice(0, sets.length - KEEP_SETS);
|
|
97
|
-
for (const set of excess) {
|
|
98
|
-
const dir = join(conflictsDir(projectRoot), set.stamp);
|
|
99
|
-
try {
|
|
100
|
-
const info = await stat(dir);
|
|
101
|
-
if (info.mtimeMs >= cutoffMs)
|
|
102
|
-
continue; // Younger than 30 days: keep.
|
|
103
|
-
await rm(dir, { recursive: true, force: true });
|
|
104
|
-
}
|
|
105
|
-
catch {
|
|
106
|
-
// Ignore unreadable sets.
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* `summer cloud conflicts restore <path>`: copies the preserved bytes back
|
|
112
|
-
* into the project tree as a fresh edit (next push syncs it normally).
|
|
113
|
-
*/
|
|
114
|
-
export async function restoreConflictPath(projectRoot, path, stamp) {
|
|
115
|
-
const sets = await listConflictSets(projectRoot);
|
|
116
|
-
const candidates = (stamp ? sets.filter((set) => set.stamp === stamp) : sets).reverse();
|
|
117
|
-
for (const set of candidates) {
|
|
118
|
-
const source = join(conflictsDir(projectRoot), set.stamp, path);
|
|
119
|
-
try {
|
|
120
|
-
const bytes = await readFile(source);
|
|
121
|
-
const target = await containedProjectPath(projectRoot, path);
|
|
122
|
-
await mkdir(dirname(target), { recursive: true });
|
|
123
|
-
await writeFile(target, bytes);
|
|
124
|
-
return { path, stamp: set.stamp };
|
|
125
|
-
}
|
|
126
|
-
catch {
|
|
127
|
-
continue;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
throw new Error(stamp ? `No preserved bytes for ${path} in conflict set ${stamp}` : `No preserved bytes found for ${path} in any conflict set`);
|
|
131
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Write containment (spec 9): after joining a manifest key to the project
|
|
3
|
-
* root, resolve the parent chain and assert the final absolute path is
|
|
4
|
-
* strictly inside the realpath of the project root; refuse to write through
|
|
5
|
-
* any symlinked directory component; create nested parents per component so
|
|
6
|
-
* a hostile manifest can never escape the project.
|
|
7
|
-
*/
|
|
8
|
-
export declare function containedProjectPath(projectRoot: string, key: string): Promise<string>;
|