@rotifer/playground 0.5.0-alpha.2 → 0.7.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.
Files changed (316) hide show
  1. package/CHANGELOG.md +159 -15
  2. package/LICENSE +1 -1
  3. package/README.md +51 -23
  4. package/README.zh.md +54 -25
  5. package/dist/cloud/auth.d.ts +7 -1
  6. package/dist/cloud/auth.d.ts.map +1 -1
  7. package/dist/cloud/auth.js +65 -1
  8. package/dist/cloud/auth.js.map +1 -1
  9. package/dist/cloud/client.d.ts +4 -1
  10. package/dist/cloud/client.d.ts.map +1 -1
  11. package/dist/cloud/client.js +9 -2
  12. package/dist/cloud/client.js.map +1 -1
  13. package/dist/cloud/types.d.ts +3 -1
  14. package/dist/cloud/types.d.ts.map +1 -1
  15. package/dist/cloud/types.js.map +1 -1
  16. package/dist/commands/agent-create.d.ts.map +1 -1
  17. package/dist/commands/agent-create.js +66 -3
  18. package/dist/commands/agent-create.js.map +1 -1
  19. package/dist/commands/agent-run.d.ts.map +1 -1
  20. package/dist/commands/agent-run.js +296 -32
  21. package/dist/commands/agent-run.js.map +1 -1
  22. package/dist/commands/arena-submit.d.ts.map +1 -1
  23. package/dist/commands/arena-submit.js +45 -17
  24. package/dist/commands/arena-submit.js.map +1 -1
  25. package/dist/commands/compile.d.ts.map +1 -1
  26. package/dist/commands/compile.js +9 -3
  27. package/dist/commands/compile.js.map +1 -1
  28. package/dist/commands/init.d.ts.map +1 -1
  29. package/dist/commands/init.js +13 -3
  30. package/dist/commands/init.js.map +1 -1
  31. package/dist/commands/login.d.ts.map +1 -1
  32. package/dist/commands/login.js +23 -16
  33. package/dist/commands/login.js.map +1 -1
  34. package/dist/commands/network.js +4 -4
  35. package/dist/commands/network.js.map +1 -1
  36. package/dist/commands/publish.d.ts.map +1 -1
  37. package/dist/commands/publish.js +162 -44
  38. package/dist/commands/publish.js.map +1 -1
  39. package/dist/commands/test.d.ts.map +1 -1
  40. package/dist/commands/test.js +209 -23
  41. package/dist/commands/test.js.map +1 -1
  42. package/dist/commands/wrap.d.ts.map +1 -1
  43. package/dist/commands/wrap.js +17 -1
  44. package/dist/commands/wrap.js.map +1 -1
  45. package/dist/index.js +0 -0
  46. package/dist/runtime/network-gateway.d.ts +53 -0
  47. package/dist/runtime/network-gateway.d.ts.map +1 -0
  48. package/dist/runtime/network-gateway.js +147 -0
  49. package/dist/runtime/network-gateway.js.map +1 -0
  50. package/dist/utils/binding.d.ts +25 -0
  51. package/dist/utils/binding.d.ts.map +1 -1
  52. package/dist/utils/binding.js.map +1 -1
  53. package/dist/utils/open-browser.d.ts +10 -0
  54. package/dist/utils/open-browser.d.ts.map +1 -0
  55. package/dist/utils/open-browser.js +23 -0
  56. package/dist/utils/open-browser.js.map +1 -0
  57. package/genes/academic-writer/.cloud-manifest.json +6 -0
  58. package/genes/academic-writer/.gene-manifest.json +8 -0
  59. package/genes/academic-writer/SKILL.md +274 -0
  60. package/genes/academic-writer/phenotype.json +28 -0
  61. package/genes/ai-components/.cloud-manifest.json +6 -0
  62. package/genes/ai-components/.gene-manifest.json +8 -0
  63. package/genes/ai-components/SKILL.md +381 -0
  64. package/genes/ai-components/phenotype.json +28 -0
  65. package/genes/algorithmic-art/.cloud-manifest.json +6 -0
  66. package/genes/algorithmic-art/.gene-manifest.json +8 -0
  67. package/genes/algorithmic-art/SKILL.md +405 -0
  68. package/genes/algorithmic-art/phenotype.json +28 -0
  69. package/genes/answer-synthesizer/.cloud-manifest.json +6 -0
  70. package/genes/answer-synthesizer/index.ts +194 -0
  71. package/genes/answer-synthesizer/phenotype.json +61 -0
  72. package/genes/api-designer/.cloud-manifest.json +6 -0
  73. package/genes/api-designer/.gene-manifest.json +8 -0
  74. package/genes/api-designer/SKILL.md +456 -0
  75. package/genes/api-designer/phenotype.json +28 -0
  76. package/genes/auto-coder/.cloud-manifest.json +6 -0
  77. package/genes/auto-coder/.gene-manifest.json +8 -0
  78. package/genes/auto-coder/SKILL.md +400 -0
  79. package/genes/auto-coder/phenotype.json +28 -0
  80. package/genes/auto-writer/.cloud-manifest.json +6 -0
  81. package/genes/auto-writer/.gene-manifest.json +8 -0
  82. package/genes/auto-writer/SKILL.md +361 -0
  83. package/genes/auto-writer/phenotype.json +28 -0
  84. package/genes/brand-personality/.cloud-manifest.json +6 -0
  85. package/genes/brand-personality/.gene-manifest.json +8 -0
  86. package/genes/brand-personality/SKILL.md +549 -0
  87. package/genes/brand-personality/phenotype.json +28 -0
  88. package/genes/business-writer/.cloud-manifest.json +6 -0
  89. package/genes/business-writer/.gene-manifest.json +8 -0
  90. package/genes/business-writer/SKILL.md +448 -0
  91. package/genes/business-writer/phenotype.json +28 -0
  92. package/genes/citation-manager/.cloud-manifest.json +6 -0
  93. package/genes/citation-manager/.gene-manifest.json +8 -0
  94. package/genes/citation-manager/SKILL.md +279 -0
  95. package/genes/citation-manager/index.ts +162 -0
  96. package/genes/citation-manager/package.json +1 -0
  97. package/genes/citation-manager/phenotype.json +50 -0
  98. package/genes/code-complexity/.cloud-manifest.json +6 -0
  99. package/genes/code-complexity/README.md +35 -0
  100. package/genes/code-complexity/index.ts +101 -0
  101. package/genes/code-complexity/phenotype.json +34 -0
  102. package/genes/copywriter/.cloud-manifest.json +6 -0
  103. package/genes/copywriter/.gene-manifest.json +8 -0
  104. package/genes/copywriter/SKILL.md +329 -0
  105. package/genes/copywriter/phenotype.json +28 -0
  106. package/genes/creative-writer/.cloud-manifest.json +6 -0
  107. package/genes/creative-writer/.gene-manifest.json +8 -0
  108. package/genes/creative-writer/SKILL.md +356 -0
  109. package/genes/creative-writer/phenotype.json +28 -0
  110. package/genes/data-modeler/.cloud-manifest.json +6 -0
  111. package/genes/data-modeler/.gene-manifest.json +8 -0
  112. package/genes/data-modeler/SKILL.md +486 -0
  113. package/genes/data-modeler/phenotype.json +28 -0
  114. package/genes/debugger/.cloud-manifest.json +6 -0
  115. package/genes/debugger/.gene-manifest.json +8 -0
  116. package/genes/debugger/SKILL.md +416 -0
  117. package/genes/debugger/phenotype.json +28 -0
  118. package/genes/design-tokens/.cloud-manifest.json +6 -0
  119. package/genes/design-tokens/.gene-manifest.json +8 -0
  120. package/genes/design-tokens/SKILL.md +222 -0
  121. package/genes/design-tokens/index.ts +128 -0
  122. package/genes/design-tokens/package.json +1 -0
  123. package/genes/design-tokens/phenotype.json +1 -0
  124. package/genes/devops-automator/.cloud-manifest.json +6 -0
  125. package/genes/devops-automator/.gene-manifest.json +8 -0
  126. package/genes/devops-automator/SKILL.md +490 -0
  127. package/genes/devops-automator/phenotype.json +28 -0
  128. package/genes/doc-coauthoring/.cloud-manifest.json +6 -0
  129. package/genes/doc-coauthoring/.gene-manifest.json +8 -0
  130. package/genes/doc-coauthoring/SKILL.md +375 -0
  131. package/genes/doc-coauthoring/phenotype.json +28 -0
  132. package/genes/doc-retrieval/.cloud-manifest.json +6 -0
  133. package/genes/doc-retrieval/index.ts +134 -0
  134. package/genes/doc-retrieval/phenotype.json +54 -0
  135. package/genes/docs-writer/.cloud-manifest.json +6 -0
  136. package/genes/docs-writer/.gene-manifest.json +8 -0
  137. package/genes/docs-writer/SKILL.md +492 -0
  138. package/genes/docs-writer/phenotype.json +28 -0
  139. package/genes/evolve-life/.cloud-manifest.json +6 -0
  140. package/genes/evolve-life/.compile-result.json +12 -0
  141. package/genes/evolve-life/README.md +52 -0
  142. package/genes/evolve-life/gene.ir.wasm +0 -0
  143. package/genes/evolve-life/gene.wasm +0 -0
  144. package/genes/evolve-life/index.ts +255 -0
  145. package/genes/evolve-life/phenotype.json +129 -0
  146. package/genes/evolve-life-bitwise/.cloud-manifest.json +6 -0
  147. package/genes/evolve-life-bitwise/.compile-result.json +12 -0
  148. package/genes/evolve-life-bitwise/gene.ir.wasm +0 -0
  149. package/genes/evolve-life-bitwise/gene.wasm +0 -0
  150. package/genes/evolve-life-bitwise/index.ts +273 -0
  151. package/genes/evolve-life-bitwise/phenotype.json +129 -0
  152. package/genes/evolve-life-sparse/.cloud-manifest.json +6 -0
  153. package/genes/evolve-life-sparse/.compile-result.json +12 -0
  154. package/genes/evolve-life-sparse/gene.ir.wasm +0 -0
  155. package/genes/evolve-life-sparse/gene.wasm +0 -0
  156. package/genes/evolve-life-sparse/index.ts +236 -0
  157. package/genes/evolve-life-sparse/phenotype.json +129 -0
  158. package/genes/fact-checker/.cloud-manifest.json +6 -0
  159. package/genes/fact-checker/.gene-manifest.json +8 -0
  160. package/genes/fact-checker/SKILL.md +373 -0
  161. package/genes/fact-checker/phenotype.json +28 -0
  162. package/genes/genesis-code-format/.cloud-manifest.json +6 -0
  163. package/genes/genesis-code-format/package.json +1 -0
  164. package/genes/genesis-code-format/phenotype.json +1 -0
  165. package/genes/genesis-file-read/.cloud-manifest.json +6 -0
  166. package/genes/genesis-file-read/index.ts +11 -1
  167. package/genes/genesis-file-read/package.json +1 -0
  168. package/genes/genesis-file-read/phenotype.json +1 -0
  169. package/genes/genesis-l0-constraint/.cloud-manifest.json +6 -0
  170. package/genes/genesis-l0-constraint/package.json +1 -0
  171. package/genes/genesis-l0-constraint/phenotype.json +1 -0
  172. package/genes/genesis-web-search/.cloud-manifest.json +2 -2
  173. package/genes/genesis-web-search/package.json +1 -0
  174. package/genes/genesis-web-search/phenotype.json +1 -0
  175. package/genes/genesis-web-search-lite/.cloud-manifest.json +6 -0
  176. package/genes/genesis-web-search-lite/package.json +1 -0
  177. package/genes/genesis-web-search-lite/phenotype.json +1 -0
  178. package/genes/git-workflow/.cloud-manifest.json +6 -0
  179. package/genes/git-workflow/.gene-manifest.json +8 -0
  180. package/genes/git-workflow/SKILL.md +407 -0
  181. package/genes/git-workflow/phenotype.json +28 -0
  182. package/genes/grammar-checker/.cloud-manifest.json +6 -0
  183. package/genes/grammar-checker/.gene-manifest.json +8 -0
  184. package/genes/grammar-checker/SKILL.md +194 -0
  185. package/genes/grammar-checker/index.ts +168 -0
  186. package/genes/grammar-checker/package.json +1 -0
  187. package/genes/grammar-checker/phenotype.json +52 -0
  188. package/genes/json-validator/.cloud-manifest.json +6 -0
  189. package/genes/json-validator/README.md +42 -0
  190. package/genes/json-validator/index.ts +112 -0
  191. package/genes/json-validator/phenotype.json +42 -0
  192. package/genes/license-advisor/.cloud-manifest.json +6 -0
  193. package/genes/license-advisor/.gene-manifest.json +8 -0
  194. package/genes/license-advisor/SKILL.md +117 -0
  195. package/genes/license-advisor/phenotype.json +28 -0
  196. package/genes/logic-architect/.cloud-manifest.json +6 -0
  197. package/genes/logic-architect/.gene-manifest.json +8 -0
  198. package/genes/logic-architect/SKILL.md +451 -0
  199. package/genes/logic-architect/phenotype.json +28 -0
  200. package/genes/markdown-formatter/.cloud-manifest.json +6 -0
  201. package/genes/markdown-formatter/README.md +34 -0
  202. package/genes/markdown-formatter/index.ts +86 -0
  203. package/genes/markdown-formatter/phenotype.json +32 -0
  204. package/genes/orch/.cloud-manifest.json +6 -0
  205. package/genes/orch/.gene-manifest.json +8 -0
  206. package/genes/orch/SKILL.md +504 -0
  207. package/genes/orch/phenotype.json +28 -0
  208. package/genes/particle-barneshut/.cloud-manifest.json +6 -0
  209. package/genes/particle-barneshut/.compile-result.json +12 -0
  210. package/genes/particle-barneshut/README.md +55 -0
  211. package/genes/particle-barneshut/gene.ir.wasm +0 -0
  212. package/genes/particle-barneshut/gene.wasm +0 -0
  213. package/genes/particle-barneshut/index.ts +486 -0
  214. package/genes/particle-barneshut/phenotype.json +137 -0
  215. package/genes/particle-brute/.cloud-manifest.json +6 -0
  216. package/genes/particle-brute/.compile-result.json +12 -0
  217. package/genes/particle-brute/README.md +55 -0
  218. package/genes/particle-brute/gene.ir.wasm +0 -0
  219. package/genes/particle-brute/gene.wasm +0 -0
  220. package/genes/particle-brute/index.ts +277 -0
  221. package/genes/particle-brute/phenotype.json +137 -0
  222. package/genes/particle-spatial/.cloud-manifest.json +6 -0
  223. package/genes/particle-spatial/.compile-result.json +12 -0
  224. package/genes/particle-spatial/README.md +53 -0
  225. package/genes/particle-spatial/gene.ir.wasm +0 -0
  226. package/genes/particle-spatial/gene.wasm +0 -0
  227. package/genes/particle-spatial/index.ts +352 -0
  228. package/genes/particle-spatial/phenotype.json +137 -0
  229. package/genes/performance-optimizer/.cloud-manifest.json +6 -0
  230. package/genes/performance-optimizer/.gene-manifest.json +8 -0
  231. package/genes/performance-optimizer/SKILL.md +480 -0
  232. package/genes/performance-optimizer/phenotype.json +28 -0
  233. package/genes/plagiarism-checker/.cloud-manifest.json +6 -0
  234. package/genes/plagiarism-checker/.gene-manifest.json +8 -0
  235. package/genes/plagiarism-checker/SKILL.md +342 -0
  236. package/genes/plagiarism-checker/phenotype.json +28 -0
  237. package/genes/product-manager/.cloud-manifest.json +6 -0
  238. package/genes/product-manager/.gene-manifest.json +8 -0
  239. package/genes/product-manager/SKILL.md +249 -0
  240. package/genes/product-manager/phenotype.json +28 -0
  241. package/genes/project-reviewer/.cloud-manifest.json +6 -0
  242. package/genes/project-reviewer/.gene-manifest.json +8 -0
  243. package/genes/project-reviewer/SKILL.md +312 -0
  244. package/genes/project-reviewer/phenotype.json +28 -0
  245. package/genes/prompt-engineer/.cloud-manifest.json +6 -0
  246. package/genes/prompt-engineer/.gene-manifest.json +8 -0
  247. package/genes/prompt-engineer/SKILL.md +411 -0
  248. package/genes/prompt-engineer/phenotype.json +28 -0
  249. package/genes/readability-analyzer/.cloud-manifest.json +6 -0
  250. package/genes/readability-analyzer/.gene-manifest.json +8 -0
  251. package/genes/readability-analyzer/SKILL.md +357 -0
  252. package/genes/readability-analyzer/index.ts +123 -0
  253. package/genes/readability-analyzer/package.json +1 -0
  254. package/genes/readability-analyzer/phenotype.json +35 -0
  255. package/genes/rotifer-protocol/SKILL.md +121 -0
  256. package/genes/security-auditor/.cloud-manifest.json +6 -0
  257. package/genes/security-auditor/.gene-manifest.json +8 -0
  258. package/genes/security-auditor/SKILL.md +494 -0
  259. package/genes/security-auditor/phenotype.json +28 -0
  260. package/genes/seo-optimizer/.cloud-manifest.json +6 -0
  261. package/genes/seo-optimizer/.gene-manifest.json +8 -0
  262. package/genes/seo-optimizer/SKILL.md +327 -0
  263. package/genes/seo-optimizer/index.ts +206 -0
  264. package/genes/seo-optimizer/package.json +1 -0
  265. package/genes/seo-optimizer/phenotype.json +1 -0
  266. package/genes/source-linker/.cloud-manifest.json +6 -0
  267. package/genes/source-linker/index.ts +88 -0
  268. package/genes/source-linker/phenotype.json +45 -0
  269. package/genes/style-optimizer/.cloud-manifest.json +6 -0
  270. package/genes/style-optimizer/.gene-manifest.json +8 -0
  271. package/genes/style-optimizer/SKILL.md +285 -0
  272. package/genes/style-optimizer/phenotype.json +28 -0
  273. package/genes/tech-lead/.cloud-manifest.json +6 -0
  274. package/genes/tech-lead/.gene-manifest.json +8 -0
  275. package/genes/tech-lead/SKILL.md +451 -0
  276. package/genes/tech-lead/phenotype.json +28 -0
  277. package/genes/test-wrap/.cloud-manifest.json +6 -0
  278. package/genes/test-wrap/.gene-manifest.json +8 -0
  279. package/genes/test-wrap/phenotype.json +28 -0
  280. package/genes/testing-strategist/.cloud-manifest.json +6 -0
  281. package/genes/testing-strategist/.gene-manifest.json +8 -0
  282. package/genes/testing-strategist/SKILL.md +500 -0
  283. package/genes/testing-strategist/phenotype.json +28 -0
  284. package/genes/text-summarizer/.cloud-manifest.json +6 -0
  285. package/genes/text-summarizer/README.md +34 -0
  286. package/genes/text-summarizer/index.ts +122 -0
  287. package/genes/text-summarizer/phenotype.json +32 -0
  288. package/genes/tone-analyzer/.cloud-manifest.json +6 -0
  289. package/genes/tone-analyzer/.gene-manifest.json +8 -0
  290. package/genes/tone-analyzer/SKILL.md +410 -0
  291. package/genes/tone-analyzer/phenotype.json +28 -0
  292. package/genes/translator/.cloud-manifest.json +6 -0
  293. package/genes/translator/.gene-manifest.json +8 -0
  294. package/genes/translator/SKILL.md +355 -0
  295. package/genes/translator/phenotype.json +28 -0
  296. package/genes/ui-components/.cloud-manifest.json +6 -0
  297. package/genes/ui-components/.gene-manifest.json +8 -0
  298. package/genes/ui-components/SKILL.md +467 -0
  299. package/genes/ui-components/phenotype.json +28 -0
  300. package/genes/uiux-designer/.cloud-manifest.json +6 -0
  301. package/genes/uiux-designer/.gene-manifest.json +8 -0
  302. package/genes/uiux-designer/SKILL.md +353 -0
  303. package/genes/uiux-designer/phenotype.json +28 -0
  304. package/genes/url-extractor/.cloud-manifest.json +6 -0
  305. package/genes/url-extractor/README.md +37 -0
  306. package/genes/url-extractor/index.ts +86 -0
  307. package/genes/url-extractor/phenotype.json +48 -0
  308. package/genes/ux-patterns/.cloud-manifest.json +6 -0
  309. package/genes/ux-patterns/.gene-manifest.json +8 -0
  310. package/genes/ux-patterns/SKILL.md +872 -0
  311. package/genes/ux-patterns/phenotype.json +28 -0
  312. package/genes/web3-components/.cloud-manifest.json +6 -0
  313. package/genes/web3-components/.gene-manifest.json +8 -0
  314. package/genes/web3-components/SKILL.md +390 -0
  315. package/genes/web3-components/phenotype.json +28 -0
  316. package/package.json +6 -5
@@ -0,0 +1,486 @@
1
+ interface Particle {
2
+ x: number;
3
+ y: number;
4
+ vx: number;
5
+ vy: number;
6
+ mass: number;
7
+ }
8
+
9
+ interface ParticleInput {
10
+ particles?: Particle[];
11
+ preset?: "solar" | "binary" | "cluster" | "collision";
12
+ count?: number;
13
+ steps?: number;
14
+ dt?: number;
15
+ G?: number;
16
+ softening?: number;
17
+ seed?: number;
18
+ }
19
+
20
+ interface ParticleOutput {
21
+ particles: Particle[];
22
+ steps_computed: number;
23
+ total_energy: number;
24
+ interactions_computed: number;
25
+ }
26
+
27
+ interface QuadNode {
28
+ cx: number;
29
+ cy: number;
30
+ mass: number;
31
+ x: number;
32
+ y: number;
33
+ size: number;
34
+ children: (QuadNode | null)[];
35
+ particleIdx: number;
36
+ particleIndices?: number[];
37
+ }
38
+
39
+ const MIN_CELL_SIZE = 1e-10;
40
+
41
+ function mulberry32(seed: number): () => number {
42
+ let s = seed | 0;
43
+ return () => {
44
+ s = (s + 0x6d2b79f5) | 0;
45
+ let t = Math.imul(s ^ (s >>> 15), 1 | s);
46
+ t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
47
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
48
+ };
49
+ }
50
+
51
+ function generatePreset(
52
+ preset: "solar" | "binary" | "cluster" | "collision",
53
+ count: number,
54
+ seed: number
55
+ ): Particle[] {
56
+ const rng = mulberry32(seed);
57
+ const G = 1.0;
58
+
59
+ switch (preset) {
60
+ case "solar": {
61
+ const particles: Particle[] = [];
62
+ const M_central = 100;
63
+ particles.push({ x: 0, y: 0, vx: 0, vy: 0, mass: M_central });
64
+
65
+ const nOrbiters = Math.min(count - 1, 63);
66
+ for (let i = 0; i < nOrbiters; i++) {
67
+ const r = 2 + rng() * 8;
68
+ const theta = rng() * 2 * Math.PI;
69
+ const x = r * Math.cos(theta);
70
+ const y = r * Math.sin(theta);
71
+ const v = Math.sqrt((G * M_central) / r);
72
+ const vx = -v * Math.sin(theta);
73
+ const vy = v * Math.cos(theta);
74
+ const mass = 0.1 + rng() * 0.9;
75
+ particles.push({ x, y, vx, vy, mass });
76
+ }
77
+ return particles;
78
+ }
79
+
80
+ case "binary": {
81
+ const particles: Particle[] = [];
82
+ const m1 = 50;
83
+ const m2 = 50;
84
+ const d = 4;
85
+ const r1 = (d * m2) / (m1 + m2);
86
+ const r2 = (d * m1) / (m1 + m2);
87
+ const omega = Math.sqrt((G * (m1 + m2)) / (d * d * d));
88
+ const v1 = omega * r1;
89
+ const v2 = omega * r2;
90
+
91
+ particles.push({ x: -r1, y: 0, vx: 0, vy: -v1, mass: m1 });
92
+ particles.push({ x: r2, y: 0, vx: 0, vy: v2, mass: m2 });
93
+
94
+ const nDebris = Math.min(count - 2, 62);
95
+ for (let i = 0; i < nDebris; i++) {
96
+ const r = 6 + rng() * 4;
97
+ const theta = rng() * 2 * Math.PI;
98
+ const x = r * Math.cos(theta);
99
+ const y = r * Math.sin(theta);
100
+ const v = Math.sqrt((G * (m1 + m2)) / r) * (0.8 + rng() * 0.4);
101
+ const vx = -v * Math.sin(theta);
102
+ const vy = v * Math.cos(theta);
103
+ const mass = 0.1 + rng() * 0.5;
104
+ particles.push({ x, y, vx, vy, mass });
105
+ }
106
+ return particles;
107
+ }
108
+
109
+ case "cluster": {
110
+ const particles: Particle[] = [];
111
+ const radius = 5;
112
+ for (let i = 0; i < count; i++) {
113
+ const r = radius * Math.sqrt(rng());
114
+ const theta = rng() * 2 * Math.PI;
115
+ const x = r * Math.cos(theta);
116
+ const y = r * Math.sin(theta);
117
+ const vMax = 0.3;
118
+ const vx = (rng() - 0.5) * 2 * vMax;
119
+ const vy = (rng() - 0.5) * 2 * vMax;
120
+ const mass = 0.5 + rng() * 1.5;
121
+ particles.push({ x, y, vx, vy, mass });
122
+ }
123
+ return particles;
124
+ }
125
+
126
+ case "collision": {
127
+ const particles: Particle[] = [];
128
+ const half = Math.floor(count / 2);
129
+ const sep = 10;
130
+ const vApproach = 1.5;
131
+
132
+ for (let i = 0; i < half; i++) {
133
+ const x = -sep + (rng() - 0.5) * 4;
134
+ const y = (rng() - 0.5) * 4;
135
+ const vx = vApproach + (rng() - 0.5) * 0.4;
136
+ const vy = (rng() - 0.5) * 0.4;
137
+ const mass = 0.5 + rng() * 1.5;
138
+ particles.push({ x, y, vx, vy, mass });
139
+ }
140
+ for (let i = 0; i < count - half; i++) {
141
+ const x = sep + (rng() - 0.5) * 4;
142
+ const y = (rng() - 0.5) * 4;
143
+ const vx = -vApproach + (rng() - 0.5) * 0.4;
144
+ const vy = (rng() - 0.5) * 0.4;
145
+ const mass = 0.5 + rng() * 1.5;
146
+ particles.push({ x, y, vx, vy, mass });
147
+ }
148
+ return particles;
149
+ }
150
+
151
+ default:
152
+ return generatePreset("cluster", count, seed);
153
+ }
154
+ }
155
+
156
+ function createEmptyNode(x: number, y: number, size: number): QuadNode {
157
+ return {
158
+ cx: 0,
159
+ cy: 0,
160
+ mass: 0,
161
+ x,
162
+ y,
163
+ size,
164
+ children: [null, null, null, null],
165
+ particleIdx: -1,
166
+ };
167
+ }
168
+
169
+ function getQuadrant(px: number, py: number, cx: number, cy: number): number {
170
+ if (px < cx) {
171
+ return py < cy ? 0 : 2;
172
+ }
173
+ return py < cy ? 1 : 3;
174
+ }
175
+
176
+ function insertParticle(
177
+ node: QuadNode,
178
+ particles: Particle[],
179
+ idx: number
180
+ ): void {
181
+ const p = particles[idx];
182
+ const half = node.size / 2;
183
+
184
+ if (half < MIN_CELL_SIZE) {
185
+ if (node.particleIdx >= 0) {
186
+ node.particleIndices = [node.particleIdx];
187
+ node.particleIdx = -1;
188
+ }
189
+ if (!node.particleIndices) node.particleIndices = [];
190
+ node.particleIndices.push(idx);
191
+ return;
192
+ }
193
+
194
+ if (node.particleIdx >= 0) {
195
+ const existing = particles[node.particleIdx];
196
+ const q = getQuadrant(existing.x, existing.y, node.x, node.y);
197
+ const child = createEmptyNode(
198
+ node.x + (q === 0 || q === 2 ? -half / 2 : half / 2),
199
+ node.y + (q < 2 ? -half / 2 : half / 2),
200
+ half
201
+ );
202
+ insertParticle(child, particles, node.particleIdx);
203
+ node.children[q] = child;
204
+ node.particleIdx = -1;
205
+ }
206
+
207
+ const q = getQuadrant(p.x, p.y, node.x, node.y);
208
+ let child = node.children[q];
209
+
210
+ if (child === null) {
211
+ child = createEmptyNode(
212
+ node.x + (q === 0 || q === 2 ? -half / 2 : half / 2),
213
+ node.y + (q < 2 ? -half / 2 : half / 2),
214
+ half
215
+ );
216
+ child.particleIdx = idx;
217
+ child.cx = p.x;
218
+ child.cy = p.y;
219
+ child.mass = p.mass;
220
+ node.children[q] = child;
221
+ } else {
222
+ insertParticle(child, particles, idx);
223
+ }
224
+ }
225
+
226
+ function computeCenterOfMass(node: QuadNode, particles: Particle[]): void {
227
+ if (node.particleIdx >= 0) {
228
+ const p = particles[node.particleIdx];
229
+ node.cx = p.x;
230
+ node.cy = p.y;
231
+ node.mass = p.mass;
232
+ return;
233
+ }
234
+
235
+ if (node.particleIndices && node.particleIndices.length > 0) {
236
+ let totalMass = 0;
237
+ let sumX = 0;
238
+ let sumY = 0;
239
+ for (const i of node.particleIndices) {
240
+ const p = particles[i];
241
+ totalMass += p.mass;
242
+ sumX += p.x * p.mass;
243
+ sumY += p.y * p.mass;
244
+ }
245
+ if (totalMass > 0) {
246
+ node.cx = sumX / totalMass;
247
+ node.cy = sumY / totalMass;
248
+ }
249
+ node.mass = totalMass;
250
+ return;
251
+ }
252
+
253
+ let totalMass = 0;
254
+ let sumX = 0;
255
+ let sumY = 0;
256
+
257
+ for (const c of node.children) {
258
+ if (c !== null) {
259
+ computeCenterOfMass(c, particles);
260
+ totalMass += c.mass;
261
+ sumX += c.cx * c.mass;
262
+ sumY += c.cy * c.mass;
263
+ }
264
+ }
265
+
266
+ if (totalMass > 0) {
267
+ node.cx = sumX / totalMass;
268
+ node.cy = sumY / totalMass;
269
+ }
270
+ node.mass = totalMass;
271
+ }
272
+
273
+ const THETA = 0.5;
274
+
275
+ function computeForce(
276
+ node: QuadNode,
277
+ particles: Particle[],
278
+ idx: number,
279
+ G: number,
280
+ softening: number,
281
+ ax: Float64Array,
282
+ ay: Float64Array,
283
+ interactions: { count: number }
284
+ ): void {
285
+ const p = particles[idx];
286
+ const dx = node.cx - p.x;
287
+ const dy = node.cy - p.y;
288
+ const rSq = dx * dx + dy * dy + softening * softening;
289
+ const r = Math.sqrt(rSq);
290
+
291
+ if (node.particleIdx >= 0) {
292
+ if (node.particleIdx === idx) return;
293
+ const factor = (G * node.mass) / Math.pow(rSq, 1.5);
294
+ ax[idx] += factor * dx;
295
+ ay[idx] += factor * dy;
296
+ interactions.count += 1;
297
+ return;
298
+ }
299
+
300
+ if (node.particleIndices && node.particleIndices.length > 0) {
301
+ for (const j of node.particleIndices) {
302
+ if (j === idx) continue;
303
+ const pj = particles[j];
304
+ const dxj = pj.x - p.x;
305
+ const dyj = pj.y - p.y;
306
+ const rSqj = dxj * dxj + dyj * dyj + softening * softening;
307
+ const factor = (G * pj.mass) / Math.pow(rSqj, 1.5);
308
+ ax[idx] += factor * dxj;
309
+ ay[idx] += factor * dyj;
310
+ interactions.count += 1;
311
+ }
312
+ return;
313
+ }
314
+
315
+ const ratio = node.size / (r + 1e-10);
316
+
317
+ if (ratio < THETA) {
318
+ const factor = (G * node.mass) / Math.pow(rSq, 1.5);
319
+ ax[idx] += factor * dx;
320
+ ay[idx] += factor * dy;
321
+ interactions.count += 1;
322
+ return;
323
+ }
324
+
325
+ for (const c of node.children) {
326
+ if (c !== null && c.mass > 0) {
327
+ computeForce(c, particles, idx, G, softening, ax, ay, interactions);
328
+ }
329
+ }
330
+ }
331
+
332
+ function computeTotalEnergy(
333
+ particles: Particle[],
334
+ G: number,
335
+ softening: number
336
+ ): number {
337
+ let kinetic = 0;
338
+ let potential = 0;
339
+ const n = particles.length;
340
+
341
+ for (let i = 0; i < n; i++) {
342
+ const p = particles[i];
343
+ kinetic += 0.5 * p.mass * (p.vx * p.vx + p.vy * p.vy);
344
+ }
345
+
346
+ for (let i = 0; i < n; i++) {
347
+ for (let j = i + 1; j < n; j++) {
348
+ const pi = particles[i];
349
+ const pj = particles[j];
350
+ const dx = pj.x - pi.x;
351
+ const dy = pj.y - pi.y;
352
+ const rSq = dx * dx + dy * dy + softening * softening;
353
+ const r = Math.sqrt(rSq);
354
+ potential -= (G * pi.mass * pj.mass) / r;
355
+ }
356
+ }
357
+
358
+ return kinetic + potential;
359
+ }
360
+
361
+ export async function express(input: ParticleInput): Promise<ParticleOutput> {
362
+ const count = Math.max(2, Math.min(2048, input.count ?? 64));
363
+ const steps = Math.max(1, Math.min(10000, input.steps ?? 100));
364
+ const dt = input.dt ?? 0.01;
365
+ const G = input.G ?? 1.0;
366
+ const softening = input.softening ?? 0.01;
367
+ const seed = input.seed ?? 42;
368
+
369
+ let particles: Particle[];
370
+
371
+ if (input.particles && input.particles.length > 0) {
372
+ particles = input.particles.map((p) => ({
373
+ x: p.x,
374
+ y: p.y,
375
+ vx: p.vx,
376
+ vy: p.vy,
377
+ mass: p.mass,
378
+ }));
379
+ } else {
380
+ const preset = input.preset ?? "cluster";
381
+ particles = generatePreset(preset, count, seed);
382
+ }
383
+
384
+ const n = particles.length;
385
+ const ax = new Float64Array(n);
386
+ const ay = new Float64Array(n);
387
+ let interactionsComputed = 0;
388
+ const margin = 0.1;
389
+
390
+ for (let stepIdx = 0; stepIdx < steps; stepIdx++) {
391
+ let minX = Infinity;
392
+ let maxX = -Infinity;
393
+ let minY = Infinity;
394
+ let maxY = -Infinity;
395
+
396
+ for (let i = 0; i < n; i++) {
397
+ const p = particles[i];
398
+ if (p.x < minX) minX = p.x;
399
+ if (p.x > maxX) maxX = p.x;
400
+ if (p.y < minY) minY = p.y;
401
+ if (p.y > maxY) maxY = p.y;
402
+ }
403
+
404
+ const size = Math.max(maxX - minX, maxY - minY, 1) / 2 + margin;
405
+ const root = createEmptyNode(
406
+ (minX + maxX) / 2,
407
+ (minY + maxY) / 2,
408
+ size
409
+ );
410
+
411
+ for (let i = 0; i < n; i++) {
412
+ insertParticle(root, particles, i);
413
+ }
414
+ computeCenterOfMass(root, particles);
415
+
416
+ ax.fill(0);
417
+ ay.fill(0);
418
+ const interactions = { count: 0 };
419
+
420
+ for (let i = 0; i < n; i++) {
421
+ computeForce(root, particles, i, G, softening, ax, ay, interactions);
422
+ }
423
+ interactionsComputed += interactions.count;
424
+
425
+ for (let i = 0; i < n; i++) {
426
+ const p = particles[i];
427
+ p.vx += 0.5 * dt * ax[i];
428
+ p.vy += 0.5 * dt * ay[i];
429
+ }
430
+
431
+ for (let i = 0; i < n; i++) {
432
+ const p = particles[i];
433
+ p.x += dt * p.vx;
434
+ p.y += dt * p.vy;
435
+ }
436
+
437
+ minX = Infinity;
438
+ maxX = -Infinity;
439
+ minY = Infinity;
440
+ maxY = -Infinity;
441
+
442
+ for (let i = 0; i < n; i++) {
443
+ const p = particles[i];
444
+ if (p.x < minX) minX = p.x;
445
+ if (p.x > maxX) maxX = p.x;
446
+ if (p.y < minY) minY = p.y;
447
+ if (p.y > maxY) maxY = p.y;
448
+ }
449
+
450
+ const size2 = Math.max(maxX - minX, maxY - minY, 1) / 2 + margin;
451
+ const root2 = createEmptyNode(
452
+ (minX + maxX) / 2,
453
+ (minY + maxY) / 2,
454
+ size2
455
+ );
456
+
457
+ for (let i = 0; i < n; i++) {
458
+ insertParticle(root2, particles, i);
459
+ }
460
+ computeCenterOfMass(root2, particles);
461
+
462
+ ax.fill(0);
463
+ ay.fill(0);
464
+ const interactions2 = { count: 0 };
465
+
466
+ for (let i = 0; i < n; i++) {
467
+ computeForce(root2, particles, i, G, softening, ax, ay, interactions2);
468
+ }
469
+ interactionsComputed += interactions2.count;
470
+
471
+ for (let i = 0; i < n; i++) {
472
+ const p = particles[i];
473
+ p.vx += 0.5 * dt * ax[i];
474
+ p.vy += 0.5 * dt * ay[i];
475
+ }
476
+ }
477
+
478
+ const totalEnergy = computeTotalEnergy(particles, G, softening);
479
+
480
+ return {
481
+ particles,
482
+ steps_computed: steps,
483
+ total_energy: totalEnergy,
484
+ interactions_computed: interactionsComputed,
485
+ };
486
+ }
@@ -0,0 +1,137 @@
1
+ {
2
+ "domain": "sim.particle",
3
+ "description": "N-body gravitational simulation using Barnes-Hut quadtree approximation. Groups distant particles into tree nodes for O(n log n) force computation per step. Balances accuracy and speed via configurable opening angle theta.",
4
+ "inputSchema": {
5
+ "type": "object",
6
+ "properties": {
7
+ "particles": {
8
+ "type": "array",
9
+ "description": "Initial particle states. Ignored if preset is provided.",
10
+ "items": {
11
+ "type": "object",
12
+ "properties": {
13
+ "x": {
14
+ "type": "number"
15
+ },
16
+ "y": {
17
+ "type": "number"
18
+ },
19
+ "vx": {
20
+ "type": "number"
21
+ },
22
+ "vy": {
23
+ "type": "number"
24
+ },
25
+ "mass": {
26
+ "type": "number"
27
+ }
28
+ },
29
+ "required": [
30
+ "x",
31
+ "y",
32
+ "vx",
33
+ "vy",
34
+ "mass"
35
+ ]
36
+ }
37
+ },
38
+ "preset": {
39
+ "type": "string",
40
+ "description": "Preset particle configuration",
41
+ "enum": [
42
+ "solar",
43
+ "binary",
44
+ "cluster",
45
+ "collision"
46
+ ]
47
+ },
48
+ "count": {
49
+ "type": "number",
50
+ "description": "Number of particles for preset generation",
51
+ "default": 64,
52
+ "minimum": 2,
53
+ "maximum": 2048
54
+ },
55
+ "steps": {
56
+ "type": "number",
57
+ "description": "Number of simulation steps",
58
+ "default": 100,
59
+ "minimum": 1,
60
+ "maximum": 10000
61
+ },
62
+ "dt": {
63
+ "type": "number",
64
+ "description": "Time step size",
65
+ "default": 0.01
66
+ },
67
+ "G": {
68
+ "type": "number",
69
+ "description": "Gravitational constant",
70
+ "default": 1
71
+ },
72
+ "softening": {
73
+ "type": "number",
74
+ "description": "Softening parameter to prevent singularity at close range",
75
+ "default": 0.01
76
+ },
77
+ "seed": {
78
+ "type": "number",
79
+ "description": "Random seed for preset generation (deterministic output)"
80
+ }
81
+ },
82
+ "required": []
83
+ },
84
+ "outputSchema": {
85
+ "type": "object",
86
+ "properties": {
87
+ "particles": {
88
+ "type": "array",
89
+ "description": "Final particle states after simulation",
90
+ "items": {
91
+ "type": "object",
92
+ "properties": {
93
+ "x": {
94
+ "type": "number"
95
+ },
96
+ "y": {
97
+ "type": "number"
98
+ },
99
+ "vx": {
100
+ "type": "number"
101
+ },
102
+ "vy": {
103
+ "type": "number"
104
+ },
105
+ "mass": {
106
+ "type": "number"
107
+ }
108
+ }
109
+ }
110
+ },
111
+ "steps_computed": {
112
+ "type": "number",
113
+ "description": "Actual number of simulation steps computed"
114
+ },
115
+ "total_energy": {
116
+ "type": "number",
117
+ "description": "Total system energy (kinetic + potential) at final state"
118
+ },
119
+ "interactions_computed": {
120
+ "type": "number",
121
+ "description": "Total pairwise force evaluations across all steps"
122
+ }
123
+ },
124
+ "required": [
125
+ "particles",
126
+ "steps_computed",
127
+ "total_energy",
128
+ "interactions_computed"
129
+ ]
130
+ },
131
+ "dependencies": [],
132
+ "version": "0.1.0",
133
+ "author": "rotifer-team",
134
+ "fidelity": "Native",
135
+ "transparency": "Open",
136
+ "ir_hash": "391614d239e64ad94d257ec59c079a1a060d0143b28f6edd8ec255858f961d1c"
137
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "cloud_id": "30e35b9b-a377-4a2b-a7eb-fce16f379941",
3
+ "owner": "Rotifer Protocol",
4
+ "version": "0.1.0",
5
+ "published_at": "2026-03-17T14:13:16.873Z"
6
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "geneId": "0ec8e0410da37367e5a3fbacdfbb53e44f22da0741bc538eeef819d728a4305c",
3
+ "name": "particle-brute",
4
+ "domain": "sim.particle",
5
+ "compiledAt": "2026-03-14T09:13:33.395Z",
6
+ "fidelity": "Native",
7
+ "wasmAvailable": true,
8
+ "irHash": "391614d239e64ad94d257ec59c079a1a060d0143b28f6edd8ec255858f961d1c",
9
+ "totalSize": 1295630,
10
+ "codeSectionSize": 956115,
11
+ "durationMs": 6609
12
+ }
@@ -0,0 +1,55 @@
1
+ # particle-brute
2
+
3
+ Brute-force N-body gravitational simulation — a pure-computation Native Gene for the Rotifer Protocol.
4
+
5
+ ## Algorithm
6
+
7
+ All-pairs direct summation with O(n²) complexity per step. For each pair of particles (i, j), computes the exact gravitational force using Newton's law with a softening parameter to prevent singularities:
8
+
9
+ ```
10
+ F = G × m_i × m_j × r̂ / (|r|² + ε²)^(3/2)
11
+ ```
12
+
13
+ Integration uses the symplectic leapfrog (kick-drift-kick) scheme for energy conservation.
14
+
15
+ This is the **accuracy baseline** — every pairwise interaction is computed exactly, making it ideal for validating approximation-based algorithms like Barnes-Hut or spatial hashing.
16
+
17
+ ## Usage
18
+
19
+ ```bash
20
+ # Solar system preset (64 particles, 100 steps)
21
+ rotifer run particle-brute --input '{"preset": "solar"}'
22
+
23
+ # Cluster collision (128 particles, 500 steps)
24
+ rotifer run particle-brute --input '{"preset": "collision", "count": 128, "steps": 500}'
25
+
26
+ # Custom particles
27
+ rotifer run particle-brute --input '{"particles": [{"x":0,"y":0,"vx":0,"vy":0,"mass":100}, {"x":5,"y":0,"vx":0,"vy":4.47,"mass":1}]}'
28
+ ```
29
+
30
+ ## Presets
31
+
32
+ | Preset | Description |
33
+ |--------|-------------|
34
+ | `solar` | Central massive body + orbiting lighter bodies with circular velocities |
35
+ | `binary` | Two equal-mass stars in mutual orbit + debris ring |
36
+ | `cluster` | Random particles in a disk with small random velocities |
37
+ | `collision` | Two groups of particles approaching head-on |
38
+
39
+ ## Output
40
+
41
+ - `particles` — final positions and velocities of all particles
42
+ - `steps_computed` — number of simulation steps executed
43
+ - `total_energy` — total system energy (kinetic + potential) for conservation validation
44
+ - `interactions_computed` — total force evaluations (n(n-1)/2 × 2 × steps for kick-drift-kick)
45
+
46
+ ## Fitness Characteristics
47
+
48
+ | Metric | Expected |
49
+ |--------|----------|
50
+ | Success Rate | 1.0 (deterministic, no failure mode) |
51
+ | Accuracy | Exact (machine-precision pairwise forces) |
52
+ | Complexity | O(n² × steps) |
53
+ | Interactions | n(n-1) × steps |
54
+ | Best For | Small N (≤256), accuracy benchmarks |
55
+ | Weakness | Scales poorly for large N |
Binary file