@kernel.chat/kbot 3.61.8 → 3.63.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 (648) hide show
  1. package/README.md +275 -1
  2. package/dist/agent.js +4 -1
  3. package/dist/cli.js +75 -1
  4. package/dist/dream.d.ts +66 -0
  5. package/dist/dream.js +377 -0
  6. package/dist/tools/dream-tools.d.ts +2 -0
  7. package/dist/tools/dream-tools.js +159 -0
  8. package/dist/tools/index.js +1 -0
  9. package/ollama-manifest.json +1 -1
  10. package/package.json +9 -122
  11. package/dist/a2a-client.d.ts.map +0 -1
  12. package/dist/a2a-client.js.map +0 -1
  13. package/dist/a2a.d.ts.map +0 -1
  14. package/dist/a2a.js.map +0 -1
  15. package/dist/agent-create.d.ts.map +0 -1
  16. package/dist/agent-create.js.map +0 -1
  17. package/dist/agent-protocol.d.ts.map +0 -1
  18. package/dist/agent-protocol.js.map +0 -1
  19. package/dist/agent-protocol.test.d.ts +0 -2
  20. package/dist/agent-protocol.test.d.ts.map +0 -1
  21. package/dist/agent-protocol.test.js +0 -730
  22. package/dist/agent-protocol.test.js.map +0 -1
  23. package/dist/agent-teams.d.ts.map +0 -1
  24. package/dist/agent-teams.js.map +0 -1
  25. package/dist/agent.d.ts.map +0 -1
  26. package/dist/agent.js.map +0 -1
  27. package/dist/agents/agents.test.d.ts +0 -2
  28. package/dist/agents/agents.test.d.ts.map +0 -1
  29. package/dist/agents/agents.test.js +0 -127
  30. package/dist/agents/agents.test.js.map +0 -1
  31. package/dist/agents/creative.d.ts.map +0 -1
  32. package/dist/agents/creative.js.map +0 -1
  33. package/dist/agents/developer.d.ts.map +0 -1
  34. package/dist/agents/developer.js.map +0 -1
  35. package/dist/agents/gamedev.d.ts.map +0 -1
  36. package/dist/agents/gamedev.js.map +0 -1
  37. package/dist/agents/playtester.d.ts.map +0 -1
  38. package/dist/agents/playtester.js.map +0 -1
  39. package/dist/agents/producer.d.ts.map +0 -1
  40. package/dist/agents/producer.js.map +0 -1
  41. package/dist/agents/replit.d.ts.map +0 -1
  42. package/dist/agents/replit.js.map +0 -1
  43. package/dist/agents/specialists.d.ts.map +0 -1
  44. package/dist/agents/specialists.js.map +0 -1
  45. package/dist/agents/trader.d.ts.map +0 -1
  46. package/dist/agents/trader.js.map +0 -1
  47. package/dist/architect.d.ts.map +0 -1
  48. package/dist/architect.js.map +0 -1
  49. package/dist/auth.d.ts.map +0 -1
  50. package/dist/auth.js.map +0 -1
  51. package/dist/auth.test.d.ts +0 -2
  52. package/dist/auth.test.d.ts.map +0 -1
  53. package/dist/auth.test.js +0 -87
  54. package/dist/auth.test.js.map +0 -1
  55. package/dist/automations.d.ts.map +0 -1
  56. package/dist/automations.js.map +0 -1
  57. package/dist/autonomous-contributor.d.ts.map +0 -1
  58. package/dist/autonomous-contributor.js.map +0 -1
  59. package/dist/autopoiesis.d.ts.map +0 -1
  60. package/dist/autopoiesis.js.map +0 -1
  61. package/dist/behaviour.d.ts.map +0 -1
  62. package/dist/behaviour.js.map +0 -1
  63. package/dist/bench.d.ts.map +0 -1
  64. package/dist/bench.js.map +0 -1
  65. package/dist/bootstrap.d.ts.map +0 -1
  66. package/dist/bootstrap.js.map +0 -1
  67. package/dist/briefing.d.ts.map +0 -1
  68. package/dist/briefing.js.map +0 -1
  69. package/dist/build-targets.d.ts.map +0 -1
  70. package/dist/build-targets.js.map +0 -1
  71. package/dist/changelog.d.ts.map +0 -1
  72. package/dist/changelog.js.map +0 -1
  73. package/dist/channels/kbot-channel.d.ts.map +0 -1
  74. package/dist/channels/kbot-channel.js.map +0 -1
  75. package/dist/checkpoint.d.ts.map +0 -1
  76. package/dist/checkpoint.js.map +0 -1
  77. package/dist/cli.d.ts.map +0 -1
  78. package/dist/cli.js.map +0 -1
  79. package/dist/cloud-agent.d.ts.map +0 -1
  80. package/dist/cloud-agent.js.map +0 -1
  81. package/dist/cloud-sync.d.ts.map +0 -1
  82. package/dist/cloud-sync.js.map +0 -1
  83. package/dist/codebase-guardian.d.ts.map +0 -1
  84. package/dist/codebase-guardian.js.map +0 -1
  85. package/dist/collective-learning.d.ts.map +0 -1
  86. package/dist/collective-learning.js.map +0 -1
  87. package/dist/collective-network.d.ts.map +0 -1
  88. package/dist/collective-network.js.map +0 -1
  89. package/dist/collective.d.ts.map +0 -1
  90. package/dist/collective.js.map +0 -1
  91. package/dist/community-autopilot.d.ts.map +0 -1
  92. package/dist/community-autopilot.js.map +0 -1
  93. package/dist/community-manager.d.ts.map +0 -1
  94. package/dist/community-manager.js.map +0 -1
  95. package/dist/compete.d.ts.map +0 -1
  96. package/dist/compete.js.map +0 -1
  97. package/dist/completions.d.ts.map +0 -1
  98. package/dist/completions.js.map +0 -1
  99. package/dist/confidence.d.ts.map +0 -1
  100. package/dist/confidence.js.map +0 -1
  101. package/dist/consultation.d.ts.map +0 -1
  102. package/dist/consultation.js.map +0 -1
  103. package/dist/consultation.test.d.ts +0 -2
  104. package/dist/consultation.test.d.ts.map +0 -1
  105. package/dist/consultation.test.js +0 -86
  106. package/dist/consultation.test.js.map +0 -1
  107. package/dist/context-manager.d.ts.map +0 -1
  108. package/dist/context-manager.js.map +0 -1
  109. package/dist/context-manager.test.d.ts +0 -2
  110. package/dist/context-manager.test.d.ts.map +0 -1
  111. package/dist/context-manager.test.js +0 -121
  112. package/dist/context-manager.test.js.map +0 -1
  113. package/dist/context.d.ts.map +0 -1
  114. package/dist/context.js.map +0 -1
  115. package/dist/context.test.d.ts +0 -2
  116. package/dist/context.test.d.ts.map +0 -1
  117. package/dist/context.test.js +0 -561
  118. package/dist/context.test.js.map +0 -1
  119. package/dist/cross-device-sync.d.ts.map +0 -1
  120. package/dist/cross-device-sync.js.map +0 -1
  121. package/dist/daemon.d.ts.map +0 -1
  122. package/dist/daemon.js.map +0 -1
  123. package/dist/dashboard.d.ts.map +0 -1
  124. package/dist/dashboard.js.map +0 -1
  125. package/dist/decision-journal.d.ts.map +0 -1
  126. package/dist/decision-journal.js.map +0 -1
  127. package/dist/digest.d.ts.map +0 -1
  128. package/dist/digest.js.map +0 -1
  129. package/dist/discovery.d.ts.map +0 -1
  130. package/dist/discovery.js.map +0 -1
  131. package/dist/doctor.d.ts.map +0 -1
  132. package/dist/doctor.js.map +0 -1
  133. package/dist/doctor.test.d.ts +0 -2
  134. package/dist/doctor.test.d.ts.map +0 -1
  135. package/dist/doctor.test.js +0 -432
  136. package/dist/doctor.test.js.map +0 -1
  137. package/dist/dream-mode.d.ts.map +0 -1
  138. package/dist/dream-mode.js.map +0 -1
  139. package/dist/email-agent.d.ts.map +0 -1
  140. package/dist/email-agent.js.map +0 -1
  141. package/dist/email-service.d.ts.map +0 -1
  142. package/dist/email-service.js.map +0 -1
  143. package/dist/embeddings.d.ts.map +0 -1
  144. package/dist/embeddings.js.map +0 -1
  145. package/dist/emergent-swarm.d.ts.map +0 -1
  146. package/dist/emergent-swarm.js.map +0 -1
  147. package/dist/entropy-context.d.ts.map +0 -1
  148. package/dist/entropy-context.js.map +0 -1
  149. package/dist/episodic-memory.d.ts.map +0 -1
  150. package/dist/episodic-memory.js.map +0 -1
  151. package/dist/error-correction.d.ts.map +0 -1
  152. package/dist/error-correction.js.map +0 -1
  153. package/dist/evolution.d.ts.map +0 -1
  154. package/dist/evolution.js.map +0 -1
  155. package/dist/evolution.test.d.ts +0 -2
  156. package/dist/evolution.test.d.ts.map +0 -1
  157. package/dist/evolution.test.js +0 -160
  158. package/dist/evolution.test.js.map +0 -1
  159. package/dist/export.d.ts.map +0 -1
  160. package/dist/export.js.map +0 -1
  161. package/dist/forge-marketplace-server.d.ts.map +0 -1
  162. package/dist/forge-marketplace-server.js.map +0 -1
  163. package/dist/forge-marketplace.d.ts.map +0 -1
  164. package/dist/forge-marketplace.js.map +0 -1
  165. package/dist/forge-registry.d.ts.map +0 -1
  166. package/dist/forge-registry.js.map +0 -1
  167. package/dist/free-energy.d.ts.map +0 -1
  168. package/dist/free-energy.js.map +0 -1
  169. package/dist/gitagent-export.d.ts.map +0 -1
  170. package/dist/gitagent-export.js.map +0 -1
  171. package/dist/github-release.d.ts.map +0 -1
  172. package/dist/github-release.js.map +0 -1
  173. package/dist/godel-limits.d.ts.map +0 -1
  174. package/dist/godel-limits.js.map +0 -1
  175. package/dist/graph-memory.d.ts.map +0 -1
  176. package/dist/graph-memory.js.map +0 -1
  177. package/dist/graph-memory.test.d.ts +0 -2
  178. package/dist/graph-memory.test.d.ts.map +0 -1
  179. package/dist/graph-memory.test.js +0 -946
  180. package/dist/graph-memory.test.js.map +0 -1
  181. package/dist/guardrails.d.ts.map +0 -1
  182. package/dist/guardrails.js.map +0 -1
  183. package/dist/handoffs.d.ts.map +0 -1
  184. package/dist/handoffs.js.map +0 -1
  185. package/dist/hooks-integration.d.ts.map +0 -1
  186. package/dist/hooks-integration.js.map +0 -1
  187. package/dist/hooks.d.ts.map +0 -1
  188. package/dist/hooks.js.map +0 -1
  189. package/dist/ide/acp-server.d.ts.map +0 -1
  190. package/dist/ide/acp-server.js.map +0 -1
  191. package/dist/ide/bridge.d.ts.map +0 -1
  192. package/dist/ide/bridge.js.map +0 -1
  193. package/dist/ide/index.d.ts.map +0 -1
  194. package/dist/ide/index.js.map +0 -1
  195. package/dist/ide/lsp-bridge.d.ts.map +0 -1
  196. package/dist/ide/lsp-bridge.js.map +0 -1
  197. package/dist/ide/mcp-server.d.ts.map +0 -1
  198. package/dist/ide/mcp-server.js.map +0 -1
  199. package/dist/imessage-agent.d.ts.map +0 -1
  200. package/dist/imessage-agent.js.map +0 -1
  201. package/dist/inference.d.ts.map +0 -1
  202. package/dist/inference.js.map +0 -1
  203. package/dist/init-science.d.ts.map +0 -1
  204. package/dist/init-science.js.map +0 -1
  205. package/dist/init.d.ts.map +0 -1
  206. package/dist/init.js.map +0 -1
  207. package/dist/init.test.d.ts +0 -2
  208. package/dist/init.test.d.ts.map +0 -1
  209. package/dist/init.test.js +0 -91
  210. package/dist/init.test.js.map +0 -1
  211. package/dist/integrated-information.d.ts.map +0 -1
  212. package/dist/integrated-information.js.map +0 -1
  213. package/dist/integrations/ableton-live.d.ts.map +0 -1
  214. package/dist/integrations/ableton-live.js.map +0 -1
  215. package/dist/integrations/ableton-m4l.d.ts.map +0 -1
  216. package/dist/integrations/ableton-m4l.js.map +0 -1
  217. package/dist/integrations/ableton-osc-installer.d.ts.map +0 -1
  218. package/dist/integrations/ableton-osc-installer.js.map +0 -1
  219. package/dist/integrations/ableton-osc.d.ts.map +0 -1
  220. package/dist/integrations/ableton-osc.js.map +0 -1
  221. package/dist/integrations/openclaw/plugin.d.ts.map +0 -1
  222. package/dist/integrations/openclaw/plugin.js.map +0 -1
  223. package/dist/intentionality.d.ts.map +0 -1
  224. package/dist/intentionality.js.map +0 -1
  225. package/dist/interactive-buttons.d.ts.map +0 -1
  226. package/dist/interactive-buttons.js.map +0 -1
  227. package/dist/interference.d.ts.map +0 -1
  228. package/dist/interference.js.map +0 -1
  229. package/dist/introspection.d.ts.map +0 -1
  230. package/dist/introspection.js.map +0 -1
  231. package/dist/kbot-service.d.ts.map +0 -1
  232. package/dist/kbot-service.js.map +0 -1
  233. package/dist/knowledge-base.d.ts.map +0 -1
  234. package/dist/knowledge-base.js.map +0 -1
  235. package/dist/lab.d.ts.map +0 -1
  236. package/dist/lab.js.map +0 -1
  237. package/dist/learned-router.d.ts.map +0 -1
  238. package/dist/learned-router.js.map +0 -1
  239. package/dist/learning.d.ts.map +0 -1
  240. package/dist/learning.js.map +0 -1
  241. package/dist/learning.test.d.ts +0 -2
  242. package/dist/learning.test.d.ts.map +0 -1
  243. package/dist/learning.test.js +0 -106
  244. package/dist/learning.test.js.map +0 -1
  245. package/dist/lsp-client.d.ts.map +0 -1
  246. package/dist/lsp-client.js.map +0 -1
  247. package/dist/lsp-deep.d.ts.map +0 -1
  248. package/dist/lsp-deep.js.map +0 -1
  249. package/dist/machine.d.ts.map +0 -1
  250. package/dist/machine.js.map +0 -1
  251. package/dist/marketplace.d.ts.map +0 -1
  252. package/dist/marketplace.js.map +0 -1
  253. package/dist/matrix.d.ts.map +0 -1
  254. package/dist/matrix.js.map +0 -1
  255. package/dist/mcp-apps.d.ts.map +0 -1
  256. package/dist/mcp-apps.js.map +0 -1
  257. package/dist/mcp-plugins.d.ts.map +0 -1
  258. package/dist/mcp-plugins.js.map +0 -1
  259. package/dist/memory-hotswap.d.ts.map +0 -1
  260. package/dist/memory-hotswap.js.map +0 -1
  261. package/dist/memory-synthesis.d.ts.map +0 -1
  262. package/dist/memory-synthesis.js.map +0 -1
  263. package/dist/memory-synthesis.test.d.ts +0 -2
  264. package/dist/memory-synthesis.test.d.ts.map +0 -1
  265. package/dist/memory-synthesis.test.js +0 -83
  266. package/dist/memory-synthesis.test.js.map +0 -1
  267. package/dist/memory.d.ts.map +0 -1
  268. package/dist/memory.js.map +0 -1
  269. package/dist/memory.test.d.ts +0 -2
  270. package/dist/memory.test.d.ts.map +0 -1
  271. package/dist/memory.test.js +0 -450
  272. package/dist/memory.test.js.map +0 -1
  273. package/dist/meta-agent.d.ts.map +0 -1
  274. package/dist/meta-agent.js.map +0 -1
  275. package/dist/migrate.d.ts.map +0 -1
  276. package/dist/migrate.js.map +0 -1
  277. package/dist/multi-session.d.ts.map +0 -1
  278. package/dist/multi-session.js.map +0 -1
  279. package/dist/multimodal.d.ts.map +0 -1
  280. package/dist/multimodal.js.map +0 -1
  281. package/dist/music-learning.d.ts.map +0 -1
  282. package/dist/music-learning.js.map +0 -1
  283. package/dist/notifications.d.ts.map +0 -1
  284. package/dist/notifications.js.map +0 -1
  285. package/dist/observer.d.ts.map +0 -1
  286. package/dist/observer.js.map +0 -1
  287. package/dist/openclaw-connect.d.ts.map +0 -1
  288. package/dist/openclaw-connect.js.map +0 -1
  289. package/dist/packages/kbot/src/tools/mcp-client.d.ts.map +0 -1
  290. package/dist/packages/kbot/src/tools/mcp-client.js.map +0 -1
  291. package/dist/packages/kbot/src/tools/mcp-discovery.d.ts.map +0 -1
  292. package/dist/packages/kbot/src/tools/mcp-discovery.js.map +0 -1
  293. package/dist/packages/kbot/src/tools/memory-harness.d.ts.map +0 -1
  294. package/dist/packages/kbot/src/tools/memory-harness.js.map +0 -1
  295. package/dist/pair.d.ts.map +0 -1
  296. package/dist/pair.js.map +0 -1
  297. package/dist/pattern-feed.d.ts.map +0 -1
  298. package/dist/pattern-feed.js.map +0 -1
  299. package/dist/permissions.d.ts.map +0 -1
  300. package/dist/permissions.js.map +0 -1
  301. package/dist/personal-security.d.ts.map +0 -1
  302. package/dist/personal-security.js.map +0 -1
  303. package/dist/planner.d.ts.map +0 -1
  304. package/dist/planner.js.map +0 -1
  305. package/dist/plugin/index.d.ts.map +0 -1
  306. package/dist/plugin/index.js.map +0 -1
  307. package/dist/plugin-sdk.d.ts.map +0 -1
  308. package/dist/plugin-sdk.js.map +0 -1
  309. package/dist/plugins.d.ts.map +0 -1
  310. package/dist/plugins.js.map +0 -1
  311. package/dist/predictive-processing.d.ts.map +0 -1
  312. package/dist/predictive-processing.js.map +0 -1
  313. package/dist/privacy-router.d.ts.map +0 -1
  314. package/dist/privacy-router.js.map +0 -1
  315. package/dist/prompt-cache.d.ts.map +0 -1
  316. package/dist/prompt-cache.js.map +0 -1
  317. package/dist/prompt-evolution.d.ts.map +0 -1
  318. package/dist/prompt-evolution.js.map +0 -1
  319. package/dist/provider-fallback.d.ts.map +0 -1
  320. package/dist/provider-fallback.js.map +0 -1
  321. package/dist/quality-diversity.d.ts.map +0 -1
  322. package/dist/quality-diversity.js.map +0 -1
  323. package/dist/rate-limiter.d.ts.map +0 -1
  324. package/dist/rate-limiter.js.map +0 -1
  325. package/dist/reasoning.d.ts.map +0 -1
  326. package/dist/reasoning.js.map +0 -1
  327. package/dist/record.d.ts.map +0 -1
  328. package/dist/record.js.map +0 -1
  329. package/dist/reflection.d.ts.map +0 -1
  330. package/dist/reflection.js.map +0 -1
  331. package/dist/replit.d.ts.map +0 -1
  332. package/dist/replit.js.map +0 -1
  333. package/dist/repo-map.d.ts.map +0 -1
  334. package/dist/repo-map.js.map +0 -1
  335. package/dist/sandbox-policy.d.ts.map +0 -1
  336. package/dist/sandbox-policy.js.map +0 -1
  337. package/dist/sdk.d.ts.map +0 -1
  338. package/dist/sdk.js.map +0 -1
  339. package/dist/seed-knowledge.d.ts.map +0 -1
  340. package/dist/seed-knowledge.js.map +0 -1
  341. package/dist/self-defense.d.ts.map +0 -1
  342. package/dist/self-defense.js.map +0 -1
  343. package/dist/self-eval.d.ts.map +0 -1
  344. package/dist/self-eval.js.map +0 -1
  345. package/dist/serve.d.ts.map +0 -1
  346. package/dist/serve.js.map +0 -1
  347. package/dist/sessions.d.ts.map +0 -1
  348. package/dist/sessions.js.map +0 -1
  349. package/dist/sessions.test.d.ts +0 -2
  350. package/dist/sessions.test.d.ts.map +0 -1
  351. package/dist/sessions.test.js +0 -55
  352. package/dist/sessions.test.js.map +0 -1
  353. package/dist/share.d.ts.map +0 -1
  354. package/dist/share.js.map +0 -1
  355. package/dist/side-conversation.d.ts.map +0 -1
  356. package/dist/side-conversation.js.map +0 -1
  357. package/dist/simulation.d.ts.map +0 -1
  358. package/dist/simulation.js.map +0 -1
  359. package/dist/skill-library.d.ts.map +0 -1
  360. package/dist/skill-library.js.map +0 -1
  361. package/dist/skill-rating.d.ts.map +0 -1
  362. package/dist/skill-rating.js.map +0 -1
  363. package/dist/skill-system.d.ts.map +0 -1
  364. package/dist/skill-system.js.map +0 -1
  365. package/dist/skills-loader.d.ts.map +0 -1
  366. package/dist/skills-loader.js.map +0 -1
  367. package/dist/spec.d.ts.map +0 -1
  368. package/dist/spec.js.map +0 -1
  369. package/dist/strange-loops.d.ts.map +0 -1
  370. package/dist/strange-loops.js.map +0 -1
  371. package/dist/streaming.d.ts.map +0 -1
  372. package/dist/streaming.js.map +0 -1
  373. package/dist/streaming.test.d.ts +0 -2
  374. package/dist/streaming.test.d.ts.map +0 -1
  375. package/dist/streaming.test.js +0 -41
  376. package/dist/streaming.test.js.map +0 -1
  377. package/dist/synthesis-engine.d.ts.map +0 -1
  378. package/dist/synthesis-engine.js.map +0 -1
  379. package/dist/task-ledger.d.ts.map +0 -1
  380. package/dist/task-ledger.js.map +0 -1
  381. package/dist/teach.d.ts.map +0 -1
  382. package/dist/teach.js.map +0 -1
  383. package/dist/team.d.ts.map +0 -1
  384. package/dist/team.js.map +0 -1
  385. package/dist/telemetry.d.ts.map +0 -1
  386. package/dist/telemetry.js.map +0 -1
  387. package/dist/temporal.d.ts.map +0 -1
  388. package/dist/temporal.js.map +0 -1
  389. package/dist/terminal-caps.d.ts.map +0 -1
  390. package/dist/terminal-caps.js.map +0 -1
  391. package/dist/tool-pipeline.d.ts.map +0 -1
  392. package/dist/tool-pipeline.js.map +0 -1
  393. package/dist/tools/ableton-knowledge.d.ts.map +0 -1
  394. package/dist/tools/ableton-knowledge.js.map +0 -1
  395. package/dist/tools/ableton.d.ts.map +0 -1
  396. package/dist/tools/ableton.js.map +0 -1
  397. package/dist/tools/admin.d.ts.map +0 -1
  398. package/dist/tools/admin.js.map +0 -1
  399. package/dist/tools/analytics.d.ts.map +0 -1
  400. package/dist/tools/analytics.js.map +0 -1
  401. package/dist/tools/arrangement-engine.d.ts.map +0 -1
  402. package/dist/tools/arrangement-engine.js.map +0 -1
  403. package/dist/tools/audit.d.ts.map +0 -1
  404. package/dist/tools/audit.js.map +0 -1
  405. package/dist/tools/background.d.ts.map +0 -1
  406. package/dist/tools/background.js.map +0 -1
  407. package/dist/tools/bash.d.ts.map +0 -1
  408. package/dist/tools/bash.js.map +0 -1
  409. package/dist/tools/bash.test.d.ts +0 -2
  410. package/dist/tools/bash.test.d.ts.map +0 -1
  411. package/dist/tools/bash.test.js +0 -284
  412. package/dist/tools/bash.test.js.map +0 -1
  413. package/dist/tools/bootstrapper.d.ts.map +0 -1
  414. package/dist/tools/bootstrapper.js.map +0 -1
  415. package/dist/tools/browser-agent.d.ts.map +0 -1
  416. package/dist/tools/browser-agent.js.map +0 -1
  417. package/dist/tools/browser.d.ts.map +0 -1
  418. package/dist/tools/browser.js.map +0 -1
  419. package/dist/tools/build-matrix.d.ts.map +0 -1
  420. package/dist/tools/build-matrix.js.map +0 -1
  421. package/dist/tools/comfyui-plugin.d.ts.map +0 -1
  422. package/dist/tools/comfyui-plugin.js.map +0 -1
  423. package/dist/tools/composio.d.ts.map +0 -1
  424. package/dist/tools/composio.js.map +0 -1
  425. package/dist/tools/computer.d.ts.map +0 -1
  426. package/dist/tools/computer.js.map +0 -1
  427. package/dist/tools/containers.d.ts.map +0 -1
  428. package/dist/tools/containers.js.map +0 -1
  429. package/dist/tools/content-engine.d.ts.map +0 -1
  430. package/dist/tools/content-engine.js.map +0 -1
  431. package/dist/tools/contribute.d.ts.map +0 -1
  432. package/dist/tools/contribute.js.map +0 -1
  433. package/dist/tools/creative.d.ts.map +0 -1
  434. package/dist/tools/creative.js.map +0 -1
  435. package/dist/tools/creative.test.d.ts +0 -2
  436. package/dist/tools/creative.test.d.ts.map +0 -1
  437. package/dist/tools/creative.test.js +0 -281
  438. package/dist/tools/creative.test.js.map +0 -1
  439. package/dist/tools/ctf.d.ts.map +0 -1
  440. package/dist/tools/ctf.js.map +0 -1
  441. package/dist/tools/database.d.ts.map +0 -1
  442. package/dist/tools/database.js.map +0 -1
  443. package/dist/tools/db-admin.d.ts.map +0 -1
  444. package/dist/tools/db-admin.js.map +0 -1
  445. package/dist/tools/deploy-all.d.ts.map +0 -1
  446. package/dist/tools/deploy-all.js.map +0 -1
  447. package/dist/tools/deploy.d.ts.map +0 -1
  448. package/dist/tools/deploy.js.map +0 -1
  449. package/dist/tools/dj-set-builder.d.ts.map +0 -1
  450. package/dist/tools/dj-set-builder.js.map +0 -1
  451. package/dist/tools/documents.d.ts.map +0 -1
  452. package/dist/tools/documents.js.map +0 -1
  453. package/dist/tools/e2b-sandbox.d.ts.map +0 -1
  454. package/dist/tools/e2b-sandbox.js.map +0 -1
  455. package/dist/tools/email.d.ts.map +0 -1
  456. package/dist/tools/email.js.map +0 -1
  457. package/dist/tools/emergent.d.ts.map +0 -1
  458. package/dist/tools/emergent.js.map +0 -1
  459. package/dist/tools/env-manager.d.ts.map +0 -1
  460. package/dist/tools/env-manager.js.map +0 -1
  461. package/dist/tools/fetch.d.ts.map +0 -1
  462. package/dist/tools/fetch.js.map +0 -1
  463. package/dist/tools/fetch.test.d.ts +0 -2
  464. package/dist/tools/fetch.test.d.ts.map +0 -1
  465. package/dist/tools/fetch.test.js +0 -363
  466. package/dist/tools/fetch.test.js.map +0 -1
  467. package/dist/tools/files.d.ts.map +0 -1
  468. package/dist/tools/files.js.map +0 -1
  469. package/dist/tools/files.test.d.ts +0 -2
  470. package/dist/tools/files.test.d.ts.map +0 -1
  471. package/dist/tools/files.test.js +0 -395
  472. package/dist/tools/files.test.js.map +0 -1
  473. package/dist/tools/finance.d.ts.map +0 -1
  474. package/dist/tools/finance.js.map +0 -1
  475. package/dist/tools/finance.test.d.ts +0 -2
  476. package/dist/tools/finance.test.d.ts.map +0 -1
  477. package/dist/tools/finance.test.js +0 -245
  478. package/dist/tools/finance.test.js.map +0 -1
  479. package/dist/tools/forge.d.ts.map +0 -1
  480. package/dist/tools/forge.js.map +0 -1
  481. package/dist/tools/forge.test.d.ts +0 -2
  482. package/dist/tools/forge.test.d.ts.map +0 -1
  483. package/dist/tools/forge.test.js +0 -250
  484. package/dist/tools/forge.test.js.map +0 -1
  485. package/dist/tools/gamedev.d.ts.map +0 -1
  486. package/dist/tools/gamedev.js.map +0 -1
  487. package/dist/tools/gamedev.test.d.ts +0 -2
  488. package/dist/tools/gamedev.test.d.ts.map +0 -1
  489. package/dist/tools/gamedev.test.js +0 -937
  490. package/dist/tools/gamedev.test.js.map +0 -1
  491. package/dist/tools/git.d.ts.map +0 -1
  492. package/dist/tools/git.js.map +0 -1
  493. package/dist/tools/git.test.d.ts +0 -2
  494. package/dist/tools/git.test.d.ts.map +0 -1
  495. package/dist/tools/git.test.js +0 -303
  496. package/dist/tools/git.test.js.map +0 -1
  497. package/dist/tools/github.d.ts.map +0 -1
  498. package/dist/tools/github.js.map +0 -1
  499. package/dist/tools/hacker-toolkit.d.ts.map +0 -1
  500. package/dist/tools/hacker-toolkit.js.map +0 -1
  501. package/dist/tools/hypothesis-engine.d.ts.map +0 -1
  502. package/dist/tools/hypothesis-engine.js.map +0 -1
  503. package/dist/tools/index.d.ts.map +0 -1
  504. package/dist/tools/index.js.map +0 -1
  505. package/dist/tools/index.test.d.ts +0 -2
  506. package/dist/tools/index.test.d.ts.map +0 -1
  507. package/dist/tools/index.test.js +0 -155
  508. package/dist/tools/index.test.js.map +0 -1
  509. package/dist/tools/kbot-local.d.ts.map +0 -1
  510. package/dist/tools/kbot-local.js.map +0 -1
  511. package/dist/tools/lab-bio.d.ts.map +0 -1
  512. package/dist/tools/lab-bio.js.map +0 -1
  513. package/dist/tools/lab-chem.d.ts.map +0 -1
  514. package/dist/tools/lab-chem.js.map +0 -1
  515. package/dist/tools/lab-core.d.ts.map +0 -1
  516. package/dist/tools/lab-core.js.map +0 -1
  517. package/dist/tools/lab-data.d.ts.map +0 -1
  518. package/dist/tools/lab-data.js.map +0 -1
  519. package/dist/tools/lab-earth.d.ts.map +0 -1
  520. package/dist/tools/lab-earth.js.map +0 -1
  521. package/dist/tools/lab-frontier.d.ts.map +0 -1
  522. package/dist/tools/lab-frontier.js.map +0 -1
  523. package/dist/tools/lab-health.d.ts.map +0 -1
  524. package/dist/tools/lab-health.js.map +0 -1
  525. package/dist/tools/lab-humanities.d.ts.map +0 -1
  526. package/dist/tools/lab-humanities.js.map +0 -1
  527. package/dist/tools/lab-math.d.ts.map +0 -1
  528. package/dist/tools/lab-math.js.map +0 -1
  529. package/dist/tools/lab-neuro.d.ts.map +0 -1
  530. package/dist/tools/lab-neuro.js.map +0 -1
  531. package/dist/tools/lab-physics.d.ts.map +0 -1
  532. package/dist/tools/lab-physics.js.map +0 -1
  533. package/dist/tools/lab-social.d.ts.map +0 -1
  534. package/dist/tools/lab-social.js.map +0 -1
  535. package/dist/tools/lsp-tools.d.ts.map +0 -1
  536. package/dist/tools/lsp-tools.js.map +0 -1
  537. package/dist/tools/machine-tools.d.ts.map +0 -1
  538. package/dist/tools/machine-tools.js.map +0 -1
  539. package/dist/tools/magenta-plugin.d.ts.map +0 -1
  540. package/dist/tools/magenta-plugin.js.map +0 -1
  541. package/dist/tools/matrix.d.ts.map +0 -1
  542. package/dist/tools/matrix.js.map +0 -1
  543. package/dist/tools/mcp-client.d.ts.map +0 -1
  544. package/dist/tools/mcp-client.js.map +0 -1
  545. package/dist/tools/mcp-marketplace.d.ts.map +0 -1
  546. package/dist/tools/mcp-marketplace.js.map +0 -1
  547. package/dist/tools/memory-tools.d.ts.map +0 -1
  548. package/dist/tools/memory-tools.js.map +0 -1
  549. package/dist/tools/monitor.d.ts.map +0 -1
  550. package/dist/tools/monitor.js.map +0 -1
  551. package/dist/tools/music-theory.d.ts.map +0 -1
  552. package/dist/tools/music-theory.js.map +0 -1
  553. package/dist/tools/notebook.d.ts.map +0 -1
  554. package/dist/tools/notebook.js.map +0 -1
  555. package/dist/tools/openclaw.d.ts.map +0 -1
  556. package/dist/tools/openclaw.js.map +0 -1
  557. package/dist/tools/parallel.d.ts.map +0 -1
  558. package/dist/tools/parallel.js.map +0 -1
  559. package/dist/tools/pentest.d.ts.map +0 -1
  560. package/dist/tools/pentest.js.map +0 -1
  561. package/dist/tools/producer-engine.d.ts.map +0 -1
  562. package/dist/tools/producer-engine.js.map +0 -1
  563. package/dist/tools/quality.d.ts.map +0 -1
  564. package/dist/tools/quality.js.map +0 -1
  565. package/dist/tools/redblue.d.ts.map +0 -1
  566. package/dist/tools/redblue.js.map +0 -1
  567. package/dist/tools/research-notebook.d.ts.map +0 -1
  568. package/dist/tools/research-notebook.js.map +0 -1
  569. package/dist/tools/research-pipeline.d.ts.map +0 -1
  570. package/dist/tools/research-pipeline.js.map +0 -1
  571. package/dist/tools/research.d.ts.map +0 -1
  572. package/dist/tools/research.js.map +0 -1
  573. package/dist/tools/sandbox.d.ts.map +0 -1
  574. package/dist/tools/sandbox.js.map +0 -1
  575. package/dist/tools/science-graph.d.ts.map +0 -1
  576. package/dist/tools/science-graph.js.map +0 -1
  577. package/dist/tools/search.d.ts.map +0 -1
  578. package/dist/tools/search.js.map +0 -1
  579. package/dist/tools/search.test.d.ts +0 -2
  580. package/dist/tools/search.test.d.ts.map +0 -1
  581. package/dist/tools/search.test.js +0 -311
  582. package/dist/tools/search.test.js.map +0 -1
  583. package/dist/tools/security-brain.d.ts.map +0 -1
  584. package/dist/tools/security-brain.js.map +0 -1
  585. package/dist/tools/security-hunt.d.ts.map +0 -1
  586. package/dist/tools/security-hunt.js.map +0 -1
  587. package/dist/tools/security.d.ts.map +0 -1
  588. package/dist/tools/security.js.map +0 -1
  589. package/dist/tools/sentiment.d.ts.map +0 -1
  590. package/dist/tools/sentiment.js.map +0 -1
  591. package/dist/tools/serum2-preset.d.ts.map +0 -1
  592. package/dist/tools/serum2-preset.js.map +0 -1
  593. package/dist/tools/social.d.ts.map +0 -1
  594. package/dist/tools/social.js.map +0 -1
  595. package/dist/tools/sound-designer.d.ts.map +0 -1
  596. package/dist/tools/sound-designer.js.map +0 -1
  597. package/dist/tools/stocks.d.ts.map +0 -1
  598. package/dist/tools/stocks.js.map +0 -1
  599. package/dist/tools/stocks.test.d.ts +0 -2
  600. package/dist/tools/stocks.test.d.ts.map +0 -1
  601. package/dist/tools/stocks.test.js +0 -82
  602. package/dist/tools/stocks.test.js.map +0 -1
  603. package/dist/tools/subagent.d.ts.map +0 -1
  604. package/dist/tools/subagent.js.map +0 -1
  605. package/dist/tools/tasks.d.ts.map +0 -1
  606. package/dist/tools/tasks.js.map +0 -1
  607. package/dist/tools/test-runner.d.ts.map +0 -1
  608. package/dist/tools/test-runner.js.map +0 -1
  609. package/dist/tools/training.d.ts.map +0 -1
  610. package/dist/tools/training.js.map +0 -1
  611. package/dist/tools/vfx.d.ts.map +0 -1
  612. package/dist/tools/vfx.js.map +0 -1
  613. package/dist/tools/visa-payments.d.ts.map +0 -1
  614. package/dist/tools/visa-payments.js.map +0 -1
  615. package/dist/tools/wallet.d.ts.map +0 -1
  616. package/dist/tools/wallet.js.map +0 -1
  617. package/dist/tools/wallet.test.d.ts +0 -2
  618. package/dist/tools/wallet.test.d.ts.map +0 -1
  619. package/dist/tools/wallet.test.js +0 -205
  620. package/dist/tools/wallet.test.js.map +0 -1
  621. package/dist/tools/weather.d.ts.map +0 -1
  622. package/dist/tools/weather.js.map +0 -1
  623. package/dist/tools/worktree.d.ts.map +0 -1
  624. package/dist/tools/worktree.js.map +0 -1
  625. package/dist/tree-planner.d.ts.map +0 -1
  626. package/dist/tree-planner.js.map +0 -1
  627. package/dist/tui.d.ts.map +0 -1
  628. package/dist/tui.js.map +0 -1
  629. package/dist/tutorial.d.ts.map +0 -1
  630. package/dist/tutorial.js.map +0 -1
  631. package/dist/ui-adapter.d.ts.map +0 -1
  632. package/dist/ui-adapter.js.map +0 -1
  633. package/dist/ui.d.ts.map +0 -1
  634. package/dist/ui.js.map +0 -1
  635. package/dist/updater.d.ts.map +0 -1
  636. package/dist/updater.js.map +0 -1
  637. package/dist/user-graph.d.ts.map +0 -1
  638. package/dist/user-graph.js.map +0 -1
  639. package/dist/voice-loop.d.ts.map +0 -1
  640. package/dist/voice-loop.js.map +0 -1
  641. package/dist/voice-realtime.d.ts.map +0 -1
  642. package/dist/voice-realtime.js.map +0 -1
  643. package/dist/voice.d.ts.map +0 -1
  644. package/dist/voice.js.map +0 -1
  645. package/dist/watch.d.ts.map +0 -1
  646. package/dist/watch.js.map +0 -1
  647. package/dist/workflows.d.ts.map +0 -1
  648. package/dist/workflows.js.map +0 -1
@@ -1,937 +0,0 @@
1
- // kbot Game Development Tools Tests
2
- import { describe, it, before, after } from 'node:test';
3
- import assert from 'node:assert';
4
- import { rmSync, existsSync, readFileSync, mkdirSync, writeFileSync } from 'node:fs';
5
- import { join, resolve } from 'node:path';
6
- // Import the tool registry
7
- import { executeTool, getTool } from './index.js';
8
- // Import the registration function
9
- import { registerGamedevTools } from './gamedev.js';
10
- // Use a RELATIVE temp directory inside the working directory so safePath() allows it.
11
- // safePath() enforces: resolved path must be within process.cwd().
12
- const TEST_DIR_REL = '.kbot-gamedev-test-' + Date.now();
13
- const TEST_DIR = resolve(process.cwd(), TEST_DIR_REL);
14
- before(() => {
15
- mkdirSync(TEST_DIR, { recursive: true });
16
- registerGamedevTools();
17
- });
18
- after(() => {
19
- try {
20
- rmSync(TEST_DIR, { recursive: true, force: true });
21
- }
22
- catch { }
23
- });
24
- // ─────────────────────────────────────────────────────────────────────
25
- // 1. Registration tests — all 16 tools
26
- // ─────────────────────────────────────────────────────────────────────
27
- describe('Gamedev Tools Registration', () => {
28
- const expectedTools = [
29
- { name: 'scaffold_game', requiredParams: ['engine', 'name'] },
30
- { name: 'game_config', requiredParams: ['config_type', 'settings'] },
31
- { name: 'shader_debug', requiredParams: ['source', 'language'] },
32
- { name: 'material_graph', requiredParams: ['material_type', 'engine'] },
33
- { name: 'mesh_generate', requiredParams: ['shape', 'output_path'] },
34
- { name: 'sprite_pack', requiredParams: ['input_dir', 'output_image', 'output_data'] },
35
- { name: 'physics_setup', requiredParams: ['type', 'output_path'] },
36
- { name: 'particle_system', requiredParams: [] },
37
- { name: 'level_generate', requiredParams: ['type', 'output_path'] },
38
- { name: 'tilemap_generate', requiredParams: ['tileset_type', 'terrain', 'output_path'] },
39
- { name: 'navmesh_config', requiredParams: [] },
40
- { name: 'game_audio', requiredParams: [] },
41
- { name: 'netcode_scaffold', requiredParams: [] },
42
- { name: 'game_build', requiredParams: [] },
43
- { name: 'game_test', requiredParams: [] },
44
- { name: 'ecs_generate', requiredParams: ['framework', 'entities', 'output_dir'] },
45
- ];
46
- for (const { name, requiredParams } of expectedTools) {
47
- it(`registers ${name} tool`, () => {
48
- const tool = getTool(name);
49
- assert.ok(tool, `Tool "${name}" should be registered`);
50
- assert.strictEqual(tool.tier, 'free', `Tool "${name}" should be free tier`);
51
- });
52
- if (requiredParams.length > 0) {
53
- it(`${name} has correct required parameters`, () => {
54
- const tool = getTool(name);
55
- for (const param of requiredParams) {
56
- assert.ok(tool.parameters[param], `Tool "${name}" should have parameter "${param}"`);
57
- assert.strictEqual(tool.parameters[param].required, true, `Parameter "${param}" should be required`);
58
- }
59
- });
60
- }
61
- }
62
- it('registers exactly 16 gamedev tools', () => {
63
- const toolNames = expectedTools.map(t => t.name);
64
- for (const name of toolNames) {
65
- assert.ok(getTool(name), `Tool "${name}" should exist in registry`);
66
- }
67
- });
68
- });
69
- // ─────────────────────────────────────────────────────────────────────
70
- // 2. scaffold_game
71
- // ─────────────────────────────────────────────────────────────────────
72
- describe('scaffold_game', () => {
73
- it('Godot: generates project.godot and main.tscn', async () => {
74
- const outDir = join(TEST_DIR_REL, 'godot-project');
75
- const result = await executeTool({
76
- id: 'scaffold-godot',
77
- name: 'scaffold_game',
78
- arguments: { engine: 'godot', name: 'TestGame', template: '2d', output_dir: outDir },
79
- });
80
- assert.ok(!result.error, `Should not return error: ${result.result}`);
81
- assert.ok(result.result.includes('Scaffolded godot project'), 'Should confirm scaffold');
82
- const absDir = resolve(process.cwd(), outDir);
83
- assert.ok(existsSync(join(absDir, 'project.godot')), 'project.godot should exist');
84
- assert.ok(existsSync(join(absDir, 'main.tscn')), 'main.tscn should exist');
85
- assert.ok(existsSync(join(absDir, '.gitignore')), '.gitignore should exist');
86
- const projectGodot = readFileSync(join(absDir, 'project.godot'), 'utf-8');
87
- assert.ok(projectGodot.includes('config/name="TestGame"'), 'project.godot should contain project name');
88
- assert.ok(projectGodot.includes('gl_compatibility'), '2d template should use gl_compatibility renderer');
89
- });
90
- it('Godot 3D: uses forward_plus renderer', async () => {
91
- const outDir = join(TEST_DIR_REL, 'godot-3d');
92
- await executeTool({
93
- id: 'scaffold-godot-3d',
94
- name: 'scaffold_game',
95
- arguments: { engine: 'godot', name: 'My3DGame', template: '3d', output_dir: outDir },
96
- });
97
- const absDir = resolve(process.cwd(), outDir);
98
- const projectGodot = readFileSync(join(absDir, 'project.godot'), 'utf-8');
99
- assert.ok(projectGodot.includes('forward_plus'), '3d template should use forward_plus renderer');
100
- });
101
- it('Bevy: generates Cargo.toml and src/main.rs', async () => {
102
- const outDir = join(TEST_DIR_REL, 'bevy-project');
103
- const result = await executeTool({
104
- id: 'scaffold-bevy',
105
- name: 'scaffold_game',
106
- arguments: { engine: 'bevy', name: 'BevyGame', template: '3d', output_dir: outDir },
107
- });
108
- assert.ok(!result.error, `Should not error: ${result.result}`);
109
- const absDir = resolve(process.cwd(), outDir);
110
- assert.ok(existsSync(join(absDir, 'Cargo.toml')), 'Cargo.toml should exist');
111
- assert.ok(existsSync(join(absDir, 'src/main.rs')), 'src/main.rs should exist');
112
- const cargoToml = readFileSync(join(absDir, 'Cargo.toml'), 'utf-8');
113
- assert.ok(cargoToml.includes('bevy'), 'Cargo.toml should reference bevy dependency');
114
- assert.ok(cargoToml.includes('bevygame') || cargoToml.includes('bevy-game'), 'Name should be lowercased');
115
- const mainRs = readFileSync(join(absDir, 'src/main.rs'), 'utf-8');
116
- assert.ok(mainRs.includes('use bevy::prelude::*'), 'main.rs should import bevy');
117
- assert.ok(mainRs.includes('Camera3d'), '3d template should have Camera3d');
118
- });
119
- it('Phaser: generates package.json, src/main.ts, and index.html', async () => {
120
- const outDir = join(TEST_DIR_REL, 'phaser-project');
121
- const result = await executeTool({
122
- id: 'scaffold-phaser',
123
- name: 'scaffold_game',
124
- arguments: { engine: 'phaser', name: 'PhaserGame', output_dir: outDir },
125
- });
126
- assert.ok(!result.error, `Should not error: ${result.result}`);
127
- const absDir = resolve(process.cwd(), outDir);
128
- assert.ok(existsSync(join(absDir, 'package.json')), 'package.json should exist');
129
- assert.ok(existsSync(join(absDir, 'src/main.ts')), 'src/main.ts should exist');
130
- assert.ok(existsSync(join(absDir, 'index.html')), 'index.html should exist');
131
- const pkg = JSON.parse(readFileSync(join(absDir, 'package.json'), 'utf-8'));
132
- assert.ok(pkg.dependencies.phaser, 'package.json should have phaser dependency');
133
- });
134
- it('Three.js: generates package.json and src/main.ts', async () => {
135
- const outDir = join(TEST_DIR_REL, 'three-project');
136
- const result = await executeTool({
137
- id: 'scaffold-three',
138
- name: 'scaffold_game',
139
- arguments: { engine: 'three', name: 'ThreeGame', output_dir: outDir },
140
- });
141
- assert.ok(!result.error, `Should not error: ${result.result}`);
142
- const absDir = resolve(process.cwd(), outDir);
143
- assert.ok(existsSync(join(absDir, 'package.json')), 'package.json should exist');
144
- assert.ok(existsSync(join(absDir, 'src/main.ts')), 'src/main.ts should exist');
145
- const mainTs = readFileSync(join(absDir, 'src/main.ts'), 'utf-8');
146
- assert.ok(mainTs.includes("import * as THREE from 'three'"), 'main.ts should import three');
147
- assert.ok(mainTs.includes('BoxGeometry'), 'main.ts should have a cube');
148
- });
149
- it('returns error for invalid engine', async () => {
150
- const result = await executeTool({
151
- id: 'scaffold-bad-engine',
152
- name: 'scaffold_game',
153
- arguments: { engine: 'gamemaker', name: 'Test', output_dir: join(TEST_DIR_REL, 'bad') },
154
- });
155
- assert.ok(result.result.includes('Unknown engine'), 'Should report unknown engine');
156
- assert.ok(result.result.includes('gamemaker'), 'Should mention the invalid engine name');
157
- });
158
- it('returns error for invalid template', async () => {
159
- const result = await executeTool({
160
- id: 'scaffold-bad-template',
161
- name: 'scaffold_game',
162
- arguments: { engine: 'godot', name: 'Test', template: 'vr', output_dir: join(TEST_DIR_REL, 'bad-tpl') },
163
- });
164
- assert.ok(result.result.includes('Invalid template'), 'Should report invalid template');
165
- });
166
- });
167
- // ─────────────────────────────────────────────────────────────────────
168
- // 3. shader_debug
169
- // ─────────────────────────────────────────────────────────────────────
170
- describe('shader_debug', () => {
171
- it('detects discard in fragment shaders (mobile target)', async () => {
172
- const shaderCode = `
173
- precision mediump float;
174
- varying vec2 vUv;
175
- uniform sampler2D uTexture;
176
-
177
- void main() {
178
- vec4 color = texture2D(uTexture, vUv);
179
- if (color.a < 0.1) discard;
180
- gl_FragColor = color;
181
- }
182
- `;
183
- const result = await executeTool({
184
- id: 'shader-discard',
185
- name: 'shader_debug',
186
- arguments: { source: shaderCode, language: 'glsl', target: 'mobile' },
187
- });
188
- assert.ok(!result.error);
189
- assert.ok(result.result.includes('discard'), 'Should detect discard statement');
190
- assert.ok(result.result.includes('early-Z'), 'Should mention early-Z optimization issue');
191
- assert.ok(result.result.includes('PRF'), 'Should be classified as a perf issue');
192
- });
193
- it('detects pow(x, 2.0) optimization opportunity', async () => {
194
- const shaderCode = `
195
- void main() {
196
- float val = pow(uv.x, 2.0);
197
- gl_FragColor = vec4(val, val, val, 1.0);
198
- }
199
- `;
200
- const result = await executeTool({
201
- id: 'shader-pow',
202
- name: 'shader_debug',
203
- arguments: { source: shaderCode, language: 'glsl' },
204
- });
205
- assert.ok(!result.error);
206
- assert.ok(result.result.includes('pow(x, 2.0)'), 'Should detect pow(x, 2.0)');
207
- assert.ok(result.result.includes('x*x'), 'Should suggest x*x replacement');
208
- });
209
- it('detects dynamic branching', async () => {
210
- const shaderCode = `
211
- void main() {
212
- if (uv.x > 0.5) {
213
- gl_FragColor = vec4(1.0);
214
- } else {
215
- gl_FragColor = vec4(0.0);
216
- }
217
- }
218
- `;
219
- const result = await executeTool({
220
- id: 'shader-branching',
221
- name: 'shader_debug',
222
- arguments: { source: shaderCode, language: 'glsl' },
223
- });
224
- assert.ok(!result.error);
225
- assert.ok(result.result.includes('Dynamic branching'), 'Should detect dynamic branching');
226
- assert.ok(result.result.includes('step()'), 'Should suggest branchless alternatives');
227
- });
228
- it('returns structured report with severity levels', async () => {
229
- const shaderCode = `
230
- uniform sampler2D tex;
231
- varying vec2 vUv;
232
- void main() {
233
- float val = pow(uv.x, 2.0);
234
- vec3 n = normalize(vec3(0.0));
235
- if (val > 0.5) discard;
236
- gl_FragColor = texture(tex, vUv + val);
237
- }
238
- `;
239
- const result = await executeTool({
240
- id: 'shader-report',
241
- name: 'shader_debug',
242
- arguments: { source: shaderCode, language: 'glsl', target: 'mobile' },
243
- });
244
- assert.ok(!result.error);
245
- // Verify report structure
246
- assert.ok(result.result.includes('Shader Analysis Report'), 'Should have report header');
247
- assert.ok(result.result.includes('GLSL'), 'Should mention language');
248
- assert.ok(result.result.includes('Errors:'), 'Should have error count');
249
- assert.ok(result.result.includes('Warnings:'), 'Should have warning count');
250
- assert.ok(result.result.includes('Perf issues:'), 'Should have perf issue count');
251
- assert.ok(result.result.includes('Uniforms:'), 'Should count uniforms');
252
- // Should contain both PRF and ERR severity tags
253
- assert.ok(result.result.includes('[PRF]'), 'Should have PRF-level issues');
254
- assert.ok(result.result.includes('[ERR]'), 'Should have ERR-level issues (normalize zero vector)');
255
- });
256
- it('rejects unknown shader language', async () => {
257
- const result = await executeTool({
258
- id: 'shader-bad-lang',
259
- name: 'shader_debug',
260
- arguments: { source: 'void main() {}', language: 'metal' },
261
- });
262
- assert.ok(result.result.includes('Unknown shader language'), 'Should reject unknown language');
263
- });
264
- it('reports clean shader when no issues found', async () => {
265
- const shaderCode = `
266
- void main() {
267
- gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
268
- }
269
- `;
270
- const result = await executeTool({
271
- id: 'shader-clean',
272
- name: 'shader_debug',
273
- arguments: { source: shaderCode, language: 'glsl' },
274
- });
275
- assert.ok(!result.error);
276
- assert.ok(result.result.includes('No issues found') || result.result.includes('Errors: 0'), 'Clean shader should report no issues or zero errors');
277
- });
278
- it('reads shader from file path when file is in working directory', async () => {
279
- const shaderPath = join(TEST_DIR_REL, 'test-shader.glsl');
280
- const absShaderPath = resolve(process.cwd(), shaderPath);
281
- mkdirSync(resolve(process.cwd(), TEST_DIR_REL), { recursive: true });
282
- const shaderContent = `
283
- void main() {
284
- float val = pow(uv.x, 2.0);
285
- gl_FragColor = vec4(val, val, val, 1.0);
286
- }
287
- `;
288
- writeFileSync(absShaderPath, shaderContent, 'utf-8');
289
- const result = await executeTool({
290
- id: 'shader-file',
291
- name: 'shader_debug',
292
- arguments: { source: absShaderPath, language: 'glsl' },
293
- });
294
- assert.ok(!result.error);
295
- assert.ok(result.result.includes('pow(x, 2.0)'), 'Should detect issue from file content');
296
- });
297
- });
298
- // ─────────────────────────────────────────────────────────────────────
299
- // 4. mesh_generate
300
- // ─────────────────────────────────────────────────────────────────────
301
- describe('mesh_generate', () => {
302
- it('plane generates valid OBJ with vertices and faces', async () => {
303
- const outPath = join(TEST_DIR_REL, 'plane.obj');
304
- const result = await executeTool({
305
- id: 'mesh-plane',
306
- name: 'mesh_generate',
307
- arguments: { shape: 'plane', output_path: outPath },
308
- });
309
- assert.ok(!result.error, `Should not error: ${result.result}`);
310
- assert.ok(result.result.includes('Generated plane mesh'), 'Should confirm plane generation');
311
- const absPath = resolve(process.cwd(), outPath);
312
- assert.ok(existsSync(absPath), 'OBJ file should exist');
313
- const obj = readFileSync(absPath, 'utf-8');
314
- assert.ok(obj.includes('v '), 'OBJ should contain vertices');
315
- assert.ok(obj.includes('vn '), 'OBJ should contain normals');
316
- assert.ok(obj.includes('vt '), 'OBJ should contain UVs');
317
- assert.ok(obj.includes('f '), 'OBJ should contain faces');
318
- assert.ok(obj.includes('o plane'), 'OBJ should contain object name');
319
- });
320
- it('cube generates valid OBJ', async () => {
321
- const outPath = join(TEST_DIR_REL, 'cube.obj');
322
- const result = await executeTool({
323
- id: 'mesh-cube',
324
- name: 'mesh_generate',
325
- arguments: { shape: 'cube', output_path: outPath },
326
- });
327
- assert.ok(!result.error, `Should not error: ${result.result}`);
328
- const absPath = resolve(process.cwd(), outPath);
329
- assert.ok(existsSync(absPath), 'OBJ file should exist');
330
- const obj = readFileSync(absPath, 'utf-8');
331
- // A cube has 24 vertices (4 per face x 6 faces), 12 faces (2 triangles per face x 6)
332
- const vertexLines = obj.split('\n').filter((l) => l.startsWith('v '));
333
- assert.strictEqual(vertexLines.length, 24, 'Cube should have 24 vertices');
334
- const faceLines = obj.split('\n').filter((l) => l.startsWith('f '));
335
- assert.strictEqual(faceLines.length, 12, 'Cube should have 12 triangle faces');
336
- });
337
- it('sphere generates valid OBJ', async () => {
338
- const outPath = join(TEST_DIR_REL, 'sphere.obj');
339
- const result = await executeTool({
340
- id: 'mesh-sphere',
341
- name: 'mesh_generate',
342
- arguments: { shape: 'sphere', output_path: outPath, params: '{"rings": 8, "segments": 16}' },
343
- });
344
- assert.ok(!result.error, `Should not error: ${result.result}`);
345
- const absPath = resolve(process.cwd(), outPath);
346
- assert.ok(existsSync(absPath), 'OBJ file should exist');
347
- const obj = readFileSync(absPath, 'utf-8');
348
- const vertexLines = obj.split('\n').filter((l) => l.startsWith('v '));
349
- // Sphere with 8 rings and 16 segments: (8+1) * (16+1) = 153 vertices
350
- assert.strictEqual(vertexLines.length, 153, 'Sphere should have (rings+1)*(segments+1) vertices');
351
- assert.ok(result.result.includes('Vertices: 153'), 'Result should report vertex count');
352
- });
353
- it('verifies face count for plane with given segments', async () => {
354
- const outPath = join(TEST_DIR_REL, 'plane-segs.obj');
355
- const segX = 4;
356
- const segY = 3;
357
- await executeTool({
358
- id: 'mesh-plane-segs',
359
- name: 'mesh_generate',
360
- arguments: { shape: 'plane', output_path: outPath, params: `{"segments_x": ${segX}, "segments_y": ${segY}}` },
361
- });
362
- const absPath = resolve(process.cwd(), outPath);
363
- const obj = readFileSync(absPath, 'utf-8');
364
- const faceLines = obj.split('\n').filter((l) => l.startsWith('f '));
365
- // Plane faces = segX * segY * 2 (2 triangles per quad)
366
- const expectedFaces = segX * segY * 2;
367
- assert.strictEqual(faceLines.length, expectedFaces, `Plane should have ${expectedFaces} faces for ${segX}x${segY} segments`);
368
- });
369
- it('returns error for invalid shape', async () => {
370
- const result = await executeTool({
371
- id: 'mesh-bad',
372
- name: 'mesh_generate',
373
- arguments: { shape: 'pyramid', output_path: join(TEST_DIR_REL, 'bad.obj') },
374
- });
375
- assert.ok(result.result.includes('Unknown shape'), 'Should report unknown shape');
376
- assert.ok(result.result.includes('pyramid'), 'Should mention the invalid shape name');
377
- });
378
- it('returns error for invalid params JSON', async () => {
379
- const result = await executeTool({
380
- id: 'mesh-bad-json',
381
- name: 'mesh_generate',
382
- arguments: { shape: 'cube', output_path: join(TEST_DIR_REL, 'bad.obj'), params: 'not-json' },
383
- });
384
- assert.ok(result.result.includes('params must be valid JSON'), 'Should report JSON parse error');
385
- });
386
- });
387
- // ─────────────────────────────────────────────────────────────────────
388
- // 5. level_generate
389
- // ─────────────────────────────────────────────────────────────────────
390
- describe('level_generate', () => {
391
- it('dungeon produces valid JSON with map and rooms', async () => {
392
- const outPath = join(TEST_DIR_REL, 'dungeon.json');
393
- const result = await executeTool({
394
- id: 'level-dungeon',
395
- name: 'level_generate',
396
- arguments: { type: 'dungeon', width: 40, height: 30, seed: 42, output_path: outPath, format: 'json' },
397
- });
398
- assert.ok(!result.error, `Should not error: ${result.result}`);
399
- assert.ok(result.result.includes('Level generated'), 'Should confirm level generation');
400
- const absPath = resolve(process.cwd(), outPath);
401
- assert.ok(existsSync(absPath), 'JSON file should exist');
402
- const data = JSON.parse(readFileSync(absPath, 'utf-8'));
403
- assert.ok(data.meta, 'Should have meta section');
404
- assert.strictEqual(data.meta.type, 'dungeon', 'Meta should indicate dungeon type');
405
- assert.strictEqual(data.meta.width, 40, 'Width should match');
406
- assert.strictEqual(data.meta.height, 30, 'Height should match');
407
- assert.strictEqual(data.meta.seed, 42, 'Seed should match');
408
- assert.ok(data.map, 'Should have map 2D array');
409
- assert.strictEqual(data.map.length, 30, 'Map should have correct number of rows');
410
- assert.strictEqual(data.map[0].length, 40, 'Map should have correct number of columns');
411
- assert.ok(data.rooms.length > 0, 'Should have at least one room');
412
- assert.ok(data.legend, 'Should have legend');
413
- });
414
- it('same seed produces identical output (determinism)', async () => {
415
- const path1 = join(TEST_DIR_REL, 'det-level-1.json');
416
- const path2 = join(TEST_DIR_REL, 'det-level-2.json');
417
- await executeTool({
418
- id: 'level-det-1',
419
- name: 'level_generate',
420
- arguments: { type: 'dungeon', width: 30, height: 20, seed: 12345, output_path: path1, format: 'json' },
421
- });
422
- await executeTool({
423
- id: 'level-det-2',
424
- name: 'level_generate',
425
- arguments: { type: 'dungeon', width: 30, height: 20, seed: 12345, output_path: path2, format: 'json' },
426
- });
427
- const content1 = readFileSync(resolve(process.cwd(), path1), 'utf-8');
428
- const content2 = readFileSync(resolve(process.cwd(), path2), 'utf-8');
429
- assert.strictEqual(content1, content2, 'Same seed should produce identical output');
430
- });
431
- it('different seeds produce different output', async () => {
432
- const path1 = join(TEST_DIR_REL, 'diff-seed-1.json');
433
- const path2 = join(TEST_DIR_REL, 'diff-seed-2.json');
434
- await executeTool({
435
- id: 'level-diff-1',
436
- name: 'level_generate',
437
- arguments: { type: 'dungeon', width: 30, height: 20, seed: 111, output_path: path1, format: 'json' },
438
- });
439
- await executeTool({
440
- id: 'level-diff-2',
441
- name: 'level_generate',
442
- arguments: { type: 'dungeon', width: 30, height: 20, seed: 999, output_path: path2, format: 'json' },
443
- });
444
- const content1 = readFileSync(resolve(process.cwd(), path1), 'utf-8');
445
- const content2 = readFileSync(resolve(process.cwd(), path2), 'utf-8');
446
- assert.notStrictEqual(content1, content2, 'Different seeds should produce different output');
447
- });
448
- it('ASCII format produces printable map', async () => {
449
- const outPath = join(TEST_DIR_REL, 'dungeon.txt');
450
- const result = await executeTool({
451
- id: 'level-ascii',
452
- name: 'level_generate',
453
- arguments: { type: 'dungeon', width: 20, height: 15, seed: 42, output_path: outPath, format: 'ascii' },
454
- });
455
- assert.ok(!result.error, `Should not error: ${result.result}`);
456
- const absPath = resolve(process.cwd(), outPath);
457
- assert.ok(existsSync(absPath), 'ASCII file should exist');
458
- const content = readFileSync(absPath, 'utf-8');
459
- // ASCII map should contain wall (#) and floor (.) characters
460
- assert.ok(content.includes('#'), 'ASCII map should contain wall characters');
461
- assert.ok(content.includes('.'), 'ASCII map should contain floor characters');
462
- // Should have a header line
463
- assert.ok(content.includes('Level: dungeon'), 'Should have type header');
464
- assert.ok(content.includes('seed=42'), 'Should include seed in header');
465
- });
466
- it('dimensions are capped at 1000', async () => {
467
- const outPath = join(TEST_DIR_REL, 'large-level.json');
468
- const result = await executeTool({
469
- id: 'level-large',
470
- name: 'level_generate',
471
- arguments: { type: 'dungeon', width: 5000, height: 3000, seed: 1, output_path: outPath, format: 'json' },
472
- });
473
- assert.ok(!result.error, `Should not error: ${result.result}`);
474
- const data = JSON.parse(readFileSync(resolve(process.cwd(), outPath), 'utf-8'));
475
- assert.ok(data.meta.width <= 1000, 'Width should be capped at 1000');
476
- assert.ok(data.meta.height <= 1000, 'Height should be capped at 1000');
477
- });
478
- it('returns error for invalid level type', async () => {
479
- const result = await executeTool({
480
- id: 'level-bad-type',
481
- name: 'level_generate',
482
- arguments: { type: 'rpg', output_path: join(TEST_DIR_REL, 'bad-level.json') },
483
- });
484
- assert.ok(result.result.includes('Invalid type'), 'Should report invalid type');
485
- });
486
- it('tiled format produces valid Tiled JSON', async () => {
487
- const outPath = join(TEST_DIR_REL, 'dungeon-tiled.json');
488
- const result = await executeTool({
489
- id: 'level-tiled',
490
- name: 'level_generate',
491
- arguments: { type: 'dungeon', width: 20, height: 15, seed: 42, output_path: outPath, format: 'tiled' },
492
- });
493
- assert.ok(!result.error, `Should not error: ${result.result}`);
494
- const data = JSON.parse(readFileSync(resolve(process.cwd(), outPath), 'utf-8'));
495
- assert.strictEqual(data.orientation, 'orthogonal', 'Should be orthogonal orientation');
496
- assert.ok(Array.isArray(data.layers), 'Should have layers array');
497
- assert.ok(data.layers.length >= 2, 'Should have at least terrain and objects layers');
498
- assert.strictEqual(data.layers[0].type, 'tilelayer', 'First layer should be tilelayer');
499
- assert.strictEqual(data.layers[1].type, 'objectgroup', 'Second layer should be objectgroup');
500
- assert.ok(Array.isArray(data.tilesets), 'Should have tilesets');
501
- });
502
- });
503
- // ─────────────────────────────────────────────────────────────────────
504
- // 6. ecs_generate
505
- // ─────────────────────────────────────────────────────────────────────
506
- describe('ecs_generate', () => {
507
- it('Bevy generates valid Rust files (components.rs, systems.rs)', async () => {
508
- const outDir = join(TEST_DIR_REL, 'ecs-bevy');
509
- const entities = JSON.stringify([
510
- { name: 'Player', components: ['Position', 'Velocity', 'Health'] },
511
- { name: 'Enemy', components: ['Position', 'Velocity', 'Health', 'Damage'] },
512
- ]);
513
- const result = await executeTool({
514
- id: 'ecs-bevy',
515
- name: 'ecs_generate',
516
- arguments: { framework: 'bevy', entities, output_dir: outDir },
517
- });
518
- assert.ok(!result.error, `Should not error: ${result.result}`);
519
- const absDir = resolve(process.cwd(), outDir);
520
- // Check files exist
521
- assert.ok(existsSync(join(absDir, 'components.rs')), 'components.rs should exist');
522
- assert.ok(existsSync(join(absDir, 'systems.rs')), 'systems.rs should exist');
523
- assert.ok(existsSync(join(absDir, 'plugin.rs')), 'plugin.rs should exist');
524
- // Verify components.rs content
525
- const components = readFileSync(join(absDir, 'components.rs'), 'utf-8');
526
- assert.ok(components.includes('use bevy::prelude::*'), 'Should import bevy prelude');
527
- assert.ok(components.includes('#[derive(Component'), 'Should derive Component');
528
- assert.ok(components.includes('pub struct Position'), 'Should define Position component');
529
- assert.ok(components.includes('pub struct Velocity'), 'Should define Velocity component');
530
- assert.ok(components.includes('pub struct Health'), 'Should define Health component');
531
- assert.ok(components.includes('pub struct Damage'), 'Should define Damage component');
532
- // Verify systems.rs content
533
- const systems = readFileSync(join(absDir, 'systems.rs'), 'utf-8');
534
- assert.ok(systems.includes('use bevy::prelude::*'), 'Systems should import bevy prelude');
535
- assert.ok(systems.includes('use super::components::*'), 'Systems should import components');
536
- assert.ok(systems.includes('Query<'), 'Systems should use Query');
537
- });
538
- it('bitecs generates TypeScript files', async () => {
539
- const outDir = join(TEST_DIR_REL, 'ecs-bitecs');
540
- const entities = JSON.stringify([
541
- { name: 'Bullet', components: ['Position', 'Velocity'] },
542
- ]);
543
- const result = await executeTool({
544
- id: 'ecs-bitecs',
545
- name: 'ecs_generate',
546
- arguments: { framework: 'bitecs', entities, output_dir: outDir },
547
- });
548
- assert.ok(!result.error, `Should not error: ${result.result}`);
549
- const absDir = resolve(process.cwd(), outDir);
550
- assert.ok(existsSync(join(absDir, 'ecs.ts')), 'ecs.ts should exist');
551
- const code = readFileSync(join(absDir, 'ecs.ts'), 'utf-8');
552
- assert.ok(code.includes("from 'bitecs'"), 'Should import from bitecs');
553
- assert.ok(code.includes('defineComponent'), 'Should use defineComponent');
554
- assert.ok(code.includes('defineSystem'), 'Should use defineSystem');
555
- assert.ok(code.includes('Position'), 'Should reference Position component');
556
- assert.ok(code.includes('Velocity'), 'Should reference Velocity component');
557
- assert.ok(code.includes('createBullet') || code.includes('Bullet'), 'Should have Bullet entity factory');
558
- });
559
- it('generated files contain expected component and system names', async () => {
560
- const outDir = join(TEST_DIR_REL, 'ecs-names');
561
- const entities = JSON.stringify([
562
- { name: 'Ship', components: ['Position', 'Velocity', 'Shield'] },
563
- ]);
564
- const systems = JSON.stringify([
565
- { name: 'Movement', queries: ['Position', 'Velocity'] },
566
- { name: 'ShieldRegen', queries: ['Shield'] },
567
- ]);
568
- const result = await executeTool({
569
- id: 'ecs-names',
570
- name: 'ecs_generate',
571
- arguments: { framework: 'bevy', entities, output_dir: outDir, systems },
572
- });
573
- assert.ok(!result.error, `Should not error: ${result.result}`);
574
- const absDir = resolve(process.cwd(), outDir);
575
- const systemsRs = readFileSync(join(absDir, 'systems.rs'), 'utf-8');
576
- assert.ok(systemsRs.includes('movement_system'), 'Should contain movement_system');
577
- assert.ok(systemsRs.includes('shield_regen_system'), 'Should contain shield_regen_system');
578
- });
579
- it('returns error for unknown framework', async () => {
580
- const entities = JSON.stringify([{ name: 'X', components: ['Y'] }]);
581
- const result = await executeTool({
582
- id: 'ecs-bad-fw',
583
- name: 'ecs_generate',
584
- arguments: { framework: 'flecs', entities, output_dir: join(TEST_DIR_REL, 'ecs-bad') },
585
- });
586
- assert.ok(result.result.includes('Unknown ECS framework'), 'Should report unknown framework');
587
- });
588
- it('returns error for invalid entities JSON', async () => {
589
- const result = await executeTool({
590
- id: 'ecs-bad-json',
591
- name: 'ecs_generate',
592
- arguments: { framework: 'bevy', entities: 'not-valid-json', output_dir: join(TEST_DIR_REL, 'ecs-bad-json') },
593
- });
594
- assert.ok(result.result.includes('valid JSON'), 'Should report JSON parse error');
595
- });
596
- it('returns error for empty entities', async () => {
597
- const result = await executeTool({
598
- id: 'ecs-empty',
599
- name: 'ecs_generate',
600
- arguments: { framework: 'bevy', entities: '[]', output_dir: join(TEST_DIR_REL, 'ecs-empty') },
601
- });
602
- assert.ok(result.result.includes('At least one entity'), 'Should require at least one entity');
603
- });
604
- });
605
- // ─────────────────────────────────────────────────────────────────────
606
- // 7. Error handling
607
- // ─────────────────────────────────────────────────────────────────────
608
- describe('Error handling', () => {
609
- it('game_config: invalid JSON in settings returns friendly error', async () => {
610
- const result = await executeTool({
611
- id: 'err-config-json',
612
- name: 'game_config',
613
- arguments: { engine: 'godot', config_type: 'project', settings: '{bad json!' },
614
- });
615
- assert.ok(result.result.includes('valid JSON'), 'Should return JSON parse error');
616
- });
617
- it('mesh_generate: invalid params JSON returns friendly error', async () => {
618
- const result = await executeTool({
619
- id: 'err-mesh-json',
620
- name: 'mesh_generate',
621
- arguments: { shape: 'sphere', output_path: join(TEST_DIR_REL, 'err.obj'), params: 'not-json' },
622
- });
623
- assert.ok(result.result.includes('valid JSON'), 'Should return JSON parse error');
624
- });
625
- it('level_generate: invalid params JSON returns friendly error', async () => {
626
- const result = await executeTool({
627
- id: 'err-level-json',
628
- name: 'level_generate',
629
- arguments: { type: 'dungeon', output_path: join(TEST_DIR_REL, 'err-level.json'), params: '{{invalid' },
630
- });
631
- assert.ok(result.result.includes('valid JSON'), 'Should return JSON parse error');
632
- });
633
- it('physics_setup: invalid params JSON returns friendly error', async () => {
634
- const result = await executeTool({
635
- id: 'err-physics-json',
636
- name: 'physics_setup',
637
- arguments: { type: 'rigidbody', engine: 'rapier', output_path: join(TEST_DIR_REL, 'err-physics.ts'), params: 'bad' },
638
- });
639
- assert.ok(result.result.includes('valid JSON'), 'Should return JSON parse error');
640
- });
641
- it('material_graph: invalid params JSON returns friendly error', async () => {
642
- const result = await executeTool({
643
- id: 'err-material-json',
644
- name: 'material_graph',
645
- arguments: { material_type: 'pbr', engine: 'three', params: '{broken' },
646
- });
647
- assert.ok(result.result.includes('valid JSON'), 'Should return JSON parse error');
648
- });
649
- it('scaffold_game: missing engine parameter returns error', async () => {
650
- const result = await executeTool({
651
- id: 'err-scaffold-no-engine',
652
- name: 'scaffold_game',
653
- arguments: { name: 'Test', output_dir: join(TEST_DIR_REL, 'err-scaffold') },
654
- });
655
- // When engine is missing, it defaults to String(undefined) = 'undefined' which is unknown
656
- assert.ok(result.result.includes('Unknown engine') || result.result.includes('Error'), 'Should report error for missing engine');
657
- });
658
- it('game_config: unknown config_type returns error', async () => {
659
- const result = await executeTool({
660
- id: 'err-config-type',
661
- name: 'game_config',
662
- arguments: { engine: 'godot', config_type: 'networking', settings: '{}' },
663
- });
664
- assert.ok(result.result.includes('Unknown config_type') || result.result.includes('Error'), 'Should report unknown config_type');
665
- });
666
- it('mesh_generate: unknown shape returns error with supported list', async () => {
667
- const result = await executeTool({
668
- id: 'err-mesh-shape',
669
- name: 'mesh_generate',
670
- arguments: { shape: 'octahedron', output_path: join(TEST_DIR_REL, 'err.obj') },
671
- });
672
- assert.ok(result.result.includes('Unknown shape'), 'Should report unknown shape');
673
- assert.ok(result.result.includes('plane'), 'Should list supported shapes');
674
- assert.ok(result.result.includes('cube'), 'Should list supported shapes');
675
- assert.ok(result.result.includes('sphere'), 'Should list supported shapes');
676
- });
677
- });
678
- // ─────────────────────────────────────────────────────────────────────
679
- // 8. Security
680
- // ─────────────────────────────────────────────────────────────────────
681
- describe('Security', () => {
682
- it('path traversal: ../../etc/passwd as output_path is rejected', async () => {
683
- const result = await executeTool({
684
- id: 'sec-traversal',
685
- name: 'mesh_generate',
686
- arguments: { shape: 'cube', output_path: '../../etc/passwd' },
687
- });
688
- assert.ok(result.error, 'Should return an error');
689
- assert.ok(result.result.includes('Path must be within the working directory'), 'Should reject path traversal');
690
- });
691
- it('scaffold_game: path traversal output_dir is rejected', async () => {
692
- const result = await executeTool({
693
- id: 'sec-scaffold-traversal',
694
- name: 'scaffold_game',
695
- arguments: { engine: 'godot', name: 'Test', output_dir: '../../../tmp/evil' },
696
- });
697
- assert.ok(result.error, 'Should return an error for path traversal');
698
- assert.ok(result.result.includes('Path must be within the working directory'), 'Should reject traversal');
699
- });
700
- it('level_generate: absolute path outside cwd is rejected', async () => {
701
- const result = await executeTool({
702
- id: 'sec-level-abs',
703
- name: 'level_generate',
704
- arguments: { type: 'dungeon', output_path: '/tmp/evil-level.json' },
705
- });
706
- assert.ok(result.error, 'Should return an error for absolute path outside cwd');
707
- assert.ok(result.result.includes('Path must be within the working directory'), 'Should reject path outside cwd');
708
- });
709
- it('ecs_generate: path traversal output_dir is rejected', async () => {
710
- const entities = JSON.stringify([{ name: 'X', components: ['Y'] }]);
711
- const result = await executeTool({
712
- id: 'sec-ecs-traversal',
713
- name: 'ecs_generate',
714
- arguments: { framework: 'bevy', entities, output_dir: '../../etc' },
715
- });
716
- assert.ok(result.error, 'Should return an error for path traversal');
717
- assert.ok(result.result.includes('Path must be within the working directory'), 'Should reject traversal');
718
- });
719
- it('shader_debug: .env as inline source is analyzed as code (no file read)', async () => {
720
- // shader_debug accepts inline source code or file paths.
721
- // .env as a path that doesn't exist will be treated as inline source text.
722
- const result = await executeTool({
723
- id: 'sec-shader-env',
724
- name: 'shader_debug',
725
- arguments: { source: '.env', language: 'glsl' },
726
- });
727
- assert.ok(!result.error, 'Should process .env as inline source (not a file)');
728
- assert.ok(result.result.includes('Shader Analysis Report'), 'Should produce analysis report');
729
- });
730
- it('mesh_generate: segments are capped (sphere rings/segments bounded at 256/512)', async () => {
731
- const outPath = join(TEST_DIR_REL, 'large-sphere.obj');
732
- const result = await executeTool({
733
- id: 'sec-mesh-large',
734
- name: 'mesh_generate',
735
- arguments: {
736
- shape: 'sphere',
737
- output_path: outPath,
738
- params: '{"rings": 100000, "segments": 100000}',
739
- },
740
- });
741
- assert.ok(!result.error, `Should not error: ${result.result}`);
742
- const absPath = resolve(process.cwd(), outPath);
743
- assert.ok(existsSync(absPath), 'File should be created');
744
- const obj = readFileSync(absPath, 'utf-8');
745
- const vertexLines = obj.split('\n').filter((l) => l.startsWith('v '));
746
- // rings capped at 256, segments capped at 512
747
- // max vertices = (256+1) * (512+1) = 131841
748
- assert.ok(vertexLines.length <= 131841, `Vertex count (${vertexLines.length}) should be bounded by caps`);
749
- // Verify it didn't actually create 100000x100000 vertices
750
- assert.ok(vertexLines.length < 200000, 'Should not create unbounded vertices');
751
- });
752
- it('level_generate: dimensions capped at 1000 even when requesting larger', async () => {
753
- const outPath = join(TEST_DIR_REL, 'capped-level.json');
754
- const result = await executeTool({
755
- id: 'sec-level-cap',
756
- name: 'level_generate',
757
- arguments: { type: 'maze', width: 99999, height: 99999, seed: 1, output_path: outPath, format: 'json' },
758
- });
759
- assert.ok(!result.error, `Should not error: ${result.result}`);
760
- const data = JSON.parse(readFileSync(resolve(process.cwd(), outPath), 'utf-8'));
761
- assert.ok(data.meta.width <= 1000, `Width (${data.meta.width}) should be capped at 1000`);
762
- assert.ok(data.meta.height <= 1000, `Height (${data.meta.height}) should be capped at 1000`);
763
- });
764
- });
765
- // ─────────────────────────────────────────────────────────────────────
766
- // Additional tool tests
767
- // ─────────────────────────────────────────────────────────────────────
768
- describe('game_config', () => {
769
- it('generates Godot project config', async () => {
770
- const outPath = join(TEST_DIR_REL, 'config-project.godot');
771
- const result = await executeTool({
772
- id: 'config-godot',
773
- name: 'game_config',
774
- arguments: {
775
- engine: 'godot',
776
- config_type: 'project',
777
- settings: JSON.stringify({ name: 'MyGame', main_scene: 'res://main.tscn' }),
778
- path: outPath,
779
- },
780
- });
781
- assert.ok(!result.error, `Should not error: ${result.result}`);
782
- assert.ok(result.result.includes('Generated godot project config'), 'Should confirm generation');
783
- const absPath = resolve(process.cwd(), outPath);
784
- assert.ok(existsSync(absPath), 'Config file should exist');
785
- const content = readFileSync(absPath, 'utf-8');
786
- assert.ok(content.includes('[application]'), 'Should have application section');
787
- assert.ok(content.includes('config/name="MyGame"'), 'Should contain project name');
788
- });
789
- it('generates Bevy Cargo.toml config', async () => {
790
- const outPath = join(TEST_DIR_REL, 'config-cargo.toml');
791
- const result = await executeTool({
792
- id: 'config-bevy',
793
- name: 'game_config',
794
- arguments: {
795
- engine: 'bevy',
796
- config_type: 'project',
797
- settings: JSON.stringify({ name: 'CoolGame', version: '0.2.0' }),
798
- path: outPath,
799
- },
800
- });
801
- assert.ok(!result.error, `Should not error: ${result.result}`);
802
- const absPath = resolve(process.cwd(), outPath);
803
- const content = readFileSync(absPath, 'utf-8');
804
- assert.ok(content.includes('[package]'), 'Should have package section');
805
- assert.ok(content.includes('coolgame') || content.includes('cool-game'), 'Name should be sanitized');
806
- assert.ok(content.includes('0.2.0'), 'Version should be present');
807
- assert.ok(content.includes('bevy'), 'Should reference bevy dependency');
808
- });
809
- });
810
- describe('material_graph', () => {
811
- it('generates PBR material for Three.js', async () => {
812
- const outPath = join(TEST_DIR_REL, 'material-pbr.ts');
813
- const result = await executeTool({
814
- id: 'mat-pbr',
815
- name: 'material_graph',
816
- arguments: {
817
- material_type: 'pbr',
818
- engine: 'three',
819
- output_path: outPath,
820
- params: JSON.stringify({ roughness: 0.3, metalness: 0.8 }),
821
- },
822
- });
823
- assert.ok(!result.error, `Should not error: ${result.result}`);
824
- const absPath = resolve(process.cwd(), outPath);
825
- assert.ok(existsSync(absPath), 'Material file should exist');
826
- const code = readFileSync(absPath, 'utf-8');
827
- assert.ok(code.includes("import * as THREE from 'three'"), 'Should import Three.js');
828
- assert.ok(code.includes('MeshStandardMaterial'), 'Should use MeshStandardMaterial');
829
- assert.ok(code.includes('0.3'), 'Should use specified roughness');
830
- assert.ok(code.includes('0.8'), 'Should use specified metalness');
831
- });
832
- it('generates water material for Godot', async () => {
833
- const result = await executeTool({
834
- id: 'mat-water',
835
- name: 'material_graph',
836
- arguments: {
837
- material_type: 'water',
838
- engine: 'godot',
839
- },
840
- });
841
- assert.ok(!result.error, `Should not error: ${result.result}`);
842
- assert.ok(result.result.includes('shader_type spatial'), 'Should generate Godot spatial shader');
843
- assert.ok(result.result.includes('water_color'), 'Should have water color uniform');
844
- });
845
- it('returns error for unknown engine', async () => {
846
- const result = await executeTool({
847
- id: 'mat-bad-engine',
848
- name: 'material_graph',
849
- arguments: { material_type: 'pbr', engine: 'unreal' },
850
- });
851
- assert.ok(result.result.includes('Unknown engine'), 'Should report unknown engine');
852
- });
853
- it('returns error for unknown material type', async () => {
854
- const result = await executeTool({
855
- id: 'mat-bad-type',
856
- name: 'material_graph',
857
- arguments: { material_type: 'lava', engine: 'three' },
858
- });
859
- assert.ok(result.result.includes('Unknown material_type'), 'Should report unknown material type');
860
- });
861
- });
862
- describe('physics_setup', () => {
863
- it('generates rapier rigidbody code', async () => {
864
- const outPath = join(TEST_DIR_REL, 'physics-rapier.ts');
865
- const result = await executeTool({
866
- id: 'physics-rapier',
867
- name: 'physics_setup',
868
- arguments: {
869
- type: 'rigidbody',
870
- engine: 'rapier',
871
- output_path: outPath,
872
- params: JSON.stringify({ mass: 2.0, friction: 0.8 }),
873
- },
874
- });
875
- assert.ok(!result.error, `Should not error: ${result.result}`);
876
- const absPath = resolve(process.cwd(), outPath);
877
- assert.ok(existsSync(absPath), 'Physics file should exist');
878
- const code = readFileSync(absPath, 'utf-8');
879
- assert.ok(code.includes('RAPIER'), 'Should use RAPIER');
880
- assert.ok(code.includes('2') || code.includes('2.0'), 'Should use specified mass');
881
- assert.ok(code.includes('0.8'), 'Should use specified friction');
882
- });
883
- it('returns error for invalid physics type', async () => {
884
- const result = await executeTool({
885
- id: 'physics-bad-type',
886
- name: 'physics_setup',
887
- arguments: { type: 'fluid', engine: 'rapier', output_path: join(TEST_DIR_REL, 'bad-physics.ts') },
888
- });
889
- assert.ok(result.result.includes('Invalid type'), 'Should report invalid type');
890
- });
891
- it('returns error for invalid engine', async () => {
892
- const result = await executeTool({
893
- id: 'physics-bad-engine',
894
- name: 'physics_setup',
895
- arguments: { type: 'rigidbody', engine: 'havok', output_path: join(TEST_DIR_REL, 'bad-engine.ts') },
896
- });
897
- assert.ok(result.result.includes('Invalid engine'), 'Should report invalid engine');
898
- });
899
- });
900
- describe('level_generate — additional types', () => {
901
- it('platformer level generates valid output', async () => {
902
- const outPath = join(TEST_DIR_REL, 'platformer.json');
903
- const result = await executeTool({
904
- id: 'level-platformer',
905
- name: 'level_generate',
906
- arguments: { type: 'platformer', width: 40, height: 20, seed: 55, output_path: outPath, format: 'json' },
907
- });
908
- assert.ok(!result.error, `Should not error: ${result.result}`);
909
- assert.ok(result.result.includes('platformer'), 'Should mention level type');
910
- const data = JSON.parse(readFileSync(resolve(process.cwd(), outPath), 'utf-8'));
911
- assert.strictEqual(data.meta.type, 'platformer');
912
- });
913
- it('maze level generates valid output', async () => {
914
- const outPath = join(TEST_DIR_REL, 'maze.json');
915
- const result = await executeTool({
916
- id: 'level-maze',
917
- name: 'level_generate',
918
- arguments: { type: 'maze', width: 21, height: 21, seed: 77, output_path: outPath, format: 'json' },
919
- });
920
- assert.ok(!result.error, `Should not error: ${result.result}`);
921
- const data = JSON.parse(readFileSync(resolve(process.cwd(), outPath), 'utf-8'));
922
- assert.strictEqual(data.meta.type, 'maze');
923
- assert.ok(data.map.length > 0, 'Should have map data');
924
- });
925
- it('arena level generates valid output', async () => {
926
- const outPath = join(TEST_DIR_REL, 'arena.json');
927
- const result = await executeTool({
928
- id: 'level-arena',
929
- name: 'level_generate',
930
- arguments: { type: 'arena', width: 30, height: 30, seed: 88, output_path: outPath, format: 'json' },
931
- });
932
- assert.ok(!result.error, `Should not error: ${result.result}`);
933
- const data = JSON.parse(readFileSync(resolve(process.cwd(), outPath), 'utf-8'));
934
- assert.strictEqual(data.meta.type, 'arena');
935
- });
936
- });
937
- //# sourceMappingURL=gamedev.test.js.map