@needle-tools/engine 5.0.2 → 5.1.0-canary.525aa82

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 (176) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +6 -7
  3. package/SKILL.md +39 -21
  4. package/components.needle.json +1 -1
  5. package/dist/needle-engine.bundle-DPag02s9.min.js +1732 -0
  6. package/dist/needle-engine.bundle-IPMzQpe1.umd.cjs +1732 -0
  7. package/dist/{needle-engine.bundle-BoTyA-Le.js → needle-engine.bundle-qa_NEunk.js} +8881 -8148
  8. package/dist/needle-engine.d.ts +633 -61
  9. package/dist/needle-engine.js +576 -565
  10. package/dist/needle-engine.min.js +1 -1
  11. package/dist/needle-engine.umd.cjs +1 -1
  12. package/dist/{vendor-vHLk8sXu.js → vendor-CAcsI0eU.js} +116 -115
  13. package/dist/{vendor-CntUvmJu.umd.cjs → vendor-CEM38hLE.umd.cjs} +2 -2
  14. package/dist/{vendor-DPbfJJ4d.min.js → vendor-HRlxIBga.min.js} +2 -2
  15. package/lib/engine/api.d.ts +2 -0
  16. package/lib/engine/api.js +2 -0
  17. package/lib/engine/api.js.map +1 -1
  18. package/lib/engine/engine_addressables.js +5 -1
  19. package/lib/engine/engine_addressables.js.map +1 -1
  20. package/lib/engine/engine_animation.d.ts +14 -7
  21. package/lib/engine/engine_animation.js +49 -9
  22. package/lib/engine/engine_animation.js.map +1 -1
  23. package/lib/engine/engine_components.js +33 -4
  24. package/lib/engine/engine_components.js.map +1 -1
  25. package/lib/engine/engine_context.d.ts +7 -2
  26. package/lib/engine/engine_context.js +10 -2
  27. package/lib/engine/engine_context.js.map +1 -1
  28. package/lib/engine/engine_gameobject.d.ts +4 -0
  29. package/lib/engine/engine_gameobject.js.map +1 -1
  30. package/lib/engine/engine_init.js +4 -0
  31. package/lib/engine/engine_init.js.map +1 -1
  32. package/lib/engine/engine_input.js +4 -1
  33. package/lib/engine/engine_input.js.map +1 -1
  34. package/lib/engine/engine_materialpropertyblock.js +1 -20
  35. package/lib/engine/engine_materialpropertyblock.js.map +1 -1
  36. package/lib/engine/engine_networking.d.ts +11 -8
  37. package/lib/engine/engine_networking.js +43 -26
  38. package/lib/engine/engine_networking.js.map +1 -1
  39. package/lib/engine/engine_networking_instantiate.d.ts +100 -5
  40. package/lib/engine/engine_networking_instantiate.js +150 -16
  41. package/lib/engine/engine_networking_instantiate.js.map +1 -1
  42. package/lib/engine/engine_networking_prefabs.d.ts +59 -0
  43. package/lib/engine/engine_networking_prefabs.js +67 -0
  44. package/lib/engine/engine_networking_prefabs.js.map +1 -0
  45. package/lib/engine/engine_physics_rapier.d.ts +3 -0
  46. package/lib/engine/engine_physics_rapier.js +13 -9
  47. package/lib/engine/engine_physics_rapier.js.map +1 -1
  48. package/lib/engine/postprocessing/api.d.ts +2 -0
  49. package/lib/engine/postprocessing/api.js +2 -0
  50. package/lib/engine/postprocessing/api.js.map +1 -0
  51. package/lib/engine/postprocessing/index.d.ts +2 -0
  52. package/lib/engine/postprocessing/index.js +2 -0
  53. package/lib/engine/postprocessing/index.js.map +1 -0
  54. package/lib/engine/postprocessing/postprocessing.d.ts +83 -0
  55. package/lib/engine/postprocessing/postprocessing.js +280 -0
  56. package/lib/engine/postprocessing/postprocessing.js.map +1 -0
  57. package/lib/engine/postprocessing/types.d.ts +39 -0
  58. package/lib/engine/postprocessing/types.js +2 -0
  59. package/lib/engine/postprocessing/types.js.map +1 -0
  60. package/lib/engine/webcomponents/WebXRButtons.js +17 -3
  61. package/lib/engine/webcomponents/WebXRButtons.js.map +1 -1
  62. package/lib/engine/webcomponents/icons.js +3 -1
  63. package/lib/engine/webcomponents/icons.js.map +1 -1
  64. package/lib/engine/xr/NeedleXRSession.d.ts +1 -0
  65. package/lib/engine/xr/NeedleXRSession.js +43 -10
  66. package/lib/engine/xr/NeedleXRSession.js.map +1 -1
  67. package/lib/engine/xr/init.d.ts +4 -0
  68. package/lib/engine/xr/init.js +49 -0
  69. package/lib/engine/xr/init.js.map +1 -0
  70. package/lib/engine-components/AnimationUtils.d.ts +4 -1
  71. package/lib/engine-components/AnimationUtils.js +7 -19
  72. package/lib/engine-components/AnimationUtils.js.map +1 -1
  73. package/lib/engine-components/AnimatorController.d.ts +135 -2
  74. package/lib/engine-components/AnimatorController.js +216 -13
  75. package/lib/engine-components/AnimatorController.js.map +1 -1
  76. package/lib/engine-components/GroundProjection.d.ts +1 -0
  77. package/lib/engine-components/GroundProjection.js +184 -48
  78. package/lib/engine-components/GroundProjection.js.map +1 -1
  79. package/lib/engine-components/OrbitControls.d.ts +4 -0
  80. package/lib/engine-components/OrbitControls.js +5 -1
  81. package/lib/engine-components/OrbitControls.js.map +1 -1
  82. package/lib/engine-components/SeeThrough.d.ts +0 -2
  83. package/lib/engine-components/SeeThrough.js +0 -89
  84. package/lib/engine-components/SeeThrough.js.map +1 -1
  85. package/lib/engine-components/SyncedRoom.d.ts +4 -0
  86. package/lib/engine-components/SyncedRoom.js +23 -8
  87. package/lib/engine-components/SyncedRoom.js.map +1 -1
  88. package/lib/engine-components/SyncedTransform.js +5 -5
  89. package/lib/engine-components/SyncedTransform.js.map +1 -1
  90. package/lib/engine-components/Voip.d.ts +46 -0
  91. package/lib/engine-components/Voip.js +126 -2
  92. package/lib/engine-components/Voip.js.map +1 -1
  93. package/lib/engine-components/api.d.ts +1 -0
  94. package/lib/engine-components/api.js +1 -0
  95. package/lib/engine-components/api.js.map +1 -1
  96. package/lib/engine-components/codegen/components.d.ts +1 -0
  97. package/lib/engine-components/codegen/components.js +1 -0
  98. package/lib/engine-components/codegen/components.js.map +1 -1
  99. package/lib/engine-components/postprocessing/Effects/Tonemapping.d.ts +5 -2
  100. package/lib/engine-components/postprocessing/Effects/Tonemapping.js +11 -18
  101. package/lib/engine-components/postprocessing/Effects/Tonemapping.js.map +1 -1
  102. package/lib/engine-components/postprocessing/PostProcessingEffect.d.ts +3 -4
  103. package/lib/engine-components/postprocessing/PostProcessingEffect.js +6 -15
  104. package/lib/engine-components/postprocessing/PostProcessingEffect.js.map +1 -1
  105. package/lib/engine-components/postprocessing/PostProcessingHandler.d.ts +2 -1
  106. package/lib/engine-components/postprocessing/PostProcessingHandler.js.map +1 -1
  107. package/lib/engine-components/postprocessing/Volume.d.ts +18 -11
  108. package/lib/engine-components/postprocessing/Volume.js +61 -140
  109. package/lib/engine-components/postprocessing/Volume.js.map +1 -1
  110. package/lib/engine-components/postprocessing/index.d.ts +1 -0
  111. package/lib/engine-components/postprocessing/index.js +1 -0
  112. package/lib/engine-components/postprocessing/index.js.map +1 -1
  113. package/lib/engine-components/postprocessing/utils.d.ts +2 -0
  114. package/lib/engine-components/postprocessing/utils.js +2 -0
  115. package/lib/engine-components/postprocessing/utils.js.map +1 -1
  116. package/lib/engine-components/ui/Canvas.js +2 -2
  117. package/lib/engine-components/ui/Canvas.js.map +1 -1
  118. package/lib/engine-components/ui/Graphic.d.ts +3 -3
  119. package/lib/engine-components/ui/Graphic.js +6 -2
  120. package/lib/engine-components/ui/Graphic.js.map +1 -1
  121. package/lib/engine-components/ui/Text.d.ts +64 -11
  122. package/lib/engine-components/ui/Text.js +154 -45
  123. package/lib/engine-components/ui/Text.js.map +1 -1
  124. package/lib/engine-components/ui/index.d.ts +1 -0
  125. package/lib/engine-components/ui/index.js +1 -0
  126. package/lib/engine-components/ui/index.js.map +1 -1
  127. package/lib/engine-components-experimental/networking/PlayerSync.d.ts +25 -3
  128. package/lib/engine-components-experimental/networking/PlayerSync.js +60 -11
  129. package/lib/engine-components-experimental/networking/PlayerSync.js.map +1 -1
  130. package/package.json +6 -5
  131. package/plugins/vite/ai.d.ts +11 -10
  132. package/plugins/vite/ai.js +305 -31
  133. package/src/engine/api.ts +3 -0
  134. package/src/engine/engine_addressables.ts +4 -1
  135. package/src/engine/engine_animation.ts +47 -9
  136. package/src/engine/engine_components.ts +36 -7
  137. package/src/engine/engine_context.ts +11 -2
  138. package/src/engine/engine_gameobject.ts +5 -0
  139. package/src/engine/engine_init.ts +4 -0
  140. package/src/engine/engine_input.ts +2 -1
  141. package/src/engine/engine_materialpropertyblock.ts +1 -20
  142. package/src/engine/engine_networking.ts +46 -23
  143. package/src/engine/engine_networking_instantiate.ts +160 -18
  144. package/src/engine/engine_networking_prefabs.ts +80 -0
  145. package/src/engine/engine_physics_rapier.ts +14 -9
  146. package/src/engine/postprocessing/api.ts +2 -0
  147. package/src/engine/postprocessing/index.ts +2 -0
  148. package/src/engine/postprocessing/postprocessing.ts +322 -0
  149. package/src/engine/postprocessing/types.ts +43 -0
  150. package/src/engine/webcomponents/WebXRButtons.ts +21 -4
  151. package/src/engine/webcomponents/icons.ts +5 -3
  152. package/src/engine/xr/NeedleXRSession.ts +50 -15
  153. package/src/engine/xr/init.ts +56 -0
  154. package/src/engine-components/AnimationUtils.ts +7 -17
  155. package/src/engine-components/AnimatorController.ts +288 -18
  156. package/src/engine-components/GroundProjection.ts +226 -52
  157. package/src/engine-components/OrbitControls.ts +5 -1
  158. package/src/engine-components/SeeThrough.ts +0 -116
  159. package/src/engine-components/SyncedRoom.ts +28 -9
  160. package/src/engine-components/SyncedTransform.ts +5 -5
  161. package/src/engine-components/Voip.ts +129 -2
  162. package/src/engine-components/api.ts +1 -0
  163. package/src/engine-components/codegen/components.ts +1 -0
  164. package/src/engine-components/postprocessing/Effects/Tonemapping.ts +16 -24
  165. package/src/engine-components/postprocessing/PostProcessingEffect.ts +9 -16
  166. package/src/engine-components/postprocessing/PostProcessingHandler.ts +2 -1
  167. package/src/engine-components/postprocessing/Volume.ts +72 -163
  168. package/src/engine-components/postprocessing/index.ts +1 -0
  169. package/src/engine-components/postprocessing/utils.ts +2 -0
  170. package/src/engine-components/ui/Canvas.ts +2 -2
  171. package/src/engine-components/ui/Graphic.ts +7 -3
  172. package/src/engine-components/ui/Text.ts +170 -52
  173. package/src/engine-components/ui/index.ts +2 -1
  174. package/src/engine-components-experimental/networking/PlayerSync.ts +64 -11
  175. package/dist/needle-engine.bundle-B3ywqx5o.min.js +0 -1654
  176. package/dist/needle-engine.bundle-CzOPcOui.umd.cjs +0 -1654
@@ -8,7 +8,7 @@ import { Object3D } from "three";
8
8
  import { AssetReference } from "../../engine/engine_addressables.js";
9
9
  import { RoomEvents } from "../../engine/engine_networking.js";
10
10
  import { syncField } from "../../engine/engine_networking_auto.js";
11
- import { syncDestroy } from "../../engine/engine_networking_instantiate.js";
11
+ import { onSyncInstantiate, syncDestroy } from "../../engine/engine_networking_instantiate.js";
12
12
  import { serializable } from "../../engine/engine_serialization_decorator.js";
13
13
  import { delay, getParam } from "../../engine/engine_utils.js";
14
14
  import { Behaviour, Component, GameObject } from "../../engine-components/Component.js";
@@ -36,18 +36,48 @@ export class PlayerSync extends Behaviour {
36
36
  * scene.add(res.gameObject);
37
37
  * ```
38
38
  */
39
- static async setupFrom(url, init) {
40
- const assetReference = AssetReference.getOrCreateFromUrl(url);
41
- if (!assetReference.asset) {
42
- const i = await assetReference.loadAssetAsync();
43
- if (i)
44
- GameObject.getOrAddComponent(i, PlayerState);
39
+ /**
40
+ * This API is experimental and may change or be removed in the future.
41
+ * Creates a PlayerSync instance at runtime from a given URL or Object3D and sets it up for networking.
42
+ * @param urlOrObject Path to the asset that should be instantiated for each player, or a pre-created Object3D to use as the player prefab
43
+ * @param init Optional initialization parameters for the PlayerSync component
44
+ * @returns Promise resolving to a PlayerSync instance with a guaranteed asset property
45
+ * @example
46
+ * ```typescript
47
+ * // From a GLB URL:
48
+ * const res = await PlayerSync.setupFrom("/assets/demo.glb");
49
+ *
50
+ * // From a runtime-created Object3D:
51
+ * const avatar = ObjectUtils.createPrimitive("Sphere");
52
+ * const res = await PlayerSync.setupFrom(avatar);
53
+ * ```
54
+ */
55
+ static async setupFrom(urlOrObject, init) {
56
+ let assetReference;
57
+ if (typeof urlOrObject === "string") {
58
+ assetReference = AssetReference.getOrCreateFromUrl(urlOrObject);
59
+ if (!assetReference.asset) {
60
+ const i = await assetReference.loadAssetAsync();
61
+ if (i)
62
+ GameObject.getOrAddComponent(i, PlayerState);
63
+ }
64
+ }
65
+ else {
66
+ // Runtime Object3D passed directly — wrap in AssetReference without loading
67
+ // Ensure the prefab has a guid (required for syncInstantiate)
68
+ const guid = init?.guid ?? urlOrObject["guid"] ?? urlOrObject.name ?? urlOrObject.uuid;
69
+ if (!urlOrObject["guid"])
70
+ urlOrObject["guid"] = guid;
71
+ assetReference = new AssetReference({ asset: urlOrObject });
72
+ GameObject.getOrAddComponent(urlOrObject, PlayerState);
45
73
  }
46
74
  const ps = new PlayerSync();
47
75
  ps._internalInit(init);
48
76
  ps.asset = assetReference;
49
77
  const obj = new Object3D();
50
- obj["guid"] = url;
78
+ // The guid is used to identify this PlayerSync instance across the network.
79
+ // For URLs it uses the URL itself; for runtime objects it tries the init guid, object guid, name, or uuid.
80
+ obj["guid"] = init?.guid ?? (typeof urlOrObject === "string" ? urlOrObject : (urlOrObject["guid"] || urlOrObject.name || urlOrObject.uuid));
51
81
  GameObject.addComponent(obj, ps);
52
82
  return ps;
53
83
  }
@@ -60,20 +90,38 @@ export class PlayerSync extends Behaviour {
60
90
  */
61
91
  asset;
62
92
  /**
63
- * Event invoked when a player instance is spawned with the spawned {@link Object3D} as parameter
93
+ * Event invoked when ANY player instance is spawned both local and remote.
94
+ * The event argument is a {@link PlayerSpawnedEventArgs} with the player Object3D and whether it's the local player.
95
+ * For backward compatibility, the first argument is also the Object3D directly.
64
96
  * @serializable
65
97
  */
66
98
  onPlayerSpawned;
67
99
  _localInstance;
100
+ _unsubSyncInstantiate;
101
+ constructor() {
102
+ super();
103
+ this.onPlayerSpawned = new EventList();
104
+ }
68
105
  awake() {
69
106
  this.watchTabVisible();
70
- if (!this.onPlayerSpawned)
71
- this.onPlayerSpawned = new EventList();
72
107
  }
73
108
  onEnable() {
74
109
  this.context.connection.beginListen(RoomEvents.RoomStateSent, this.onJoinedRoom);
75
110
  this.context.connection.beginListen(RoomEvents.JoinedRoom, this.onJoinedRoom);
76
111
  this.context.connection.beginListen(RoomEvents.LeftRoom, this.destroyInstance);
112
+ // Listen for remote syncInstantiate events to detect remote player spawns
113
+ this._unsubSyncInstantiate = onSyncInstantiate((instance, model) => {
114
+ // Only handle instances that match this PlayerSync's asset
115
+ const assetGuid = this.asset?.asset?.["guid"];
116
+ if (!assetGuid || model.originalGuid !== assetGuid)
117
+ return;
118
+ const pl = GameObject.getComponentsInChildren(instance, PlayerState);
119
+ if (pl?.length) {
120
+ if (debug)
121
+ console.log("PlayerSync: remote player spawned", instance.name);
122
+ this.onPlayerSpawned?.invoke(instance);
123
+ }
124
+ });
77
125
  if (this.context.connection.isInRoom) {
78
126
  this.onJoinedRoom();
79
127
  }
@@ -82,6 +130,7 @@ export class PlayerSync extends Behaviour {
82
130
  this.context.connection.stopListen(RoomEvents.RoomStateSent, this.onJoinedRoom);
83
131
  this.context.connection.stopListen(RoomEvents.JoinedRoom, this.onJoinedRoom);
84
132
  this.context.connection.stopListen(RoomEvents.LeftRoom, this.destroyInstance);
133
+ this._unsubSyncInstantiate?.();
85
134
  }
86
135
  onJoinedRoom = () => {
87
136
  if (debug)
@@ -1 +1 @@
1
- {"version":3,"file":"PlayerSync.js","sourceRoot":"","sources":["../../../src/engine-components-experimental/networking/PlayerSync.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PlayerSync.js","sourceRoot":"","sources":["../../../src/engine-components-experimental/networking/PlayerSync.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@needle-tools/engine",
3
- "version": "5.0.2",
3
+ "version": "5.1.0-canary.525aa82",
4
4
  "description": "Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.",
5
5
  "main": "dist/needle-engine.min.js",
6
6
  "exports": {
@@ -68,9 +68,10 @@
68
68
  "build:plugin-types": "tsc -p tsconfig.plugins.json && cp .plugin-types-tmp/plugins/vite/*.d.ts plugins/vite/ && cp .plugin-types-tmp/plugins/next/*.d.ts plugins/next/ && rm -rf .plugin-types-tmp",
69
69
  "build:components-data": "node plugins/publish/create-component-types.now.mjs",
70
70
  "test": "node plugins/test/test.mjs",
71
- "test:playwright": "cd tests/playwright && npm install --prefer-offline && npx playwright install --with-deps chromium && npx playwright test",
72
- "test:playwright:fast": "cd tests/playwright && npm install --prefer-offline && npx playwright install --with-deps chromium && npx playwright test --grep @fast",
73
- "test:playwright:report": "cd tests/playwright && npm install --prefer-offline && npx playwright install --with-deps chromium && npx playwright show-report",
71
+ "test:playwright:setup": "cd tests/playwright && npm install --prefer-offline && npx playwright install --with-deps chromium",
72
+ "test:playwright": "npm run test:playwright:setup && npx playwright test",
73
+ "test:playwright:fast": "npm run test:playwright:setup && npx playwright test --grep @fast",
74
+ "test:playwright:report": "npm run test:playwright:setup && npx playwright show-report",
74
75
  "test:circular-imports": "node plugins/test/check-circular-imports.mjs",
75
76
  "test:tsc": "node plugins/test/test.tsc.mjs",
76
77
  "test:attw": "npx --yes @arethetypeswrong/cli --pack dist",
@@ -204,4 +205,4 @@
204
205
  "module": "lib/needle-engine.js",
205
206
  "typings": "lib/needle-engine.d.ts",
206
207
  "types": "lib/needle-engine.d.ts"
207
- }
208
+ }
@@ -1,17 +1,18 @@
1
1
  /**
2
2
  * Needle Engine AI skill installer.
3
3
  *
4
- * Writes a Needle Engine skill to `<dir>/skills/needle-engine/SKILL.md`
5
- * for each supported AI agent directory (`.claude/`, `.github/`, `.agents/`).
6
- * Both Claude Code and GitHub Copilot auto-load skills based on their
7
- * description frontmatter, so the AI agent will automatically have Needle
8
- * Engine context when working in the project.
4
+ * Auto-detects AI coding agents by checking for their config directories
5
+ * in the project root, then writes the Needle Engine skill in each agent's
6
+ * native format.
9
7
  *
10
- * The skill is only written if at least one of the supported directories
11
- * already exists in the project root (i.e. the developer is already using
12
- * an AI coding agent).
13
- * Old skill files are always overwritten so the skill stays up to date with
14
- * the engine version.
8
+ * Supported agents: Claude Code, GitHub Copilot, Cursor, Codex / universal.
9
+ *
10
+ * `.agents/skills/needle-engine/` is always created as the canonical skill
11
+ * location. SKILL.md and downloaded reference files live there. Other agents
12
+ * symlink to it to avoid duplication.
13
+ *
14
+ * Remote reference files (API docs, templates, etc.) linked from SKILL.md are
15
+ * downloaded at install time and stored locally with relative paths.
15
16
  *
16
17
  * @param {"build" | "serve"} command
17
18
  * @param {{} | undefined | null} config
@@ -1,5 +1,5 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
2
- import { dirname, join } from "path";
1
+ import { copyFileSync, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, symlinkSync, writeFileSync } from "fs";
2
+ import { dirname, join, relative } from "path";
3
3
  import { fileURLToPath } from "url";
4
4
  import { needleLog } from "./logging.js";
5
5
 
@@ -8,20 +8,49 @@ const __dirname = dirname(__filename);
8
8
 
9
9
  const pluginName = "needle-ai";
10
10
 
11
+ /**
12
+ * Supported AI coding agents.
13
+ * Each entry defines how to detect the agent and how to write its skill file.
14
+ * `detect` is the directory that must exist in the project root.
15
+ * `write(cwd, canonicalDir, content)` installs the skill in the agent's native format.
16
+ *
17
+ * The `.agents/` entry is special: it is the canonical location where SKILL.md
18
+ * and downloaded reference files are written directly. All other agents symlink
19
+ * their skill directory to `.agents/skills/needle-engine/`.
20
+ */
21
+ const agents = [
22
+ {
23
+ name: "Claude Code",
24
+ detect: ".claude",
25
+ write: (cwd, canonicalDir, content) => symlinkSkillDir(join(cwd, ".claude"), canonicalDir),
26
+ },
27
+ {
28
+ name: "GitHub Copilot",
29
+ detect: ".github",
30
+ write: (cwd, canonicalDir, content) => symlinkSkillDir(join(cwd, ".github"), canonicalDir),
31
+ },
32
+ {
33
+ name: "Cursor",
34
+ detect: ".cursor",
35
+ write: (cwd, canonicalDir, content) => writeCursorRule(cwd, canonicalDir, content),
36
+ },
37
+ ];
38
+
11
39
  /**
12
40
  * Needle Engine AI skill installer.
13
41
  *
14
- * Writes a Needle Engine skill to `<dir>/skills/needle-engine/SKILL.md`
15
- * for each supported AI agent directory (`.claude/`, `.github/`, `.agents/`).
16
- * Both Claude Code and GitHub Copilot auto-load skills based on their
17
- * description frontmatter, so the AI agent will automatically have Needle
18
- * Engine context when working in the project.
42
+ * Auto-detects AI coding agents by checking for their config directories
43
+ * in the project root, then writes the Needle Engine skill in each agent's
44
+ * native format.
45
+ *
46
+ * Supported agents: Claude Code, GitHub Copilot, Cursor, Codex / universal.
19
47
  *
20
- * The skill is only written if at least one of the supported directories
21
- * already exists in the project root (i.e. the developer is already using
22
- * an AI coding agent).
23
- * Old skill files are always overwritten so the skill stays up to date with
24
- * the engine version.
48
+ * `.agents/skills/needle-engine/` is always created as the canonical skill
49
+ * location. SKILL.md and downloaded reference files live there. Other agents
50
+ * symlink to it to avoid duplication.
51
+ *
52
+ * Remote reference files (API docs, templates, etc.) linked from SKILL.md are
53
+ * downloaded at install time and stored locally with relative paths.
25
54
  *
26
55
  * @param {"build" | "serve"} command
27
56
  * @param {{} | undefined | null} config
@@ -32,34 +61,279 @@ export function needleAI(command, config, userSettings) {
32
61
  return {
33
62
  name: pluginName,
34
63
  enforce: "pre",
35
- buildStart() {
36
- installClaudeSkill();
64
+ async buildStart() {
65
+ await installSkills();
37
66
  },
38
- configureServer() {
39
- installClaudeSkill();
67
+ async configureServer() {
68
+ await installSkills();
40
69
  },
41
70
  };
42
71
  }
43
72
 
44
- function writeSkill(claudeDir) {
45
- const skillDir = join(claudeDir, "skills", "needle-engine");
46
- if (!existsSync(skillDir)) {
47
- mkdirSync(skillDir, { recursive: true });
48
- }
49
- const skillPath = join(skillDir, "SKILL.md");
73
+ /** Read the SKILL.md template shipped with the engine. */
74
+ function getSkillContent() {
50
75
  const templatePath = join(__dirname, "../../SKILL.md");
51
- const content = readFileSync(templatePath, "utf8");
52
- writeFileSync(skillPath, content, "utf8");
53
- return skillPath;
76
+ return readFileSync(templatePath, "utf8");
77
+ }
78
+
79
+ /**
80
+ * Extract the body of a SKILL.md file (everything after the YAML frontmatter).
81
+ * Returns the full content if no frontmatter is found.
82
+ */
83
+ function stripFrontmatter(content) {
84
+ const match = content.match(/^---\r?\n[\s\S]*?\r?\n---\r?\n([\s\S]*)$/);
85
+ return match ? match[1].trimStart() : content;
86
+ }
87
+
88
+ // ---------------------------------------------------------------------------
89
+ // Remote reference downloading
90
+ // ---------------------------------------------------------------------------
91
+
92
+ /**
93
+ * Extract markdown links to raw.githubusercontent.com files from content.
94
+ * Returns an array of { fullMatch, linkText, url, subdir, filename, localRelPath }.
95
+ */
96
+ function extractRemoteRefs(content) {
97
+ const pattern = /\[([^\]]*)\]\((https:\/\/raw\.githubusercontent\.com\/[^)]+)\)/g;
98
+ const refs = [];
99
+ let match;
100
+ while ((match = pattern.exec(content)) !== null) {
101
+ const url = match[2];
102
+ const urlPath = new URL(url).pathname;
103
+ const segments = urlPath.split("/").filter(Boolean);
104
+ const filename = segments[segments.length - 1];
105
+ const subdir = segments[segments.length - 2] || "";
106
+ refs.push({
107
+ fullMatch: match[0],
108
+ linkText: match[1],
109
+ url,
110
+ subdir,
111
+ filename,
112
+ localRelPath: `./${subdir}/${filename}`,
113
+ });
114
+ }
115
+ return refs;
54
116
  }
55
117
 
56
- function installClaudeSkill() {
118
+ /**
119
+ * Download a single remote file. Returns text on success, null on failure.
120
+ * @param {{ fullMatch: string, linkText: string, url: string, subdir: string, filename: string, localRelPath: string }} ref
121
+ * @param {number} timeoutMs
122
+ * @returns {Promise<string | null>}
123
+ */
124
+ async function downloadRef(ref, timeoutMs = 5000) {
125
+ try {
126
+ const controller = new AbortController();
127
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
128
+ const response = await fetch(ref.url, { signal: controller.signal });
129
+ clearTimeout(timer);
130
+ if (!response.ok) return null;
131
+ return await response.text();
132
+ }
133
+ catch {
134
+ return null;
135
+ }
136
+ }
137
+
138
+ /**
139
+ * Download all remote references found in content. Returns rewritten content
140
+ * (absolute URLs → relative paths) and the downloaded file data.
141
+ * Failed downloads keep their original absolute URL.
142
+ */
143
+ async function downloadAndRewriteRefs(content) {
144
+ const refs = extractRemoteRefs(content);
145
+ if (refs.length === 0) return { rewrittenContent: content, downloadedFiles: [] };
146
+
147
+ if (typeof globalThis.fetch !== "function") {
148
+ return { rewrittenContent: content, downloadedFiles: [] };
149
+ }
150
+
151
+ const results = await Promise.allSettled(
152
+ refs.map(async ref => {
153
+ const data = await downloadRef(ref);
154
+ return { ref, data };
155
+ })
156
+ );
157
+
158
+ let rewrittenContent = content;
159
+ const downloadedFiles = [];
160
+
161
+ for (const result of results) {
162
+ if (result.status === "fulfilled" && result.value.data !== null) {
163
+ const { ref, data } = result.value;
164
+ const newLink = `[${ref.linkText}](${ref.localRelPath})`;
165
+ rewrittenContent = rewrittenContent.replace(ref.fullMatch, newLink);
166
+ downloadedFiles.push({
167
+ subdir: ref.subdir,
168
+ filename: ref.filename,
169
+ data,
170
+ });
171
+ }
172
+ }
173
+
174
+ return { rewrittenContent, downloadedFiles };
175
+ }
176
+
177
+ // ---------------------------------------------------------------------------
178
+ // Canonical skill directory (.agents/)
179
+ // ---------------------------------------------------------------------------
180
+
181
+ /**
182
+ * Write SKILL.md and downloaded reference files into the canonical location
183
+ * at `.agents/skills/needle-engine/`. This directory is always created and
184
+ * serves as the symlink target for all other agents.
185
+ * @returns {string} The absolute path to the canonical skill directory.
186
+ */
187
+ function writeCanonicalSkillDir(cwd, content, downloadedFiles) {
188
+ const canonicalDir = join(cwd, ".agents", "skills", "needle-engine");
189
+ if (!existsSync(canonicalDir)) {
190
+ mkdirSync(canonicalDir, { recursive: true });
191
+ }
192
+
193
+ writeFileSync(join(canonicalDir, "SKILL.md"), content, "utf8");
194
+
195
+ for (const file of downloadedFiles) {
196
+ const fileDir = join(canonicalDir, file.subdir);
197
+ if (!existsSync(fileDir)) {
198
+ mkdirSync(fileDir, { recursive: true });
199
+ }
200
+ writeFileSync(join(fileDir, file.filename), file.data, "utf8");
201
+ }
202
+
203
+ return canonicalDir;
204
+ }
205
+
206
+ // ---------------------------------------------------------------------------
207
+ // Agent writers
208
+ // ---------------------------------------------------------------------------
209
+
210
+ /**
211
+ * Create a symlink at `<agentDir>/skills/needle-engine` → canonical skill dir.
212
+ * If the target already exists (file, dir, or stale symlink), it is replaced.
213
+ */
214
+ function symlinkSkillDir(agentDir, canonicalDir) {
215
+ const skillsDir = join(agentDir, "skills");
216
+ const linkPath = join(skillsDir, "needle-engine");
217
+
218
+ if (!existsSync(skillsDir)) {
219
+ mkdirSync(skillsDir, { recursive: true });
220
+ }
221
+
222
+ const target = relative(skillsDir, canonicalDir);
223
+
224
+ // Remove existing entry (file, dir, or stale symlink)
225
+ try {
226
+ if (existsSync(linkPath) || lstatSync(linkPath).isSymbolicLink()) {
227
+ rmSync(linkPath, { recursive: true, force: true });
228
+ }
229
+ }
230
+ catch { /* nothing to remove */ }
231
+
232
+ try {
233
+ symlinkSync(target, linkPath, "junction");
234
+ return linkPath;
235
+ }
236
+ catch {
237
+ // Fallback: copy if symlink fails (e.g. Windows without privileges)
238
+ if (!existsSync(linkPath)) {
239
+ mkdirSync(linkPath, { recursive: true });
240
+ }
241
+ copyDirSync(canonicalDir, linkPath);
242
+ return linkPath;
243
+ }
244
+ }
245
+
246
+ /**
247
+ * Write a Cursor rule file at `.cursor/rules/needle-engine.mdc` and symlink
248
+ * the reference files directory at `.cursor/rules/needle-engine/`.
249
+ * Cursor uses its own frontmatter format (description, globs, alwaysApply).
250
+ */
251
+ function writeCursorRule(cwd, canonicalDir, content) {
252
+ const rulesDir = join(cwd, ".cursor", "rules");
253
+ if (!existsSync(rulesDir)) {
254
+ mkdirSync(rulesDir, { recursive: true });
255
+ }
256
+
257
+ // Symlink .cursor/rules/needle-engine/ → canonical dir (for reference files)
258
+ const linkPath = join(rulesDir, "needle-engine");
259
+ const target = relative(rulesDir, canonicalDir);
260
+ try {
261
+ if (existsSync(linkPath) || lstatSync(linkPath).isSymbolicLink()) {
262
+ rmSync(linkPath, { recursive: true, force: true });
263
+ }
264
+ }
265
+ catch { /* nothing to remove */ }
266
+
267
+ try {
268
+ symlinkSync(target, linkPath, "junction");
269
+ }
270
+ catch {
271
+ // Fallback: copy directly
272
+ if (!existsSync(linkPath)) {
273
+ mkdirSync(linkPath, { recursive: true });
274
+ }
275
+ copyDirSync(canonicalDir, linkPath);
276
+ }
277
+
278
+ // Write the .mdc file with adjusted relative paths
279
+ // SKILL.md uses ./references/api.md but the .mdc sits at .cursor/rules/needle-engine.mdc
280
+ // so we need ./needle-engine/references/api.md
281
+ let body = stripFrontmatter(content);
282
+ body = body.replace(/\]\(\.\/(references|templates)\//g, "](./needle-engine/$1/");
283
+
284
+ const rulePath = join(rulesDir, "needle-engine.mdc");
285
+ const cursorContent = `---
286
+ description: Needle Engine context — use when editing TypeScript components, Vite config, GLB assets, or anything related to @needle-tools/engine.
287
+ globs:
288
+ alwaysApply: false
289
+ ---
290
+ ${body}`;
291
+ writeFileSync(rulePath, cursorContent, "utf8");
292
+ return rulePath;
293
+ }
294
+
295
+ // ---------------------------------------------------------------------------
296
+ // Helpers
297
+ // ---------------------------------------------------------------------------
298
+
299
+ /** Recursively copy a directory's contents. */
300
+ function copyDirSync(src, dest) {
301
+ for (const entry of readdirSync(src)) {
302
+ const srcPath = join(src, entry);
303
+ const destPath = join(dest, entry);
304
+ if (statSync(srcPath).isDirectory()) {
305
+ if (!existsSync(destPath)) mkdirSync(destPath, { recursive: true });
306
+ copyDirSync(srcPath, destPath);
307
+ }
308
+ else {
309
+ copyFileSync(srcPath, destPath);
310
+ }
311
+ }
312
+ }
313
+
314
+ // ---------------------------------------------------------------------------
315
+ // Main
316
+ // ---------------------------------------------------------------------------
317
+
318
+ /** Detect agents and install the Needle Engine skill for each. */
319
+ async function installSkills() {
57
320
  const cwd = process.cwd();
58
- const dirs = [".claude", ".github", ".agents"].map(d => join(cwd, d)).filter(d => existsSync(d));
59
- if (dirs.length === 0) return; // only install if developer uses an AI coding agent
60
321
 
61
- for (const dir of dirs) {
62
- const path = writeSkill(dir);
63
- if (path) needleLog(`[${pluginName}] Installed Needle Engine skill → ${path}`);
322
+ const rawContent = getSkillContent();
323
+ const { rewrittenContent, downloadedFiles } = await downloadAndRewriteRefs(rawContent);
324
+
325
+ // Always write to .agents/ as the canonical location
326
+ const canonicalDir = writeCanonicalSkillDir(cwd, rewrittenContent, downloadedFiles);
327
+
328
+ // Symlink other detected agents to the canonical dir
329
+ const detected = agents.filter(a => existsSync(join(cwd, a.detect)));
330
+ const names = ["Codex / Universal"];
331
+ for (const agent of detected) {
332
+ const path = agent.write(cwd, canonicalDir, rewrittenContent);
333
+ if (path) names.push(agent.name);
64
334
  }
335
+
336
+ const refCount = downloadedFiles.length;
337
+ const refMsg = refCount > 0 ? ` (${refCount} reference file${refCount === 1 ? "" : "s"} downloaded)` : "";
338
+ needleLog(pluginName, `Installed for ${names.length} agent${names.length === 1 ? "" : "s"}: ${names.join(", ")}${refMsg}`);
65
339
  }
package/src/engine/api.ts CHANGED
@@ -318,6 +318,9 @@ export * from "./engine_physics.types.js";
318
318
  /** Rapier physics engine integration */
319
319
  export * from "./engine_physics_rapier.js";
320
320
 
321
+ /** Core postprocessing stack (accessible via context.postprocessing) */
322
+ export * from "./postprocessing/api.js";
323
+
321
324
 
322
325
  // ============================================================================
323
326
  // PLAYER & VIEW MANAGEMENT
@@ -463,7 +463,10 @@ export class AssetReference {
463
463
  if (networked) {
464
464
  options.context = context;
465
465
  const prefab = this.asset;
466
- prefab.guid = this.url;
466
+ // Only set guid from URL if we have one — runtime Object3D prefabs
467
+ // (via new AssetReference({ asset: obj })) have no URL and may already
468
+ // have a user-assigned guid. Don't overwrite with empty string.
469
+ if (this.url) prefab.guid = this.url;
467
470
  const instance = syncInstantiate(prefab, options, undefined, saveOnServer);
468
471
  if (instance) {
469
472
  return instance;