@inneranimalmedia/agentsam-sdk 2.6.7 → 2.6.9

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 (371) hide show
  1. package/README.md +37 -0
  2. package/apps/README.md +25 -0
  3. package/apps/cad-creator/shared/cad/package.json +1 -1
  4. package/apps/client-cms-editor/backend/package.json +4 -6
  5. package/apps/client-cms-editor/frontend/package.json +6 -8
  6. package/apps/client-cms-editor/frontend/tsconfig.json +27 -8
  7. package/apps/client-cms-editor/package.json +1 -1
  8. package/apps/client-cms-editor/shared/cms/package.json +4 -6
  9. package/docs/LOCAL_ENGINE_COMPUTE_AUDIT_PLAN.md +299 -0
  10. package/docs/REPO_FILE_MAP.txt +132 -0
  11. package/migrations/d1/0018_goap_control_plane_remaster.sql +40 -0
  12. package/migrations/d1/0019_agentsam_agent_run_plan_todo.sql +14 -0
  13. package/migrations/d1/README_PORTABLE_CONTROL_PLANE.md +20 -9
  14. package/migrations/runtime/0002_goap_blackboard_v1.sql +15 -0
  15. package/migrations/runtime/0004_agent_run_plan_linkage.sql +8 -0
  16. package/native/agentsam-machine/cli/Cargo.toml +8 -1
  17. package/native/agentsam-machine/cli/README.md +21 -0
  18. package/native/agentsam-machine/core/Cargo.toml +7 -0
  19. package/native/agentsam-machine/core/README.md +14 -0
  20. package/native/agentsam-machine/core/build.rs +33 -0
  21. package/native/agentsam-machine/core/contracts/source-types.v1.json +353 -0
  22. package/native/agentsam-machine/core/src/lib.rs +6 -0
  23. package/native/agentsam-machine/core/src/source_types.rs +2 -2
  24. package/package.json +31 -10
  25. package/packages/agentsam-brand/package.json +1 -1
  26. package/packages/agentsam-contracts/package.json +71 -20
  27. package/packages/agentsam-contracts/scripts/build.mjs +18 -0
  28. package/packages/agentsam-contracts/test/contracts.test.mjs +4 -1
  29. package/packages/agentsam-contracts/test/repository.test.mjs +4 -1
  30. package/packages/agentsam-contracts/tsconfig.build.json +10 -0
  31. package/packages/agentsam-errors/package.json +3 -2
  32. package/packages/agentsam-errors/src/index.js +1 -0
  33. package/packages/agentsam-errors/src/tool.js +56 -0
  34. package/packages/agentsam-errors/test/tool.test.mjs +58 -0
  35. package/packages/agentsam-goap/README.md +52 -0
  36. package/packages/agentsam-goap/package.json +37 -0
  37. package/packages/agentsam-goap/src/adapters/d1-sqlite.js +570 -0
  38. package/packages/agentsam-goap/src/adapters/memory.js +199 -0
  39. package/packages/agentsam-goap/src/contracts.js +226 -0
  40. package/packages/agentsam-goap/src/control-plane.js +112 -0
  41. package/packages/agentsam-goap/src/errors.js +157 -0
  42. package/packages/agentsam-goap/src/index.js +5 -0
  43. package/packages/agentsam-goap/src/world.js +202 -0
  44. package/packages/agentsam-goap/test/goap-control-plane.test.mjs +245 -0
  45. package/packages/agentsam-goap/test/world.test.mjs +79 -0
  46. package/packages/agentsam-knowledge/package.json +3 -2
  47. package/packages/agentsam-nav/package.json +1 -1
  48. package/packages/agentsam-queue-control/package.json +1 -1
  49. package/packages/agentsam-rapid-rust/src/main.rs +1 -0
  50. package/packages/agentsam-repository/package.json +3 -2
  51. package/packages/agentsam-repository/src/goap.js +13 -14
  52. package/packages/agentsam-repository/src/tickets.js +15 -22
  53. package/packages/agentsam-repository/test/goap-tickets-workspace-state.test.mjs +19 -8
  54. package/packages/agentsam-vault/package.json +8 -5
  55. package/packages/agentsam-workbench/package.json +44 -17
  56. package/packages/connectors/cloudflare/package.json +4 -2
  57. package/packages/heuristic-theme/package.json +1 -1
  58. package/packages/identity/package.json +4 -3
  59. package/packages/identity/tests/lane1-packed-consumer.test.mjs +10 -2
  60. package/packages/providers/completeful/package.json +1 -1
  61. package/packages/theme-church-site/README.md +2 -2
  62. package/packages/theme-church-site/package.json +3 -4
  63. package/packages/theme-church-site/src/index.js +1 -1
  64. package/packages/theme-church-site/test/theme.test.mjs +1 -1
  65. package/packages/theme-companions-site/README.md +2 -2
  66. package/packages/theme-companions-site/package.json +3 -4
  67. package/packages/theme-companions-site/src/index.js +1 -1
  68. package/packages/theme-companions-site/test/theme.test.mjs +1 -1
  69. package/packages/theme-floors-site/README.md +2 -2
  70. package/packages/theme-floors-site/package.json +3 -4
  71. package/packages/theme-floors-site/src/index.js +1 -1
  72. package/packages/theme-floors-site/test/theme.test.mjs +1 -1
  73. package/packages/theme-fuelnfree-site/README.md +2 -2
  74. package/packages/theme-fuelnfree-site/package.json +3 -4
  75. package/packages/theme-fuelnfree-site/src/index.js +1 -1
  76. package/packages/theme-fuelnfree-site/test/theme.test.mjs +1 -1
  77. package/packages/theme-handyman-site/README.md +2 -2
  78. package/packages/theme-handyman-site/package.json +3 -4
  79. package/packages/theme-handyman-site/src/index.js +1 -1
  80. package/packages/theme-handyman-site/test/theme.test.mjs +1 -1
  81. package/packages/theme-insurance-site/README.md +2 -2
  82. package/packages/theme-insurance-site/package.json +3 -4
  83. package/packages/theme-insurance-site/src/index.js +1 -1
  84. package/packages/theme-insurance-site/test/theme.test.mjs +1 -1
  85. package/packages/theme-scenes/package.json +1 -1
  86. package/packages/theme-shinshu-site/README.md +2 -2
  87. package/packages/theme-shinshu-site/package.json +3 -4
  88. package/packages/theme-shinshu-site/src/index.js +1 -1
  89. package/packages/theme-shinshu-site/test/theme.test.mjs +1 -1
  90. package/packages/work-graph/package.json +3 -2
  91. package/protocol/local-engine/benchmark.v1.schema.json +14 -0
  92. package/protocol/local-engine/engine.v1.schema.json +17 -0
  93. package/python/agentsam_sdk/repository/intelligence/discovery.py +27 -2
  94. package/python/agentsam_sdk/repository/intelligence/git.py +4 -0
  95. package/python/tests/test_repository_intelligence.py +30 -0
  96. package/src/cli/command-catalog.js +3 -1
  97. package/src/cli.js +20 -1
  98. package/src/commands/app.js +10 -0
  99. package/src/commands/engine.js +10 -0
  100. package/src/commands/goap-world.js +134 -0
  101. package/src/commands/goap.js +11 -4
  102. package/src/commands/machine-binary.js +33 -27
  103. package/src/commands/machine-runtime.js +266 -0
  104. package/src/commands/machine.js +155 -51
  105. package/src/commands/package.js +537 -0
  106. package/src/commands/plan-ledger.js +370 -0
  107. package/src/commands/plan.js +183 -0
  108. package/src/commands/runtime.js +25 -10
  109. package/src/commands/setup.js +30 -6
  110. package/src/commands/skill.js +78 -17
  111. package/src/commands/terminal.js +20 -8
  112. package/src/errors/contract.js +4 -4
  113. package/src/errors/diagnostic.js +1 -1
  114. package/src/errors/index.js +1 -1
  115. package/src/index.js +20 -0
  116. package/src/indexing/ingest/materials.js +237 -30
  117. package/src/knowledge/source.js +1 -1
  118. package/src/lib/setup/runtime.js +4 -2
  119. package/src/lib/slash-commands.js +1 -1
  120. package/src/local/runtime-store.js +24 -2
  121. package/src/local/sqlite.js +17 -0
  122. package/src/local-engine/assets.js +37 -0
  123. package/src/local-engine/audit.js +133 -0
  124. package/src/local-engine/benchmark.js +26 -0
  125. package/src/local-engine/contracts.js +101 -0
  126. package/src/local-engine/engines.js +142 -0
  127. package/src/local-engine/index.js +18 -0
  128. package/src/local-engine/runtime.js +39 -0
  129. package/src/sam/operations/package-audit.js +41 -0
  130. package/src/sam/seed.js +2 -0
  131. package/skills/grok-auth/SKILL.md +0 -110
  132. package/skills/grok-auth/agentsam.skill.json +0 -25
  133. package/skills/grok-auth/references/grok-identity.md +0 -64
  134. package/skills/grok-auth/references/per-user-data.md +0 -49
  135. package/skills/grok-auth/references/prewired-and-env.md +0 -54
  136. package/skills/grok-auth/references/session-ui.md +0 -133
  137. package/skills/grok-auth/references/sign-in-methods.md +0 -55
  138. package/skills/grok-auth/references/wiring.md +0 -71
  139. package/skills/grok-building-games/SKILL.md +0 -213
  140. package/skills/grok-building-games/agentsam.skill.json +0 -25
  141. package/skills/grok-building-games/references/3d-libs.md +0 -64
  142. package/skills/grok-building-games/references/ai-pathfinding.md +0 -122
  143. package/skills/grok-building-games/references/audio.md +0 -129
  144. package/skills/grok-building-games/references/babylon.md +0 -202
  145. package/skills/grok-building-games/references/collision-physics.md +0 -122
  146. package/skills/grok-building-games/references/ecs-architecture.md +0 -111
  147. package/skills/grok-building-games/references/game-feel-juice.md +0 -110
  148. package/skills/grok-building-games/references/genres/board-card-chess.md +0 -89
  149. package/skills/grok-building-games/references/genres/endless-runner.md +0 -83
  150. package/skills/grok-building-games/references/genres/fps.md +0 -105
  151. package/skills/grok-building-games/references/genres/platformer-2d.md +0 -97
  152. package/skills/grok-building-games/references/genres/puzzle-match3-tetris.md +0 -131
  153. package/skills/grok-building-games/references/genres/racing-kart.md +0 -106
  154. package/skills/grok-building-games/references/genres/topdown-twin-stick.md +0 -97
  155. package/skills/grok-building-games/references/genres/tower-defense.md +0 -84
  156. package/skills/grok-building-games/references/genres/voxel-minecraft.md +0 -89
  157. package/skills/grok-building-games/references/input.md +0 -139
  158. package/skills/grok-building-games/references/phaser.md +0 -277
  159. package/skills/grok-building-games/references/procedural-generation.md +0 -141
  160. package/skills/grok-building-games/references/save-persistence.md +0 -108
  161. package/skills/grok-building-games/references/threejs-foundational.md +0 -148
  162. package/skills/grok-controls/SKILL.md +0 -274
  163. package/skills/grok-controls/agentsam.skill.json +0 -25
  164. package/skills/grok-design-ui/SKILL.md +0 -122
  165. package/skills/grok-design-ui/agentsam.skill.json +0 -25
  166. package/skills/grok-design-ui/references/animations.md +0 -379
  167. package/skills/grok-design-ui/references/performance.md +0 -88
  168. package/skills/grok-design-ui/references/refined-ui.md +0 -384
  169. package/skills/grok-design-ui/references/surfaces.md +0 -247
  170. package/skills/grok-design-ui/references/typography.md +0 -123
  171. package/skills/grok-game-animation-frames/SKILL.md +0 -84
  172. package/skills/grok-game-animation-frames/agentsam.skill.json +0 -25
  173. package/skills/grok-game-asset-core/SKILL.md +0 -69
  174. package/skills/grok-game-asset-core/agentsam.skill.json +0 -25
  175. package/skills/grok-game-character-consistency/SKILL.md +0 -69
  176. package/skills/grok-game-character-consistency/agentsam.skill.json +0 -25
  177. package/skills/grok-game-tilesets/SKILL.md +0 -65
  178. package/skills/grok-game-tilesets/agentsam.skill.json +0 -25
  179. package/skills/grok-game-ui-icons/SKILL.md +0 -56
  180. package/skills/grok-game-ui-icons/agentsam.skill.json +0 -25
  181. package/skills/grok-generate2dmap/LICENSE +0 -21
  182. package/skills/grok-generate2dmap/SKILL.md +0 -120
  183. package/skills/grok-generate2dmap/SOURCE.md +0 -6
  184. package/skills/grok-generate2dmap/agentsam.skill.json +0 -25
  185. package/skills/grok-generate2dmap/references/deliverables.md +0 -101
  186. package/skills/grok-generate2dmap/references/layered-map-contract.md +0 -209
  187. package/skills/grok-generate2dmap/references/map-strategies.md +0 -341
  188. package/skills/grok-generate2dmap/references/object-production-gate.md +0 -24
  189. package/skills/grok-generate2dmap/references/pipeline.md +0 -149
  190. package/skills/grok-generate2dmap/references/prop-pack-contract.md +0 -174
  191. package/skills/grok-generate2dmap/references/side-scroll-stages.md +0 -29
  192. package/skills/grok-generate2dmap/scripts/compose_layered_preview.py +0 -157
  193. package/skills/grok-generate2dmap/scripts/extract_prop_pack.py +0 -369
  194. package/skills/grok-generate2dsprite/LICENSE +0 -21
  195. package/skills/grok-generate2dsprite/SKILL.md +0 -313
  196. package/skills/grok-generate2dsprite/SOURCE.md +0 -6
  197. package/skills/grok-generate2dsprite/agentsam.skill.json +0 -25
  198. package/skills/grok-generate2dsprite/references/modes.md +0 -124
  199. package/skills/grok-generate2dsprite/references/prompt-rules.md +0 -315
  200. package/skills/grok-generate2dsprite/scripts/generate2dsprite.py +0 -1031
  201. package/skills/grok-generate2dsprite/scripts/make_layout_guide.py +0 -109
  202. package/skills/grok-imagine/SKILL.md +0 -201
  203. package/skills/grok-imagine/agentsam.skill.json +0 -25
  204. package/skills/grok-multiplayer-p2p/SKILL.md +0 -111
  205. package/skills/grok-multiplayer-p2p/agentsam.skill.json +0 -25
  206. package/skills/grok-multiplayer-p2p/references/react-binding.md +0 -144
  207. package/skills/grok-multiplayer-p2p/references/signaling-relay.md +0 -269
  208. package/skills/grok-neon/SKILL.md +0 -157
  209. package/skills/grok-neon/agentsam.skill.json +0 -25
  210. package/skills/grok-og/SKILL.md +0 -102
  211. package/skills/grok-og/agentsam.skill.json +0 -25
  212. package/skills/grok-og/references/brand-pass.md +0 -53
  213. package/skills/grok-og/references/custom-card.md +0 -107
  214. package/skills/grok-og/references/favicon-and-icons.md +0 -48
  215. package/skills/grok-og/references/og-type-contract.md +0 -18
  216. package/skills/grok-og/references/placeholder-card.md +0 -21
  217. package/skills/grok-og/references/x-banner.md +0 -41
  218. package/skills/grok-threejs/SKILL.md +0 -67
  219. package/skills/grok-threejs/agentsam.skill.json +0 -25
  220. package/skills/grok-threejs/references/llms-full.txt +0 -2780
  221. package/skills/grok-video2dsprite/LICENSE +0 -21
  222. package/skills/grok-video2dsprite/SKILL.md +0 -236
  223. package/skills/grok-video2dsprite/SOURCE.md +0 -6
  224. package/skills/grok-video2dsprite/agentsam.skill.json +0 -25
  225. package/skills/grok-video2dsprite/references/pipeline.md +0 -90
  226. package/skills/grok-video2dsprite/references/prompt-rules.md +0 -63
  227. package/skills/grok-video2dsprite/scripts/video2dsprite.py +0 -490
  228. package/skills/grok-xai-api/SKILL.md +0 -152
  229. package/skills/grok-xai-api/agentsam.skill.json +0 -25
  230. package/test/account-session.test.mjs +0 -101
  231. package/test/agent-capabilities.test.mjs +0 -67
  232. package/test/app-authority-context.test.mjs +0 -32
  233. package/test/app-building-skills.test.mjs +0 -61
  234. package/test/apps-scaffold-contract.test.mjs +0 -115
  235. package/test/blender-cad.test.mjs +0 -146
  236. package/test/cad-docker.test.mjs +0 -96
  237. package/test/capabilities.test.mjs +0 -133
  238. package/test/cli/api-key-env-whoami.test.mjs +0 -129
  239. package/test/cli/catalog-authority.test.mjs +0 -64
  240. package/test/cli/codebaseindex-plan-ux.test.mjs +0 -37
  241. package/test/cli/eval-live.test.mjs +0 -219
  242. package/test/cli/go.test.mjs +0 -128
  243. package/test/cli/local-vault-and-provider-setup.test.mjs +0 -268
  244. package/test/cli/machine-command.test.mjs +0 -34
  245. package/test/cli/mcp-client.test.mjs +0 -256
  246. package/test/cli/preferences-runtime.test.mjs +0 -11
  247. package/test/cli/runtime-persist.test.mjs +0 -56
  248. package/test/cli/runtime-ui.test.mjs +0 -141
  249. package/test/cli/rust-command.test.mjs +0 -21
  250. package/test/cli/skill-npm-and-env.test.mjs +0 -52
  251. package/test/cli/status-actions.test.mjs +0 -88
  252. package/test/cli/wireframes-go-registry.test.mjs +0 -139
  253. package/test/cli-preferences.test.mjs +0 -46
  254. package/test/cloudflare-connector.test.mjs +0 -93
  255. package/test/cloudflare-runtime.test.mjs +0 -82
  256. package/test/context.test.mjs +0 -159
  257. package/test/credentials-audit.test.mjs +0 -113
  258. package/test/deploy-health-scan.test.mjs +0 -95
  259. package/test/deploy-receipt.test.mjs +0 -91
  260. package/test/dockerize.test.mjs +0 -93
  261. package/test/error-diagnostics.test.mjs +0 -124
  262. package/test/eval-context.test.mjs +0 -37
  263. package/test/execution-approvals.test.mjs +0 -27
  264. package/test/fixtures/cad/courtyard-house.json +0 -208
  265. package/test/fixtures/knowledge-rpc-worker.mjs +0 -16
  266. package/test/fixtures/project-authority/customer-app/.agentsam/app.json +0 -5
  267. package/test/fixtures/project-authority/customer-app/apps/my-product/index.ts +0 -1
  268. package/test/fixtures/project-authority/customer-app/wrangler.toml +0 -17
  269. package/test/gcloud-auth.test.mjs +0 -111
  270. package/test/go/build-source-identity.test.mjs +0 -31
  271. package/test/go/cloudflare-probe.test.mjs +0 -317
  272. package/test/go/distribution.test.mjs +0 -28
  273. package/test/google-cloud-connection.test.mjs +0 -83
  274. package/test/google-cloud-inventory.test.mjs +0 -64
  275. package/test/indexing-provider.test.mjs +0 -29
  276. package/test/init-options.test.mjs +0 -35
  277. package/test/integration/ai-access-onboarding.test.mjs +0 -47
  278. package/test/integration/app-command.test.mjs +0 -85
  279. package/test/integration/autorag-project-authority.integration.test.mjs +0 -51
  280. package/test/integration/autorag-runtime-discovery.test.mjs +0 -107
  281. package/test/integration/cad-discovery.test.mjs +0 -158
  282. package/test/integration/cad-docker-executor.test.mjs +0 -249
  283. package/test/integration/cad-execution.test.mjs +0 -184
  284. package/test/integration/cad-project-app.test.mjs +0 -31
  285. package/test/integration/cad-project-d1.test.mjs +0 -25
  286. package/test/integration/cad-project-native.test.mjs +0 -24
  287. package/test/integration/cad-project-workflow.test.mjs +0 -9
  288. package/test/integration/cad-project.test.mjs +0 -85
  289. package/test/integration/cli-help.test.mjs +0 -41
  290. package/test/integration/cms-app-scaffold.test.mjs +0 -77
  291. package/test/integration/cms-site-tenancy-contract.test.mjs +0 -268
  292. package/test/integration/codebaseindex-ingest.test.mjs +0 -255
  293. package/test/integration/core-client.integration.test.mjs +0 -55
  294. package/test/integration/database-hosted-honesty.test.mjs +0 -49
  295. package/test/integration/desktop-keychain-boundary.test.mjs +0 -45
  296. package/test/integration/error-runtime-rpc.test.mjs +0 -71
  297. package/test/integration/features-resolve.test.mjs +0 -147
  298. package/test/integration/hosted-work-host-authority.test.mjs +0 -47
  299. package/test/integration/icon-registry.test.mjs +0 -67
  300. package/test/integration/ingest-discover-models.test.mjs +0 -30
  301. package/test/integration/inspect-path-cli.test.mjs +0 -46
  302. package/test/integration/install-script.test.mjs +0 -110
  303. package/test/integration/inventory-core.test.mjs +0 -53
  304. package/test/integration/inventory-eligibility.test.mjs +0 -59
  305. package/test/integration/inventory-evidence.test.mjs +0 -125
  306. package/test/integration/knowledge-rpc.test.mjs +0 -112
  307. package/test/integration/local-fs.test.mjs +0 -113
  308. package/test/integration/local-provider-bridge.test.mjs +0 -65
  309. package/test/integration/local-studio-settings-production.test.mjs +0 -40
  310. package/test/integration/lockfile-sync.test.mjs +0 -26
  311. package/test/integration/merkle-cli.test.mjs +0 -61
  312. package/test/integration/merkle-persistence-identity.test.mjs +0 -48
  313. package/test/integration/plugins-cloudflare.integration.test.mjs +0 -28
  314. package/test/integration/provider-env-cli.test.mjs +0 -60
  315. package/test/integration/provider-factory.test.mjs +0 -197
  316. package/test/integration/repository-company-graph.test.mjs +0 -90
  317. package/test/integration/runtime-migrations.test.mjs +0 -87
  318. package/test/integration/runtime-status.integration.test.mjs +0 -227
  319. package/test/integration/sam-activity-recovery.test.mjs +0 -147
  320. package/test/integration/sam-decision.test.mjs +0 -584
  321. package/test/integration/sam-kernel.test.mjs +0 -99
  322. package/test/integration/sam-planning-astar.test.mjs +0 -279
  323. package/test/integration/scaffold-cloudflare.test.mjs +0 -46
  324. package/test/integration/skill-runtime.test.mjs +0 -240
  325. package/test/integration/storage-architecture.test.mjs +0 -154
  326. package/test/integration/store-discovery.test.mjs +0 -44
  327. package/test/integration/studio-fs-pty-e2e.test.mjs +0 -294
  328. package/test/integration/terminal-exec.integration.test.mjs +0 -86
  329. package/test/integration/theme-package-registry.test.mjs +0 -31
  330. package/test/integration/tool-runtime.test.mjs +0 -124
  331. package/test/integration/tool-schema.test.mjs +0 -59
  332. package/test/jr-dev-skill.test.mjs +0 -26
  333. package/test/knowledge-context-pack.test.mjs +0 -19
  334. package/test/knowledge-postgres.test.mjs +0 -40
  335. package/test/knowledge-service.test.mjs +0 -110
  336. package/test/knowledge.test.mjs +0 -206
  337. package/test/live/terminal-transport.live.test.mjs +0 -24
  338. package/test/local-sessions.test.mjs +0 -57
  339. package/test/local-studio-deploy.test.mjs +0 -83
  340. package/test/loopback-oauth.test.mjs +0 -53
  341. package/test/merkle-render.test.mjs +0 -31
  342. package/test/mini.test.mjs +0 -140
  343. package/test/model-catalog.test.mjs +0 -70
  344. package/test/models.test.mjs +0 -309
  345. package/test/npm10-lock.test.mjs +0 -29
  346. package/test/ollama.test.mjs +0 -137
  347. package/test/open-url.test.mjs +0 -64
  348. package/test/openai-responses.test.mjs +0 -155
  349. package/test/portable-context.test.mjs +0 -94
  350. package/test/project-config.test.mjs +0 -81
  351. package/test/project-rules.test.mjs +0 -44
  352. package/test/provider-credentials.test.mjs +0 -106
  353. package/test/rehydrate.test.mjs +0 -25
  354. package/test/release-hygiene.test.mjs +0 -42
  355. package/test/repository-snapshot-view.test.mjs +0 -112
  356. package/test/responses-runner.test.mjs +0 -465
  357. package/test/runtime-activity.test.mjs +0 -98
  358. package/test/sdk-worker-contract.test.mjs +0 -72
  359. package/test/security.test.mjs +0 -266
  360. package/test/setup-planner.test.mjs +0 -74
  361. package/test/setup-runtime.test.mjs +0 -51
  362. package/test/shell.test.mjs +0 -281
  363. package/test/skills.test.mjs +0 -22
  364. package/test/smoke.mjs +0 -122
  365. package/test/telemetry.test.mjs +0 -79
  366. package/test/terminal/local-pty.mock.test.mjs +0 -153
  367. package/test/terminal-machine-identity.test.mjs +0 -88
  368. package/test/theme-portability.test.mjs +0 -14
  369. package/test/tools-search.test.mjs +0 -73
  370. package/test/unit/website-assets-bindings.test.mjs +0 -60
  371. package/test/whoami-resume.test.mjs +0 -157
@@ -1,184 +0,0 @@
1
- import test from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import fs from 'node:fs';
4
- import os from 'node:os';
5
- import path from 'node:path';
6
- import {
7
- openScadCompile,
8
- validateOpenScadSource,
9
- freeCadBuild,
10
- freeCadInspect,
11
- blenderBuild,
12
- blenderInspect,
13
- blenderExport,
14
- discoverAllCadTools,
15
- } from '../../src/lib/cad/index.js';
16
-
17
- // These tests exercise real local CAD/3D engine binaries (OpenSCAD, FreeCAD,
18
- // Blender). They are not installed on the generic CI runner and are heavy
19
- // desktop applications — deliberately not force-installed there (matches
20
- // the local-first storage/tooling stance elsewhere in this repo). Each
21
- // execution test below skips itself with a clear reason when its engine
22
- // isn't present, rather than failing CI for an environment gap. On a
23
- // machine that has the tool installed (e.g. local dev), the test runs for
24
- // real with the full original assertions, unchanged.
25
- const cadReport = await discoverAllCadTools();
26
- const toolAvailable = (name) => cadReport.tools.find((t) => t.tool === name)?.available === true;
27
-
28
- test('CAD Tool Discovery identifies local engines on the machine (schema is always validated; per-tool availability is informational)', async () => {
29
- const report = await discoverAllCadTools();
30
- assert.equal(report.schema_version, 1);
31
- assert.ok(report.total_tools >= 5);
32
-
33
- for (const toolName of ['openscad', 'freecad', 'blender']) {
34
- const tool = report.tools.find((t) => t.tool === toolName);
35
- assert.ok(tool, `${toolName} entry missing from discovery report`);
36
- assert.equal(typeof tool.available, 'boolean');
37
- if (tool.available) {
38
- assert.ok(tool.binary, `${toolName} reported available but has no binary path`);
39
- assert.ok(tool.version, `${toolName} reported available but has no version`);
40
- } else {
41
- assert.ok(tool.install_guidance, `${toolName} reported unavailable but has no install_guidance`);
42
- }
43
- }
44
- });
45
-
46
- test('OpenSCAD execution rejects security-violating scripts', async () => {
47
- assert.throws(
48
- () => validateOpenScadSource('use <child_process>;'),
49
- /Security Violation/
50
- );
51
- assert.throws(
52
- () => validateOpenScadSource('exec("cat /etc/passwd");'),
53
- /Security Violation/
54
- );
55
- assert.throws(
56
- () => validateOpenScadSource('import("../../secret.scad");'),
57
- /Security Violation/
58
- );
59
- });
60
-
61
- test('OpenSCAD real compilation produces watertight geometry and returns typed receipt', { skip: !toolAvailable('openscad') && 'openscad binary not available on this machine' }, async (t) => {
62
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-openscad-test-'));
63
- t.after(() => fs.rmSync(tmpDir, { recursive: true, force: true }));
64
-
65
- const source = `
66
- difference() {
67
- cube([width, depth, height], center=true);
68
- cylinder(h=height + 2, r=holeRadius, center=true, $fn=24);
69
- }
70
- `;
71
-
72
- const result = await openScadCompile({
73
- source,
74
- outputFormat: 'stl',
75
- parameters: {
76
- width: 30,
77
- depth: 20,
78
- height: 10,
79
- holeRadius: 4,
80
- },
81
- filename: 'flange.stl',
82
- });
83
-
84
- assert.equal(result.success, true);
85
- assert.equal(result.engine, 'openscad-native');
86
- assert.equal(result.filename, 'flange.stl');
87
- assert.equal(result.outputFormat, 'stl');
88
- assert.equal(result.mimeType, 'model/stl');
89
- assert.ok(result.sizeBytes > 0);
90
- assert.ok(result.artifactContent.includes('solid OpenSCAD_Model'));
91
- assert.ok(result.artifactContent.includes('facet normal'));
92
- assert.ok(result.artifactContent.includes('outer loop'));
93
- assert.ok(result.logs.some(l => l.includes('[KERNEL] OpenSCAD Native Compiler')));
94
- });
95
-
96
- test('FreeCAD solid kernel executes precision B-Rep operations and exports valid ISO STEP', { skip: !toolAvailable('freecad') && 'freecad binary not available on this machine' }, async (t) => {
97
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-freecad-test-'));
98
- t.after(() => fs.rmSync(tmpDir, { recursive: true, force: true }));
99
-
100
- const stepOutput = path.join(tmpDir, 'bracket.step');
101
-
102
- const recipe = {
103
- operations: [
104
- { op: 'box', name: 'main_block', length: 40.0, width: 25.0, height: 12.0 },
105
- { op: 'cylinder', name: 'bore', radius: 5.0, height: 14.0, translate: [20.0, 12.5, -1.0] },
106
- { op: 'cut', base: 'main_block', tool: 'bore' },
107
- ],
108
- };
109
-
110
- const buildResult = await freeCadBuild({
111
- recipe,
112
- output: stepOutput,
113
- format: 'step',
114
- });
115
-
116
- assert.equal(buildResult.ok, true);
117
- assert.equal(buildResult.capability, 'freecad.build');
118
- assert.equal(buildResult.format, 'step');
119
- assert.ok(buildResult.sizeBytes > 0);
120
- assert.ok(fs.existsSync(stepOutput));
121
-
122
- // Verify solid shape metrics
123
- const expectedSolidVolume = 40.0 * 25.0 * 12.0 - Math.PI * 25.0 * 12.0;
124
- assert.ok(Math.abs(buildResult.metrics.volume - expectedSolidVolume) < 1.0, 'Volume matches geometry');
125
- assert.equal(buildResult.metrics.faces_count, 7);
126
-
127
- // Read raw STEP content to verify ISO-10303 signature
128
- const stepText = fs.readFileSync(stepOutput, 'utf8');
129
- assert.ok(stepText.includes('ISO-10303-21;'));
130
- assert.ok(stepText.includes('Open CASCADE STEP processor'));
131
-
132
- // Inspect the exported STEP file using FreeCAD inspection
133
- const inspectResult = await freeCadInspect({ input: stepOutput });
134
- assert.equal(inspectResult.ok, true);
135
- assert.equal(inspectResult.capability, 'freecad.inspect');
136
- assert.ok(Math.abs(inspectResult.metrics.volume - expectedSolidVolume) < 1.0);
137
- assert.equal(inspectResult.metrics.faces_count, 7);
138
- });
139
-
140
- test('Blender real execution builds, inspects, and exports production 3D assets', { skip: !toolAvailable('blender') && 'blender binary not available on this machine' }, async (t) => {
141
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-blender-test-'));
142
- t.after(() => fs.rmSync(tmpDir, { recursive: true, force: true }));
143
-
144
- const blendPath = path.join(tmpDir, 'scene.blend');
145
- const glbPath = path.join(tmpDir, 'scene.glb');
146
-
147
- const recipe = {
148
- schema_version: 1,
149
- operations: [
150
- { op: 'clear_scene' },
151
- { op: 'add', primitive: 'cylinder', name: 'Pillar', radius: 1.5, depth: 4.0 },
152
- { op: 'add_light', light_type: 'SUN', energy: 2.5 },
153
- ],
154
- };
155
-
156
- // 1. Build .blend file
157
- const buildResult = await blenderBuild({
158
- recipe,
159
- output: blendPath,
160
- });
161
-
162
- assert.equal(buildResult.ok, true);
163
- assert.equal(buildResult.capability, 'blender.build');
164
- assert.ok(fs.existsSync(blendPath));
165
- assert.ok(buildResult.objects.includes('Pillar'));
166
-
167
- // 2. Inspect built scene
168
- const inspectResult = await blenderInspect({ input: blendPath });
169
- assert.equal(inspectResult.ok, true);
170
- assert.equal(inspectResult.capability, 'blender.inspect');
171
- assert.ok(inspectResult.scene.objects.some(o => o.name === 'Pillar'));
172
-
173
- // 3. Export to GLB
174
- const exportResult = await blenderExport({
175
- input: blendPath,
176
- output: glbPath,
177
- format: 'glb',
178
- });
179
-
180
- assert.equal(exportResult.ok, true);
181
- assert.equal(exportResult.capability, 'blender.export');
182
- assert.ok(fs.existsSync(glbPath));
183
- assert.ok(fs.statSync(glbPath).size > 0);
184
- });
@@ -1,31 +0,0 @@
1
- import test from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import fs from 'node:fs';
4
- import os from 'node:os';
5
- import path from 'node:path';
6
- import {spawn} from 'node:child_process';
7
- import {localProjectRuntime} from '../../src/lib/cad/project-cli.js';
8
- test('packaged app API shares CLI revisions, emits events and rejects stale writes',{skip:process.env.AGENTSAM_TEST_CAD_APP!=='1'},async t=>{
9
- const root=fs.mkdtempSync(path.join(os.tmpdir(),'cad-app-proof-')),port=31987;
10
- const app=new URL('../../apps/cad-creator/backend/',import.meta.url);
11
- const child=spawn(process.execPath,['dist/server.mjs'],{cwd:app,env:{...process.env,NODE_ENV:'production',PORT:String(port),HOST:'127.0.0.1',AGENTSAM_CAD_PROJECT_ROOT:root},stdio:['ignore','pipe','pipe']});
12
- let log='';child.stdout.on('data',d=>log+=d);child.stderr.on('data',d=>log+=d);
13
- t.after(()=>{child.kill();fs.rmSync(root,{recursive:true,force:true});});
14
- const base='http://127.0.0.1:'+port;
15
- let ready=false;
16
- for(let i=0;i<80;i++){try{const r=await fetch(base);if(r.ok){ready=true;break;}}catch{}await new Promise(r=>setTimeout(r,100));}
17
- assert.ok(ready,log);
18
- async function call(name,input){const res=await fetch(base+'/api/cad/project/tools/'+name,{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify(input)});return {status:res.status,body:await res.json()};}
19
- const project=JSON.parse(fs.readFileSync(new URL('../fixtures/cad/courtyard-house.json',import.meta.url),'utf8'));
20
- const saved=await call('design_project_save',{project,expected_revision:0});assert.equal(saved.status,200);
21
- const runtime=localProjectRuntime(root);assert.equal((await runtime.execute('design_project_get',{project_id:project.id})).content_hash,saved.body.result.content_hash);
22
- const abort=new AbortController();t.after(()=>abort.abort());
23
- const events=await fetch(base+'/api/cad/project/events',{signal:abort.signal});const reader=events.body.getReader();
24
- const edited=await runtime.execute('design_apply_operation',{project_id:project.id,expected_revision:1,operation:{type:'update_wall',wallId:'wall-0',updates:{height3D:132}}});
25
- const event=await Promise.race([reader.read(),new Promise((_,reject)=>setTimeout(()=>reject(new Error('event timeout')),5000))]);
26
- assert.match(new TextDecoder().decode(event.value),/"revision":2/);
27
- const reopened=await call('design_project_get',{project_id:project.id,expected_content_hash:edited.content_hash});assert.equal(reopened.body.result.revision,2);
28
- assert.equal((await call('design_project_save',{project,expected_revision:1})).status,409);
29
- const denied=await fetch(base+'/api/cad/project/tools/design_project_get',{method:'POST',headers:{'content-type':'application/json',origin:'https://other.example'},body:JSON.stringify({project_id:project.id})});assert.equal(denied.status,403);
30
- abort.abort();
31
- });
@@ -1,25 +0,0 @@
1
- import test from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import fs from 'node:fs';
4
- import {DatabaseSync} from 'node:sqlite';
5
- import {D1ProjectStore} from '../../src/lib/cad/d1-project-store.js';
6
- const schema="CREATE TABLE designstudio_design_blueprints (\n id TEXT PRIMARY KEY DEFAULT ('dsb_' || lower(hex(randomblob(8)))),\n\n tenant_id TEXT NOT NULL DEFAULT 'tenant_inneranimalmedia',\n workspace_id TEXT NOT NULL DEFAULT 'ws_inneranimalmedia',\n project_id TEXT,\n\n title TEXT NOT NULL,\n description TEXT,\n original_prompt TEXT,\n\n intent_json TEXT NOT NULL DEFAULT '{}',\n\n cad_script TEXT,\n cad_engine TEXT DEFAULT 'openscad',\n\n sketch_json TEXT DEFAULT '{}',\n preview_image_url TEXT,\n\n generation_config_json TEXT DEFAULT '{}',\n\n latest_asset_id TEXT,\n latest_run_id TEXT,\n\n status TEXT NOT NULL DEFAULT 'draft'\n CHECK (status IN (\n 'draft',\n 'structured',\n 'generated',\n 'validated',\n 'exported',\n 'failed'\n )),\n\n quality_score REAL DEFAULT 0,\n success_rate REAL DEFAULT 0,\n\n tags TEXT DEFAULT '[]',\n notes TEXT,\n\n total_tokens INTEGER DEFAULT 0,\n total_cost_usd REAL DEFAULT 0,\n avg_latency_ms REAL DEFAULT 0,\n\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n, preview_svg_url TEXT);\nCREATE TABLE \"scene_snapshots\" (\n id TEXT PRIMARY KEY DEFAULT ('scene_' || lower(hex(randomblob(8)))),\n workspace_id TEXT NOT NULL,\n user_id TEXT NOT NULL,\n tenant_id TEXT NOT NULL DEFAULT 'tenant_sam_primeaux',\n name TEXT NOT NULL DEFAULT 'Untitled Scene',\n project_type TEXT NOT NULL DEFAULT 'SANDBOX',\n entity_count INTEGER NOT NULL DEFAULT 0,\n r2_key TEXT NOT NULL,\n r2_bucket TEXT NOT NULL DEFAULT 'inneranimalmedia',\n public_url TEXT,\n thumbnail_r2_key TEXT,\n thumbnail_url TEXT,\n tags TEXT DEFAULT '[]',\n description TEXT,\n is_autosave INTEGER NOT NULL DEFAULT 0,\n version INTEGER NOT NULL DEFAULT 1,\n created_at INTEGER NOT NULL DEFAULT (unixepoch()),\n updated_at INTEGER NOT NULL DEFAULT (unixepoch())\n, project_id TEXT, glb_r2_key TEXT, style_preset TEXT, voxel_count INTEGER, cad_job_id TEXT);";
7
- const project=JSON.parse(fs.readFileSync(new URL('../fixtures/cad/courtyard-house.json',import.meta.url),'utf8'));
8
- test('existing D1 tables support scoped immutable revisions and optimistic concurrency',async t=>{
9
- const sqlite=new DatabaseSync(':memory:');t.after(()=>sqlite.close());sqlite.exec(schema);
10
- const db={prepare(sql){return {bind(...params){return {sql,params,async first(){return sqlite.prepare(sql).get(...params)||null;}};}};},
11
- async batch(statements){sqlite.exec('BEGIN');try{const results=statements.map(s=>({meta:{changes:Number(sqlite.prepare(s.sql).run(...s.params).changes)}}));sqlite.exec('COMMIT');return results;}catch(e){sqlite.exec('ROLLBACK');throw e;}}};
12
- const blobs=new Map(),objects={async put(k,v){blobs.set(k,v);},async get(k){return blobs.has(k)?{async text(){return blobs.get(k);}}:null;}};
13
- const scope={account_id:'test-owner',workspace_id:'test-workspace',tenant_id:'test-tenant'};
14
- const store=new D1ProjectStore({db,objects,bucket:'test-bucket',scope});
15
- await store.save(project,0);
16
- await store.save({...project,name:'Revision two'},1);
17
- await assert.rejects(store.save(project,1),/revision_conflict/);
18
- assert.equal(sqlite.prepare('SELECT count(*) n FROM scene_snapshots').get().n,2);
19
- assert.equal((await store.read(project.id,1)).project.name,project.name);
20
- assert.equal((await store.restore(project.id,1,2)).revision,3);
21
- const other=new D1ProjectStore({db,objects,bucket:'test-bucket',scope:{...scope,account_id:'other'}});
22
- await assert.rejects(other.read(project.id),/project_not_found/);
23
- await assert.rejects(other.save(project,3),/revision_conflict/);
24
- assert.equal((await store.read(project.id)).revision,3);
25
- });
@@ -1,24 +0,0 @@
1
- import test from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import fs from 'node:fs';
4
- import os from 'node:os';
5
- import path from 'node:path';
6
- import {localProjectRuntime} from '../../src/lib/cad/project-cli.js';
7
- const enabled=process.env.AGENTSAM_TEST_NATIVE_CAD==='1';
8
- test('courtyard real build inspect export render and restored revision rebuild',{skip:!enabled&&'Set AGENTSAM_TEST_NATIVE_CAD=1; enabled runs must find Blender'},async t=>{
9
- const root=process.env.AGENTSAM_CAD_TEST_OUTPUT||fs.mkdtempSync(path.join(os.tmpdir(),'cad-house-native-'));
10
- if(!process.env.AGENTSAM_CAD_TEST_OUTPUT)t.after(()=>fs.rmSync(root,{recursive:true,force:true}));
11
- const p=JSON.parse(fs.readFileSync(new URL('../fixtures/cad/courtyard-house.json',import.meta.url),'utf8'));
12
- p.id='courtyard-'+Date.now();
13
- const run=localProjectRuntime(root),saved=await run.execute('design_project_save',{project:p,expected_revision:0});
14
- const input={project_id:p.id,revision:saved.revision};
15
- const build=await run.execute('design_model_build',input);assert.ok(build.artifact.size_bytes>0);
16
- const inspection=await run.execute('design_model_inspect',input);assert.ok(inspection.ok);
17
- const glb=await run.execute('design_model_export',{...input,format:'glb'});assert.equal(fs.readFileSync(glb.artifact.path).subarray(0,4).toString(),'glTF');
18
- const png=await run.execute('design_model_render',input);assert.equal(fs.readFileSync(png.artifact.path).subarray(1,4).toString(),'PNG');
19
- const edited=await run.execute('design_apply_operation',{project_id:p.id,expected_revision:1,operation:{type:'update_wall',wallId:'wall-0',updates:{height3D:132}}});
20
- assert.equal(edited.revision,2);
21
- const restored=await run.execute('design_project_restore',{project_id:p.id,revision:1,expected_revision:2});assert.equal(restored.project.walls[0].height3D,120);
22
- await run.execute('design_model_build',{project_id:p.id,revision:3});
23
- console.log(JSON.stringify({root,project_id:p.id,build:build.artifact,glb:glb.artifact,png:png.artifact,restored_revision:3}));
24
- });
@@ -1,9 +0,0 @@
1
- import test from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import {runProjectWorkflow} from '../../src/lib/cad/project-workflows.js';
4
- test('workflow halts on invalid validation and records no claimed effects',async()=>{
5
- let calls=0;await assert.rejects(runProjectWorkflow({execute:async()=>{calls++;return {valid:false,errors:['bad wall']};}},'cad.house_baseline',{project:{}}),/project_invalid/);assert.equal(calls,1);
6
- });
7
- test('edit workflow refuses stale expected revision before edit',async()=>{
8
- const calls=[];await assert.rejects(runProjectWorkflow({execute:async(name)=>{calls.push(name);return {revision:2,project:{id:'p'}};}},'cad.edit_preview',{project_id:'p',expected_revision:1,operation:{}}),/revision_conflict/);assert.deepEqual(calls,['design_project_get']);
9
- });
@@ -1,85 +0,0 @@
1
- import test from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import fs from 'node:fs';
4
- import os from 'node:os';
5
- import path from 'node:path';
6
- import {validateProject,applyProjectOperation} from '../../src/lib/cad/project-contract.js';
7
- import {FileProjectStore} from '../../src/lib/cad/project-store.js';
8
- import {createProjectRuntime} from '../../src/lib/cad/project-runtime.js';
9
- import {localProjectRuntime} from '../../src/lib/cad/project-cli.js';
10
- import {projectToBlenderRecipe} from '../../src/lib/cad/project-recipe.js';
11
- import {createCapabilityAdapter} from '../../src/agent/capability-adapter.js';
12
- const project=JSON.parse(fs.readFileSync(new URL('../fixtures/cad/courtyard-house.json',import.meta.url),'utf8'));
13
- test('invalid references and non-finite geometry fail before mutation',()=>{
14
- const p=structuredClone(project);p.walls[0].x1=Infinity;assert.equal(validateProject(p).valid,false);
15
- p.walls[0].x1=0;p.doors[0].wallId='missing';assert.equal(validateProject(p).valid,false);
16
- assert.equal(validateProject({...p,walls:{}}).valid,false);
17
- });
18
- test('batch is atomic, absent targets fail, and host deletion cascades',()=>{
19
- const before=JSON.stringify(project);
20
- assert.throws(()=>applyProjectOperation(project,{type:'batch_operations',operations:[{type:'delete_wall',wallId:'wall-4'},{type:'update_wall',wallId:'absent',updates:{height3D:96}}]}),/element_not_found/);
21
- assert.equal(JSON.stringify(project),before);
22
- assert.equal(applyProjectOperation(project,{type:'delete_wall',wallId:'wall-4'}).doors.length,0);
23
- });
24
- test('save reopen restore and stale revision checks preserve immutable snapshots',async t=>{
25
- const dir=fs.mkdtempSync(path.join(os.tmpdir(),'cad-project-'));t.after(()=>fs.rmSync(dir,{recursive:true,force:true}));
26
- const store=new FileProjectStore(dir);
27
- await store.save(project,0);
28
- const next=applyProjectOperation(project,{type:'update_wall',wallId:'wall-0',updates:{height3D:132}});
29
- await store.save(next,1);
30
- await assert.rejects(store.save(project,1),/revision_conflict/);
31
- const restored=await new FileProjectStore(dir).restore(project.id,1,2);
32
- assert.equal(restored.revision,3);assert.equal(restored.project.walls[0].height3D,120);assert.equal((await store.read(project.id,2)).project.walls[0].height3D,132);
33
- });
34
- test('native recipe converts inches to metres and preserves a real door gap',()=>{
35
- const recipe=projectToBlenderRecipe(project);
36
- assert.equal(recipe.operations.find(o=>o.name==='wall-0:0').scale[0],864*0.0254);
37
- const pieces=recipe.operations.filter(o=>o.name?.startsWith('wall-4:'));
38
- assert.equal(pieces.length,3);
39
- assert.throws(()=>projectToBlenderRecipe({...project,roofType:'gable'}),/roof_geometry_not_supported/);
40
- });
41
- test('agent and runtime share executable CAD handlers',async t=>{
42
- const root=fs.mkdtempSync(path.join(os.tmpdir(),'cad-agent-'));t.after(()=>fs.rmSync(root,{recursive:true,force:true}));
43
- const adapter=createCapabilityAdapter({projectRoot:root});
44
- assert.ok(adapter.toolDescriptors().some(t=>t.name==='design_project_save'));
45
- await adapter.invoke('design_project_save',{project,expected_revision:0});
46
- const result=await adapter.invoke('design_apply_operation',{project_id:project.id,expected_revision:1,operation:{type:'update_wall',wallId:'wall-0',updates:{height3D:132}}});
47
- assert.equal(result.result.revision,2);
48
- });
49
-
50
-
51
- test('CAD registry projects the app into tools workflows and CLI graph relationships',()=>{
52
- const manifest=JSON.parse(fs.readFileSync(new URL('../../registry/cad-project/manifest.json',import.meta.url),'utf8'));
53
- const migration=fs.readFileSync(new URL('../../registry/cad-project/migration.sql',import.meta.url),'utf8');
54
- assert.equal(manifest.product.app_id,'cad-creator');
55
- assert.equal(manifest.product.slug,'cad-creator');
56
- assert.deepEqual(manifest.product.capability_keys,['design.read','design.write','design.export']);
57
- assert.equal(manifest.product.cli_commands[0].id,'agentsam:cad:project');
58
- assert.equal(manifest.tools.length,9);
59
- assert.equal(manifest.workflows.length,2);
60
- assert.match(migration,/WHERE slug='cad-creator'/);
61
- assert.match(migration,/WHERE slug='agentsam-cad-creator'/);
62
- assert.match(migration,/legacy_slug','agentsam-cad-creator/);
63
- assert.equal((migration.match(/'exposes_tool'/g)||[]).length,9);
64
- assert.equal((migration.match(/'provides_workflow'/g)||[]).length,2);
65
- assert.equal((migration.match(/'exposes_command'/g)||[]).length,1);
66
- assert.match(migration,/'cli_command','agentsam:cad:project'/);
67
- assert.match(migration,/ON CONFLICT\(id\) DO UPDATE SET tool_name=excluded\.tool_name/);
68
- assert.doesNotMatch(migration,/DO UPDATE SET[^;]*is_active=excluded\.is_active/);
69
- assert.doesNotMatch(migration,/DO UPDATE SET[^;]*lifecycle=excluded\.lifecycle/);
70
-
71
- });
72
-
73
-
74
- test('CAD validate requires project or project_id and model-facing CAD tools declare non-strict rich payloads',async()=>{
75
- const root=fs.mkdtempSync(path.join(os.tmpdir(),'cad-validate-source-'));
76
- const runtime=localProjectRuntime(root);
77
- await assert.rejects(()=>runtime.execute('design_project_validate',{}),/argument_required:project_or_project_id/);
78
- const adapter=createCapabilityAdapter({projectRoot:root});
79
- const save=adapter.toolDescriptors().find(t=>t.name==='design_project_save');
80
- const edit=adapter.toolDescriptors().find(t=>t.name==='design_apply_operation');
81
- assert.equal(save.strict,false);
82
- assert.equal(edit.strict,false);
83
- assert.equal(save.input_schema.properties.project.additionalProperties,true);
84
- assert.equal(edit.input_schema.properties.operation.additionalProperties,true);
85
- });
@@ -1,41 +0,0 @@
1
- import assert from 'node:assert/strict';
2
- import path from 'node:path';
3
- import { spawnSync } from 'node:child_process';
4
- import test from 'node:test';
5
-
6
- const repoRoot = path.resolve(new URL('../..', import.meta.url).pathname);
7
-
8
- function run(...args) {
9
- return spawnSync(process.execPath, ['src/cli.js', ...args], { cwd: repoRoot, encoding: 'utf8' });
10
- }
11
-
12
- test('agentsam help is concise, topic-aware, and deterministic outside a TTY', () => {
13
- const help = run('help');
14
- assert.equal(help.status, 0, help.stderr);
15
- assert.doesNotMatch(help.stderr, /Unknown command/);
16
- assert.match(help.stdout, /Agent Sam/);
17
- assert.match(help.stdout, /SAM = Systematic Autonomous Machinery/);
18
- assert.match(help.stdout, /agentsam help <topic>/);
19
- assert.match(help.stdout, /press \/ for the command picker/i);
20
- assert.doesNotMatch(help.stdout, /Inspect options:/);
21
-
22
- const topic = run('help', 'runtime');
23
- assert.equal(topic.status, 0, topic.stderr);
24
- assert.match(topic.stdout, /Runtime \/ terminal/);
25
- assert.match(topic.stdout, /agentsam connections/);
26
- assert.match(topic.stdout, /agentsam deploy/);
27
-
28
- const all = run('help', '--all');
29
- assert.equal(all.status, 0, all.stderr);
30
- assert.match(all.stdout, /Build \/ inspect/);
31
- assert.match(all.stdout, /Create \/ extend/);
32
-
33
- const allAlias = run('help', 'all');
34
- assert.equal(allAlias.status, 0, allAlias.stderr);
35
- assert.equal(allAlias.stdout, all.stdout);
36
-
37
- const flag = run('--help');
38
- assert.equal(flag.status, 0, flag.stderr);
39
- assert.match(flag.stdout, /agentsam help <topic>/);
40
- assert.doesNotMatch(flag.stdout, /Inspect options:/);
41
- });
@@ -1,77 +0,0 @@
1
- import assert from 'node:assert/strict';
2
- import fs from 'node:fs';
3
- import os from 'node:os';
4
- import path from 'node:path';
5
- import test from 'node:test';
6
- import { execFileSync } from 'node:child_process';
7
- import { fileURLToPath } from 'node:url';
8
-
9
- const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
10
- const cmsBin = path.join(root, 'apps/client-cms-editor/bin/agentsam-cms.mjs');
11
-
12
- function scaffold(persistence, extraArgs = []) {
13
- const temp = fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-cms-scaffold-'));
14
- const target = path.join(temp, 'editor');
15
- execFileSync(process.execPath, [
16
- cmsBin,
17
- 'scaffold',
18
- target,
19
- '--persistence',
20
- persistence,
21
- ...extraArgs,
22
- ], { cwd: root, stdio: 'pipe' });
23
- return { temp, target };
24
- }
25
-
26
- test('CMS editor scaffold is self-contained and records SQLite authority', () => {
27
- const { temp, target } = scaffold('sqlite');
28
- try {
29
- assert.equal(fs.existsSync(path.join(target, 'agentsam.app.json')), true);
30
- assert.equal(fs.existsSync(path.join(target, 'cms.config.json')), true);
31
- assert.equal(fs.existsSync(path.join(target, '.agentsam/cms.sqlite')), true);
32
- assert.equal(fs.existsSync(path.join(target, '.agentsam/assets')), true);
33
- assert.equal(fs.existsSync(path.join(target, 'public')), true);
34
-
35
- const cfg = JSON.parse(fs.readFileSync(path.join(target, 'cms.config.json'), 'utf8'));
36
- assert.equal(cfg.schema, 'agentsam.cms.project.v1');
37
- assert.equal(cfg.persistence, 'sqlite');
38
- assert.equal(cfg.dbPath, '.agentsam/cms.sqlite');
39
- assert.equal(cfg.cmsBase, '/cms');
40
- assert.equal(cfg.auth?.mode, 'local-dev-principal');
41
-
42
- const app = JSON.parse(fs.readFileSync(path.join(target, 'agentsam.app.json'), 'utf8'));
43
- assert.equal(app.schema, 'agentsam.app.v1');
44
- assert.equal(app.product_id, 'cms');
45
- assert.equal(app.package, '@inneranimalmedia/client-cms-editor');
46
-
47
- // Lean project shell — no monorepo package vendoring / file: escapes.
48
- assert.equal(fs.existsSync(path.join(target, 'packages')), false);
49
- assert.equal(fs.existsSync(path.join(target, 'frontend/package.json')), false);
50
- } finally {
51
- fs.rmSync(temp, { recursive: true, force: true });
52
- }
53
- });
54
-
55
- test('CMS editor rejects localStorage as persistence authority', () => {
56
- const temp = fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-cms-scaffold-'));
57
- const target = path.join(temp, 'editor');
58
- try {
59
- assert.throws(
60
- () => execFileSync(process.execPath, [
61
- cmsBin,
62
- 'scaffold',
63
- target,
64
- '--persistence',
65
- 'localStorage',
66
- ], { cwd: root, stdio: 'pipe', encoding: 'utf8' }),
67
- (error) => {
68
- const message = String(error?.stderr || error?.message || error);
69
- return /unsupported persistence "localStorage"/i.test(message)
70
- && /choose sqlite or d1/i.test(message);
71
- },
72
- );
73
- assert.equal(fs.existsSync(target), false);
74
- } finally {
75
- fs.rmSync(temp, { recursive: true, force: true });
76
- }
77
- });