castle-web-cli 0.4.114 → 0.4.116

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/dist/agent-prompts.js +2 -2
  2. package/dist/agent.d.ts +9 -9
  3. package/dist/agent.js +590 -589
  4. package/dist/castleJson.d.ts +7 -0
  5. package/dist/castleJson.js +10 -0
  6. package/dist/editorConfig.d.ts +34 -0
  7. package/dist/editorConfig.js +125 -0
  8. package/dist/ide.js +245 -120
  9. package/dist/imports.d.ts +10 -0
  10. package/dist/imports.js +149 -17
  11. package/dist/init.d.ts +3 -0
  12. package/dist/init.js +113 -88
  13. package/dist/install.d.ts +1 -1
  14. package/dist/install.js +26 -24
  15. package/dist/serve.js +16 -0
  16. package/dist/shell/assets/index-DiPlPGyg.js +144 -0
  17. package/dist/shell/assets/index-Y6cJRRCX.css +1 -0
  18. package/dist/shell/index.html +2 -2
  19. package/dist/unsupportedMedia.d.ts +1 -0
  20. package/dist/unsupportedMedia.js +54 -0
  21. package/dist/vitePlugins.js +13 -20
  22. package/kits/basic-2d/castle.json +1 -1
  23. package/kits/basic-2d/editors/behaviorRegistry.js +5 -7
  24. package/kits/physics-2d/CLAUDE.md +65 -34
  25. package/kits/physics-2d/{physics/behaviors → behaviors}/AnalogStick.jsx +3 -3
  26. package/kits/physics-2d/behaviors/Collider.jsx +1 -1
  27. package/kits/physics-2d/{physics/behaviors → behaviors}/Draggable.jsx +3 -3
  28. package/kits/physics-2d/{physics/behaviors → behaviors}/Joints.jsx +5 -5
  29. package/kits/physics-2d/{physics/behaviors → behaviors}/RigidBody.jsx +2 -2
  30. package/kits/physics-2d/{physics/behaviors → behaviors}/Slingshot.jsx +3 -3
  31. package/kits/physics-2d/behaviors/Sound.jsx +152 -0
  32. package/kits/physics-2d/behaviors/Sprite.jsx +112 -42
  33. package/kits/physics-2d/behaviors/Tone.jsx +83 -0
  34. package/kits/physics-2d/behaviors/Video.jsx +111 -0
  35. package/kits/physics-2d/behaviors/tint.js +24 -9
  36. package/kits/physics-2d/blueprints/ball.scene +1 -1
  37. package/kits/physics-2d/blueprints/block.scene +1 -1
  38. package/kits/physics-2d/blueprints/cauldron.scene +1 -1
  39. package/kits/physics-2d/blueprints/crate.scene +1 -1
  40. package/kits/physics-2d/castle.json +74 -4
  41. package/kits/physics-2d/docs/pxart-format.md +537 -51
  42. package/kits/physics-2d/editors/BlueprintLibrary.jsx +7 -3
  43. package/kits/physics-2d/editors/ImageViewer.jsx +206 -0
  44. package/kits/physics-2d/editors/MediaPlayer.jsx +57 -0
  45. package/kits/physics-2d/editors/PxArtEditor.jsx +1794 -65
  46. package/kits/physics-2d/editors/SceneEditor.jsx +7 -3
  47. package/kits/physics-2d/editors/SingleEditor.jsx +8 -0
  48. package/kits/physics-2d/editors/behaviorRegistry.js +5 -7
  49. package/kits/physics-2d/editors/brushFit.js +535 -0
  50. package/kits/physics-2d/editors/brushShapes.js +140 -0
  51. package/kits/physics-2d/editors/mediaFile.js +31 -0
  52. package/kits/physics-2d/editors/mediaViewer.module.css +128 -0
  53. package/kits/physics-2d/editors/pathOverlay.js +340 -0
  54. package/kits/physics-2d/editors/pathTools.js +1906 -0
  55. package/kits/physics-2d/editors/pixelCanvas.js +13 -0
  56. package/kits/physics-2d/editors/pixelEditorChrome.jsx +2 -2
  57. package/kits/physics-2d/editors/pixelGeometry.js +4 -2
  58. package/kits/physics-2d/editors/pixelInspector.jsx +410 -37
  59. package/kits/physics-2d/editors/pxArtEditorModel.js +172 -16
  60. package/kits/physics-2d/editors/pxArtTimeline.jsx +163 -43
  61. package/kits/physics-2d/editors/pxArtTimeline.module.css +31 -5
  62. package/kits/physics-2d/engine/ScenePlayer.jsx +1 -0
  63. package/kits/physics-2d/engine/art.js +105 -0
  64. package/kits/physics-2d/engine/assets.js +12 -4
  65. package/kits/physics-2d/engine/audioContext.js +34 -0
  66. package/kits/physics-2d/engine/blueprint.js +3 -3
  67. package/kits/physics-2d/engine/collider.js +28 -17
  68. package/kits/physics-2d/engine/files.js +77 -1
  69. package/kits/physics-2d/engine/liveReload.js +1 -1
  70. package/kits/physics-2d/engine/media.js +212 -0
  71. package/kits/physics-2d/{physics → engine/physics}/PhysicsSystem.js +1 -1
  72. package/kits/physics-2d/{physics → engine/physics}/jointArt.js +3 -4
  73. package/kits/physics-2d/{physics → engine/physics}/matterBridge.js +2 -9
  74. package/kits/physics-2d/engine/pxart.js +153 -35
  75. package/kits/physics-2d/engine/pxartPath.js +1356 -0
  76. package/kits/physics-2d/engine/pxartSmooth.js +276 -125
  77. package/kits/physics-2d/engine/scene.js +12 -0
  78. package/kits/physics-2d/engine/tone.js +112 -0
  79. package/kits/physics-2d/engine/ui.jsx +22 -1
  80. package/kits/physics-2d/engine/ui.module.css +36 -12
  81. package/kits/physics-2d/package-lock.json +1 -1
  82. package/kits/physics-2d/scripts/draw.mjs +7 -7
  83. package/kits/physics-2d/scripts/import-svg.mjs +1231 -0
  84. package/kits/physics-2d/scripts/svg-emission-guide.md +92 -0
  85. package/kits/physics-2d/systems/media.js +34 -0
  86. package/kits/physics-2d/systems/physics.js +12 -3
  87. package/package.json +1 -1
  88. package/dist/shell/assets/index-CqpY1xZR.js +0 -144
  89. package/dist/shell/assets/index-DCwVFL5u.css +0 -1
  90. package/kits/physics-2d/physics/index.js +0 -26
  91. /package/kits/physics-2d/drawings/{block.pxart → block.sprite} +0 -0
  92. /package/kits/physics-2d/drawings/{cauldron.pxart → cauldron.sprite} +0 -0
  93. /package/kits/physics-2d/drawings/{joint-rope.pxart → joint-rope.sprite} +0 -0
  94. /package/kits/physics-2d/{physics → engine/physics}/controls.js +0 -0
  95. /package/kits/physics-2d/{physics → engine/physics}/joints.js +0 -0
package/dist/install.js CHANGED
@@ -1,16 +1,27 @@
1
- import { execSync } from "child_process";
2
- import * as fs from "fs";
3
- import * as path from "path";
4
- import { restoreMissingImports, syncImportDependencies } from "./imports.js";
1
+ import { execSync, spawn } from 'child_process';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+ import { restoreMissingImports, syncImportDependencies } from './imports.js';
5
5
  function hasPnpm() {
6
6
  try {
7
- execSync("pnpm --version", { stdio: "ignore" });
7
+ execSync('pnpm --version', { stdio: 'ignore' });
8
8
  return true;
9
9
  }
10
10
  catch {
11
11
  return false;
12
12
  }
13
13
  }
14
+ // Run an install command without blocking the event loop. `installDeps` also runs
15
+ // INSIDE the serve (an import from the editor adds deps), and an `execSync` there
16
+ // would freeze vite, the file API and the serve websocket for the whole install --
17
+ // the editor would look hung, not busy.
18
+ function run(command, cwd) {
19
+ return new Promise((resolve, reject) => {
20
+ const child = spawn(command, { cwd, shell: true, stdio: 'inherit' });
21
+ child.on('error', reject);
22
+ child.on('close', (code) => code === 0 ? resolve() : reject(new Error(`\`${command}\` exited with code ${code}`)));
23
+ });
24
+ }
14
25
  // Install a deck's deps. Prefer pnpm -- in the e2b template a pnpm store is baked
15
26
  // in, so this is near-instant (hardlinks from the store, no download). Fall back to
16
27
  // npm when pnpm isn't on PATH (e.g. a laptop that never installed it).
@@ -18,15 +29,12 @@ function hasPnpm() {
18
29
  // scripts (pnpm 10+ gates them and exits non-zero otherwise, and the deck's deps are
19
30
  // all prebuilt pure JS that don't need them). `frozen` installs straight from the
20
31
  // shipped lockfile (skips resolution -> no network, fast + deterministic).
21
- export function installDeps(projectDir, frozen) {
32
+ export async function installDeps(projectDir, frozen) {
22
33
  if (hasPnpm()) {
23
- console.log("Installing deps (pnpm)...");
24
- const frozenFlag = frozen ? "--frozen-lockfile " : "";
34
+ console.log('Installing deps (pnpm)...');
35
+ const frozenFlag = frozen ? '--frozen-lockfile ' : '';
25
36
  try {
26
- execSync(`pnpm install ${frozenFlag}--prefer-offline --ignore-scripts`, {
27
- cwd: projectDir,
28
- stdio: "inherit",
29
- });
37
+ await run(`pnpm install ${frozenFlag}--prefer-offline --ignore-scripts`, projectDir);
30
38
  }
31
39
  catch (err) {
32
40
  if (!frozen)
@@ -36,19 +44,13 @@ export function installDeps(projectDir, frozen) {
36
44
  // wasn't regenerated). Rather than leave the deck with no node_modules,
37
45
  // retry with resolution allowed -- a little slower (re-resolves + may
38
46
  // fetch), but self-heals the drift instead of breaking.
39
- console.warn("Frozen install failed; retrying with resolution (lockfile drift?)...");
40
- execSync("pnpm install --prefer-offline --ignore-scripts", {
41
- cwd: projectDir,
42
- stdio: "inherit",
43
- });
47
+ console.warn('Frozen install failed; retrying with resolution (lockfile drift?)...');
48
+ await run('pnpm install --prefer-offline --ignore-scripts', projectDir);
44
49
  }
45
50
  }
46
51
  else {
47
- console.log("Installing deps (npm)...");
48
- execSync("npm install --no-audit --no-fund --loglevel=error", {
49
- cwd: projectDir,
50
- stdio: "inherit",
51
- });
52
+ console.log('Installing deps (npm)...');
53
+ await run('npm install --no-audit --no-fund --loglevel=error', projectDir);
52
54
  }
53
55
  }
54
56
  // `castle-web install <dir>`: put node_modules in place for a deck that already has
@@ -56,7 +58,7 @@ export function installDeps(projectDir, frozen) {
56
58
  // (the cloud hosts treat it as regenerable and don't snapshot it).
57
59
  export async function install(dir) {
58
60
  const projectDir = path.resolve(dir);
59
- if (!fs.existsSync(path.join(projectDir, "package.json"))) {
61
+ if (!fs.existsSync(path.join(projectDir, 'package.json'))) {
60
62
  console.error(`No package.json in ${projectDir}.`);
61
63
  process.exit(1);
62
64
  }
@@ -72,6 +74,6 @@ export async function install(dir) {
72
74
  const added = syncImportDependencies(projectDir);
73
75
  for (const dep of added)
74
76
  console.log(`Added dependency ${dep} from an import`);
75
- installDeps(projectDir, fs.existsSync(path.join(projectDir, "pnpm-lock.yaml")));
77
+ await installDeps(projectDir, fs.existsSync(path.join(projectDir, 'pnpm-lock.yaml')));
76
78
  console.log(`Installed deps in ${projectDir}`);
77
79
  }
package/dist/serve.js CHANGED
@@ -8,6 +8,7 @@ import { createIdeServer, FAVICON_LINK_TAGS } from './ide.js';
8
8
  import { createAgentServer } from './agent.js';
9
9
  import { sceneFilesPlugin, importsAliasPlugin } from './vitePlugins.js';
10
10
  import { installFilesChangedWatcher } from './filesChanged.js';
11
+ import { autoUpdateImports } from './imports.js';
11
12
  import * as config from './config.js';
12
13
  import { graphql as castleGraphql } from './api.js';
13
14
  import { executeCommand } from './castle-host/host.js';
@@ -214,6 +215,21 @@ export async function serve(dir, options = {}) {
214
215
  await serveDetached(projectDir, options);
215
216
  return;
216
217
  }
218
+ // Imports whose decks opted into auto-update move to their latest version
219
+ // now, before anything is served. Serve start is the only safe moment for it:
220
+ // the process is booting, so no editor holds unsaved state and no play
221
+ // session is running against the copy being replaced.
222
+ //
223
+ // Skipped when this deck already has a live serve. That deck IS open -- the
224
+ // dedup above normally returns before here, but an explicit --port/--host
225
+ // asks for a second serve, and a second serve is not a reason to replace
226
+ // files under the first one's session.
227
+ if (!existingServe(projectDir)) {
228
+ // A failure to check must never keep the deck from opening.
229
+ await autoUpdateImports(projectDir).catch((e) => {
230
+ console.warn(`auto-update: skipped -- ${e instanceof Error ? e.message : String(e)}`);
231
+ });
232
+ }
217
233
  // Close stdin when not attached to a TTY so the process can be cleanly
218
234
  // backgrounded with `&` (otherwise stdin reads can block or hold the parent).
219
235
  if (!process.stdin.isTTY) {