@inneranimalmedia/agentsam-sdk 2.6.5 → 2.6.7

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/AGENTSAM.md +29 -0
  2. package/apps/README.md +5 -0
  3. package/apps/cad-creator/README.md +4 -4
  4. package/apps/cad-creator/shared/cad/package.json +1 -1
  5. package/apps/client-cms-editor/AGENTS.md +12 -7
  6. package/apps/client-cms-editor/README.md +76 -48
  7. package/apps/client-cms-editor/agentsam.app.json +26 -9
  8. package/apps/client-cms-editor/backend/package.json +20 -3
  9. package/apps/client-cms-editor/backend/src/api/client.ts +134 -101
  10. package/apps/client-cms-editor/backend/src/index.ts +1 -1
  11. package/apps/client-cms-editor/backend/src/model.ts +11 -115
  12. package/apps/client-cms-editor/backend/src/preview/bridge.ts +1 -1
  13. package/apps/client-cms-editor/backend/tsconfig.json +6 -1
  14. package/apps/client-cms-editor/bin/agentsam-cms.js +262 -0
  15. package/apps/client-cms-editor/bin/agentsam-cms.mjs +2 -228
  16. package/apps/client-cms-editor/frontend/package.json +16 -7
  17. package/apps/client-cms-editor/frontend/src/AgentSamDrawer.tsx +9 -41
  18. package/apps/client-cms-editor/frontend/src/CmsAgentSurface.tsx +19 -174
  19. package/apps/client-cms-editor/frontend/src/adapters/heuristic.ts +29 -0
  20. package/apps/client-cms-editor/frontend/src/adapters/http.ts +628 -0
  21. package/apps/client-cms-editor/frontend/src/adapters/memory.ts +510 -0
  22. package/apps/client-cms-editor/frontend/src/editor/CmsEditor.tsx +213 -0
  23. package/apps/client-cms-editor/frontend/src/editor/CmsEditorProvider.tsx +20 -0
  24. package/apps/client-cms-editor/frontend/src/editor/canvas/PreviewCanvas.tsx +53 -0
  25. package/apps/client-cms-editor/frontend/src/{CmsEditor.tsx → editor/legacy/CmsEditorPrototype.tsx} +52 -23
  26. package/apps/client-cms-editor/frontend/src/editor/useCmsEditorController.ts +218 -0
  27. package/apps/client-cms-editor/frontend/src/index.ts +19 -5
  28. package/apps/client-cms-editor/frontend/src/lib/agent-host.ts +24 -0
  29. package/apps/client-cms-editor/frontend/src/main.tsx +82 -8
  30. package/apps/client-cms-editor/frontend/src/mount.tsx +92 -30
  31. package/apps/client-cms-editor/frontend/src/styles/agentsam-drawer.css +1 -1
  32. package/apps/client-cms-editor/frontend/src/styles/cmsShell.css +8 -8
  33. package/apps/client-cms-editor/frontend/src/styles/studio.css +55 -3
  34. package/apps/client-cms-editor/frontend/tsconfig.json +12 -1
  35. package/apps/client-cms-editor/frontend/vite.config.ts +12 -0
  36. package/apps/client-cms-editor/package-lock.json +973 -134
  37. package/apps/client-cms-editor/package.json +118 -6
  38. package/apps/client-cms-editor/reference/harvest/HARVEST_RECEIPT.json +201 -0
  39. package/apps/client-cms-editor/reference/harvest/PROVENANCE_HISTORY.txt +10 -0
  40. package/apps/client-cms-editor/reference/harvest/README.md +8 -0
  41. package/apps/client-cms-editor/reference/harvest/plans/ARCHIVE-INTAKE.md +135 -0
  42. package/apps/client-cms-editor/reference/harvest/plans/CHATGPT-IDENTITY-HARVEST.md +83 -0
  43. package/apps/client-cms-editor/reference/harvest/plans/CMS-EDITOR-HARVEST.md +166 -0
  44. package/apps/client-cms-editor/reference/harvest/plans/HARVEST-INDEX.md +196 -0
  45. package/apps/client-cms-editor/reference/harvest/plans/INNERANIMALS-CONTENT-001.md +137 -0
  46. package/apps/client-cms-editor/reference/harvest/plans/NO-IMPLICIT-SIDE-EFFECTS.md +87 -0
  47. package/apps/client-cms-editor/reference/harvest/plans/STOREFRONT-SURFACE-MAP.md +140 -0
  48. package/apps/client-cms-editor/reference/harvest/plans/THEME-INNERANIMALS-HARVEST.md +137 -0
  49. package/apps/client-cms-editor/reference/harvest/plans/TOOLING-LAB.md +63 -0
  50. package/apps/client-cms-editor/reference/harvest/plans/harvest-manifest.json +97 -0
  51. package/apps/client-cms-editor/reference/harvest/plans/local-cms-harvest-schema.sql +328 -0
  52. package/apps/client-cms-editor/shared/cms/package.json +17 -7
  53. package/apps/client-cms-editor/shared/cms/src/adapter.ts +204 -0
  54. package/apps/client-cms-editor/shared/cms/src/agent-context.ts +7 -5
  55. package/apps/client-cms-editor/shared/cms/src/editor-types.ts +32 -0
  56. package/apps/client-cms-editor/shared/cms/src/host.ts +82 -0
  57. package/apps/client-cms-editor/shared/cms/src/index.ts +4 -0
  58. package/apps/client-cms-editor/shared/cms/src/map.ts +115 -0
  59. package/apps/client-cms-editor/shared/cms/src/starter-pack.ts +158 -0
  60. package/contracts/source-types.v1.json +353 -0
  61. package/docs/CMS_CONTEXTUAL_COMPOSER.md +1 -1
  62. package/docs/PRODUCT_LIFECYCLE.md +566 -0
  63. package/docs/THEME_REFINERY.md +2 -2
  64. package/docs/architecture/AGENTSAM_RUNTIME_PROTOCOL.md +40 -20
  65. package/docs/content-studio/REVISION_GATE_2026-09-27.md +1 -1
  66. package/docs/plans/LOCAL_STUDIO_DESKTOP_RELEASE_2026-09-29.md +150 -0
  67. package/migrations/d1/0017_identity_native_oauth.sql +21 -0
  68. package/native/agentsam-machine/Cargo.lock +426 -0
  69. package/native/agentsam-machine/Cargo.toml +9 -0
  70. package/native/agentsam-machine/cli/Cargo.toml +14 -0
  71. package/native/agentsam-machine/cli/src/main.rs +77 -0
  72. package/native/agentsam-machine/core/Cargo.toml +15 -0
  73. package/native/agentsam-machine/core/src/assets.rs +790 -0
  74. package/native/agentsam-machine/core/src/bound.rs +298 -0
  75. package/native/agentsam-machine/core/src/enrich.rs +706 -0
  76. package/native/agentsam-machine/core/src/frontend.rs +442 -0
  77. package/native/agentsam-machine/core/src/lib.rs +1086 -0
  78. package/native/agentsam-machine/core/src/liquid.rs +528 -0
  79. package/native/agentsam-machine/core/src/source_types.rs +78 -0
  80. package/package.json +51 -21
  81. package/packages/agentsam-brand/README.md +1 -1
  82. package/packages/agentsam-brand/package.json +4 -4
  83. package/packages/agentsam-brand/src/index.js +1 -1
  84. package/packages/agentsam-contracts/package.json +13 -3
  85. package/packages/agentsam-contracts/src/tools.ts +22 -0
  86. package/packages/agentsam-errors/package.json +13 -3
  87. package/packages/agentsam-knowledge/package.json +18 -4
  88. package/packages/agentsam-knowledge/src/autorag/index.js +10 -3
  89. package/packages/agentsam-knowledge/src/backends/index.js +33 -1
  90. package/packages/agentsam-knowledge/test/autorag.test.mjs +60 -1
  91. package/packages/agentsam-nav/package.json +24 -6
  92. package/packages/agentsam-queue-control/README.md +1 -1
  93. package/packages/agentsam-queue-control/package.json +7 -2
  94. package/packages/agentsam-rapid-rust/src/main.rs +1 -1
  95. package/packages/agentsam-repository/package.json +13 -3
  96. package/packages/agentsam-repository/src/source-types.js +8 -0
  97. package/packages/agentsam-vault/package.json +14 -4
  98. package/packages/agentsam-workbench/package.json +15 -4
  99. package/packages/agentsam-workbench/src/agent/ToolPermissionRequest.tsx +94 -0
  100. package/packages/agentsam-workbench/src/agent/index.ts +2 -0
  101. package/packages/agentsam-workbench/src/agent/tool-permission.css +134 -0
  102. package/packages/connectors/cloudflare/package.json +13 -3
  103. package/packages/connectors/cloudflare/src/api-client.js +3 -2
  104. package/packages/connectors/cloudflare/src/families/vectorize.js +127 -0
  105. package/packages/connectors/cloudflare/src/index.js +1 -0
  106. package/packages/heuristic-theme/README.md +2 -2
  107. package/packages/heuristic-theme/package.json +8 -3
  108. package/packages/heuristic-theme/src/registry.js +2 -2
  109. package/packages/heuristic-theme/src/theme.js +1 -1
  110. package/packages/heuristic-theme/test/theme.test.mjs +1 -1
  111. package/packages/identity/.agentsam/features/oauth-login-portal/agentsam.feature.json +1 -1
  112. package/packages/identity/.agentsam/features/oauth-login-portal/providers.json +27 -7
  113. package/packages/identity/README.md +2 -2
  114. package/packages/identity/migrations/D1_SCHEMA_MAPPING.md +18 -15
  115. package/packages/identity/migrations/apply-portable.js +109 -0
  116. package/packages/identity/migrations/sqlite/004_identity_oauth_consent_catalog.sql +1 -1
  117. package/packages/identity/migrations/sqlite/005_identity_company_native.sql +52 -0
  118. package/packages/identity/package.json +27 -6
  119. package/packages/identity/schema/agentsam.identity/manifest.json +101 -0
  120. package/packages/identity/scripts/local-identity-bridge.mjs +13 -7
  121. package/packages/identity/scripts/preview-auth-portal.mjs +6 -6
  122. package/packages/identity/src/adapters/cloudflare-d1/index.js +8 -401
  123. package/packages/identity/src/adapters/iam-compat/index.js +540 -0
  124. package/packages/identity/src/adapters/portable-d1/index.js +18 -0
  125. package/packages/identity/src/adapters/portable-store.js +479 -0
  126. package/packages/identity/src/adapters/sqlite/index.js +13 -312
  127. package/packages/identity/src/contracts/auth-config.js +0 -1
  128. package/packages/identity/src/contracts/identity-store.js +56 -5
  129. package/packages/identity/src/contracts/provider.js +1 -0
  130. package/packages/identity/src/contracts/sign-in-options.js +104 -0
  131. package/packages/identity/src/core/constants.js +1 -1
  132. package/packages/identity/src/core/session-policy.js +31 -0
  133. package/packages/identity/src/frontend/auth-portal/pages/login.html +6 -6
  134. package/packages/identity/src/frontend/auth-portal/pages/reset.html +5 -5
  135. package/packages/identity/src/frontend/auth-portal/pages/signup.html +5 -5
  136. package/packages/identity/src/frontend/auth-portal/shared/company-branding.js +1 -1
  137. package/packages/identity/src/frontend/auth-portal/shared/desktop-identity-bridge.js +6 -37
  138. package/packages/identity/src/index.js +28 -1
  139. package/packages/identity/src/migrations/README.md +23 -23
  140. package/packages/identity/src/oauth/README.md +1 -1
  141. package/packages/identity/src/oauth/credentials.js +10 -11
  142. package/packages/identity/src/oauth/google-desktop-exchange.js +195 -27
  143. package/packages/identity/src/oauth/iam-platform.js +21 -9
  144. package/packages/identity/src/oauth/native-handoff.js +136 -0
  145. package/packages/identity/src/providers/chatgpt/headers.js +65 -0
  146. package/packages/identity/src/providers/chatgpt/index.js +86 -0
  147. package/packages/identity/src/providers/chatgpt/mapper.js +43 -0
  148. package/packages/identity/src/providers/chatgpt/paths.js +45 -0
  149. package/packages/identity/src/providers/github/oauth.js +1 -2
  150. package/packages/identity/src/providers/github/profile.js +16 -2
  151. package/packages/identity/src/providers/index.js +11 -3
  152. package/packages/identity/src/server/identity-service.js +2 -1
  153. package/packages/identity/src/server/worker-router.js +71 -18
  154. package/packages/identity/tests/chatgpt-provider.test.mjs +75 -0
  155. package/packages/identity/tests/google-desktop-identity-login.test.mjs +210 -0
  156. package/packages/identity/tests/identity-init-scaffold.test.mjs +15 -4
  157. package/packages/identity/tests/lane1-identity-store-parity.test.mjs +527 -0
  158. package/packages/identity/tests/lane1-packed-consumer.test.mjs +175 -0
  159. package/packages/identity/tests/native-oauth-handoff.test.mjs +292 -0
  160. package/packages/identity/tests/oauth-credentials.test.mjs +4 -4
  161. package/packages/identity/tests/preview-auth-portal.test.mjs +4 -2
  162. package/packages/identity/tests/session-routes-policy.test.mjs +13 -1
  163. package/packages/identity/tests/worker-runtime-boundary.test.mjs +11 -0
  164. package/packages/providers/completeful/package.json +7 -2
  165. package/packages/theme-church-site/package.json +17 -6
  166. package/packages/theme-church-site/src/harvest.json +4 -2
  167. package/packages/theme-church-site/src/index.js +7 -3
  168. package/packages/theme-church-site/test/theme.test.mjs +4 -2
  169. package/packages/theme-companions-site/package.json +17 -6
  170. package/packages/theme-companions-site/src/harvest.json +4 -2
  171. package/packages/theme-companions-site/src/index.js +7 -3
  172. package/packages/theme-companions-site/test/theme.test.mjs +4 -2
  173. package/packages/theme-floors-site/package.json +17 -6
  174. package/packages/theme-floors-site/src/harvest.json +4 -2
  175. package/packages/theme-floors-site/src/index.js +7 -3
  176. package/packages/theme-floors-site/test/theme.test.mjs +4 -2
  177. package/packages/theme-fuelnfree-site/package.json +17 -6
  178. package/packages/theme-fuelnfree-site/src/harvest.json +4 -2
  179. package/packages/theme-fuelnfree-site/src/index.js +7 -3
  180. package/packages/theme-fuelnfree-site/test/theme.test.mjs +4 -2
  181. package/packages/theme-handyman-site/package.json +17 -6
  182. package/packages/theme-handyman-site/src/harvest.json +4 -2
  183. package/packages/theme-handyman-site/src/index.js +7 -3
  184. package/packages/theme-handyman-site/test/theme.test.mjs +4 -2
  185. package/packages/theme-insurance-site/package.json +17 -6
  186. package/packages/theme-insurance-site/src/harvest.json +4 -2
  187. package/packages/theme-insurance-site/src/index.js +7 -3
  188. package/packages/theme-insurance-site/test/theme.test.mjs +4 -2
  189. package/packages/theme-scenes/README.md +1 -1
  190. package/packages/theme-scenes/package.json +4 -3
  191. package/packages/theme-scenes/src/registry.js +187 -0
  192. package/packages/theme-shinshu-site/package.json +17 -6
  193. package/packages/theme-shinshu-site/src/harvest.json +4 -2
  194. package/packages/theme-shinshu-site/src/index.js +7 -3
  195. package/packages/theme-shinshu-site/test/theme.test.mjs +4 -2
  196. package/packages/work-graph/package.json +14 -4
  197. package/protocol/FILEMETA_V1.md +2 -2
  198. package/protocol/capabilities/manifest.json +1 -1
  199. package/protocol/database/agentsam.schema-pack.v1.schema.json +72 -0
  200. package/protocol/presets/catalog.json +2 -2
  201. package/protocol/theme-refinery/lineage-registry.json +105 -0
  202. package/protocol/theme-refinery/product-metadata.schema.json +21 -1
  203. package/skills/grok-auth/SKILL.md +110 -0
  204. package/skills/grok-auth/agentsam.skill.json +25 -0
  205. package/skills/grok-auth/references/grok-identity.md +64 -0
  206. package/skills/grok-auth/references/per-user-data.md +49 -0
  207. package/skills/grok-auth/references/prewired-and-env.md +54 -0
  208. package/skills/grok-auth/references/session-ui.md +133 -0
  209. package/skills/grok-auth/references/sign-in-methods.md +55 -0
  210. package/skills/grok-auth/references/wiring.md +71 -0
  211. package/skills/grok-building-games/SKILL.md +213 -0
  212. package/skills/grok-building-games/agentsam.skill.json +25 -0
  213. package/skills/grok-building-games/references/3d-libs.md +64 -0
  214. package/skills/grok-building-games/references/ai-pathfinding.md +122 -0
  215. package/skills/grok-building-games/references/audio.md +129 -0
  216. package/skills/grok-building-games/references/babylon.md +202 -0
  217. package/skills/grok-building-games/references/collision-physics.md +122 -0
  218. package/skills/grok-building-games/references/ecs-architecture.md +111 -0
  219. package/skills/grok-building-games/references/game-feel-juice.md +110 -0
  220. package/skills/grok-building-games/references/genres/board-card-chess.md +89 -0
  221. package/skills/grok-building-games/references/genres/endless-runner.md +83 -0
  222. package/skills/grok-building-games/references/genres/fps.md +105 -0
  223. package/skills/grok-building-games/references/genres/platformer-2d.md +97 -0
  224. package/skills/grok-building-games/references/genres/puzzle-match3-tetris.md +131 -0
  225. package/skills/grok-building-games/references/genres/racing-kart.md +106 -0
  226. package/skills/grok-building-games/references/genres/topdown-twin-stick.md +97 -0
  227. package/skills/grok-building-games/references/genres/tower-defense.md +84 -0
  228. package/skills/grok-building-games/references/genres/voxel-minecraft.md +89 -0
  229. package/skills/grok-building-games/references/input.md +139 -0
  230. package/skills/grok-building-games/references/phaser.md +277 -0
  231. package/skills/grok-building-games/references/procedural-generation.md +141 -0
  232. package/skills/grok-building-games/references/save-persistence.md +108 -0
  233. package/skills/grok-building-games/references/threejs-foundational.md +148 -0
  234. package/skills/grok-controls/SKILL.md +274 -0
  235. package/skills/grok-controls/agentsam.skill.json +25 -0
  236. package/skills/grok-design-ui/SKILL.md +122 -0
  237. package/skills/grok-design-ui/agentsam.skill.json +25 -0
  238. package/skills/grok-design-ui/references/animations.md +379 -0
  239. package/skills/grok-design-ui/references/performance.md +88 -0
  240. package/skills/grok-design-ui/references/refined-ui.md +384 -0
  241. package/skills/grok-design-ui/references/surfaces.md +247 -0
  242. package/skills/grok-design-ui/references/typography.md +123 -0
  243. package/skills/grok-game-animation-frames/SKILL.md +84 -0
  244. package/skills/grok-game-animation-frames/agentsam.skill.json +25 -0
  245. package/skills/grok-game-asset-core/SKILL.md +69 -0
  246. package/skills/grok-game-asset-core/agentsam.skill.json +25 -0
  247. package/skills/grok-game-character-consistency/SKILL.md +69 -0
  248. package/skills/grok-game-character-consistency/agentsam.skill.json +25 -0
  249. package/skills/grok-game-tilesets/SKILL.md +65 -0
  250. package/skills/grok-game-tilesets/agentsam.skill.json +25 -0
  251. package/skills/grok-game-ui-icons/SKILL.md +56 -0
  252. package/skills/grok-game-ui-icons/agentsam.skill.json +25 -0
  253. package/skills/grok-generate2dmap/LICENSE +21 -0
  254. package/skills/grok-generate2dmap/SKILL.md +120 -0
  255. package/skills/grok-generate2dmap/SOURCE.md +6 -0
  256. package/skills/grok-generate2dmap/agentsam.skill.json +25 -0
  257. package/skills/grok-generate2dmap/references/deliverables.md +101 -0
  258. package/skills/grok-generate2dmap/references/layered-map-contract.md +209 -0
  259. package/skills/grok-generate2dmap/references/map-strategies.md +341 -0
  260. package/skills/grok-generate2dmap/references/object-production-gate.md +24 -0
  261. package/skills/grok-generate2dmap/references/pipeline.md +149 -0
  262. package/skills/grok-generate2dmap/references/prop-pack-contract.md +174 -0
  263. package/skills/grok-generate2dmap/references/side-scroll-stages.md +29 -0
  264. package/skills/grok-generate2dmap/scripts/compose_layered_preview.py +157 -0
  265. package/skills/grok-generate2dmap/scripts/extract_prop_pack.py +369 -0
  266. package/skills/grok-generate2dsprite/LICENSE +21 -0
  267. package/skills/grok-generate2dsprite/SKILL.md +313 -0
  268. package/skills/grok-generate2dsprite/SOURCE.md +6 -0
  269. package/skills/grok-generate2dsprite/agentsam.skill.json +25 -0
  270. package/skills/grok-generate2dsprite/references/modes.md +124 -0
  271. package/skills/grok-generate2dsprite/references/prompt-rules.md +315 -0
  272. package/skills/grok-generate2dsprite/scripts/generate2dsprite.py +1031 -0
  273. package/skills/grok-generate2dsprite/scripts/make_layout_guide.py +109 -0
  274. package/skills/grok-imagine/SKILL.md +201 -0
  275. package/skills/grok-imagine/agentsam.skill.json +25 -0
  276. package/skills/grok-multiplayer-p2p/SKILL.md +111 -0
  277. package/skills/grok-multiplayer-p2p/agentsam.skill.json +25 -0
  278. package/skills/grok-multiplayer-p2p/references/react-binding.md +144 -0
  279. package/skills/grok-multiplayer-p2p/references/signaling-relay.md +269 -0
  280. package/skills/grok-neon/SKILL.md +157 -0
  281. package/skills/grok-neon/agentsam.skill.json +25 -0
  282. package/skills/grok-og/SKILL.md +102 -0
  283. package/skills/grok-og/agentsam.skill.json +25 -0
  284. package/skills/grok-og/references/brand-pass.md +53 -0
  285. package/skills/grok-og/references/custom-card.md +107 -0
  286. package/skills/grok-og/references/favicon-and-icons.md +48 -0
  287. package/skills/grok-og/references/og-type-contract.md +18 -0
  288. package/skills/grok-og/references/placeholder-card.md +21 -0
  289. package/skills/grok-og/references/x-banner.md +41 -0
  290. package/skills/grok-threejs/SKILL.md +67 -0
  291. package/skills/grok-threejs/agentsam.skill.json +25 -0
  292. package/skills/grok-threejs/references/llms-full.txt +2780 -0
  293. package/skills/grok-video2dsprite/LICENSE +21 -0
  294. package/skills/grok-video2dsprite/SKILL.md +236 -0
  295. package/skills/grok-video2dsprite/SOURCE.md +6 -0
  296. package/skills/grok-video2dsprite/agentsam.skill.json +25 -0
  297. package/skills/grok-video2dsprite/references/pipeline.md +90 -0
  298. package/skills/grok-video2dsprite/references/prompt-rules.md +63 -0
  299. package/skills/grok-video2dsprite/scripts/video2dsprite.py +490 -0
  300. package/skills/grok-xai-api/SKILL.md +152 -0
  301. package/skills/grok-xai-api/agentsam.skill.json +25 -0
  302. package/src/cli/command-catalog.js +46 -4
  303. package/src/cli/dispatch.js +1 -0
  304. package/src/cli.js +10 -0
  305. package/src/cloudflare/runtime-status.js +2 -1
  306. package/src/commands/autorag.js +67 -13
  307. package/src/commands/cheat-sheet.js +29 -4
  308. package/src/commands/codebaseindex.js +45 -2
  309. package/src/commands/knowledge.js +59 -2
  310. package/src/commands/machine-binary.js +103 -0
  311. package/src/commands/machine.js +137 -0
  312. package/src/commands/security.js +67 -4
  313. package/src/commands/setup.js +33 -16
  314. package/src/commands/status.js +8 -1
  315. package/src/features/resolve.js +1 -0
  316. package/src/knowledge/engine.js +21 -2
  317. package/src/knowledge/runtime-discovery.js +127 -0
  318. package/src/lib/identity-scaffold.js +53 -13
  319. package/src/lib/setup/recipes.js +1 -1
  320. package/src/models/discovery.js +40 -22
  321. package/src/models/inventory-core.d.ts +105 -0
  322. package/src/models/inventory-core.js +54 -6
  323. package/src/security/logs.js +3 -0
  324. package/src/ui/cli/help.js +41 -0
  325. package/test/apps-scaffold-contract.test.mjs +3 -2
  326. package/test/cli/api-key-env-whoami.test.mjs +2 -2
  327. package/test/cli/catalog-authority.test.mjs +64 -0
  328. package/test/cli/machine-command.test.mjs +34 -0
  329. package/test/fixtures/project-authority/customer-app/.agentsam/app.json +5 -0
  330. package/test/fixtures/project-authority/customer-app/apps/my-product/index.ts +1 -0
  331. package/test/fixtures/project-authority/customer-app/wrangler.toml +17 -0
  332. package/test/integration/autorag-project-authority.integration.test.mjs +51 -0
  333. package/test/integration/autorag-runtime-discovery.test.mjs +107 -0
  334. package/test/integration/cms-app-scaffold.test.mjs +37 -31
  335. package/test/integration/cms-site-tenancy-contract.test.mjs +28 -17
  336. package/test/integration/codebaseindex-ingest.test.mjs +41 -0
  337. package/test/integration/database-hosted-honesty.test.mjs +49 -0
  338. package/test/integration/desktop-keychain-boundary.test.mjs +45 -0
  339. package/test/integration/hosted-work-host-authority.test.mjs +47 -0
  340. package/test/integration/inventory-eligibility.test.mjs +59 -0
  341. package/test/integration/local-provider-bridge.test.mjs +65 -0
  342. package/test/integration/local-studio-settings-production.test.mjs +40 -0
  343. package/test/integration/lockfile-sync.test.mjs +26 -0
  344. package/test/integration/provider-env-cli.test.mjs +13 -3
  345. package/test/integration/runtime-status.integration.test.mjs +16 -1
  346. package/test/integration/theme-package-registry.test.mjs +31 -0
  347. package/test/repository-snapshot-view.test.mjs +2 -2
  348. package/test/security.test.mjs +14 -0
  349. package/test/terminal-machine-identity.test.mjs +2 -2
  350. package/apps/client-cms-editor/backend/src/demo-bootstrap.ts +0 -145
  351. package/packages/agentsam-nav/dist/Nav.d.ts +0 -43
  352. package/packages/agentsam-nav/dist/NavCollapsible.d.ts +0 -10
  353. package/packages/agentsam-nav/dist/NavContent.d.ts +0 -2
  354. package/packages/agentsam-nav/dist/NavFooter.d.ts +0 -2
  355. package/packages/agentsam-nav/dist/NavGroup.d.ts +0 -3
  356. package/packages/agentsam-nav/dist/NavHeader.d.ts +0 -2
  357. package/packages/agentsam-nav/dist/NavMenu.d.ts +0 -22
  358. package/packages/agentsam-nav/dist/NavProvider.d.ts +0 -35
  359. package/packages/agentsam-nav/dist/NavTrigger.d.ts +0 -2
  360. package/packages/agentsam-nav/dist/Surfaces.d.ts +0 -41
  361. package/packages/agentsam-nav/dist/browser.d.ts +0 -11
  362. package/packages/agentsam-nav/dist/browser.global.js +0 -132
  363. package/packages/agentsam-nav/dist/browser.js +0 -613
  364. package/packages/agentsam-nav/dist/contracts.d.ts +0 -76
  365. package/packages/agentsam-nav/dist/index.d.ts +0 -11
  366. package/packages/agentsam-nav/dist/index.js +0 -614
  367. package/packages/agentsam-nav/dist/legacy.css +0 -83
  368. package/packages/agentsam-nav/dist/shell.css +0 -113
  369. package/packages/agentsam-nav/dist/theme.css +0 -113
  370. package/packages/agentsam-nav/dist/utils.d.ts +0 -1
  371. package/packages/agentsam-repository/src/goap.js.bak-20260922011251 +0 -670
@@ -0,0 +1,133 @@
1
+ # Reading the user, protecting routes, and preventing flicker
2
+
3
+ ## When sign-in UI may render (hard rules)
4
+
5
+ - **Connector / owner-data apps: never gate the data fetch behind a session.**
6
+ When the data comes from the app's connector grants, the fetch runs on the
7
+ gate-injected connector token — a chain that does not involve the app
8
+ session. Fetch first; use the session for personalization only (greeting,
9
+ per-user rows). Requiring sign-in before fetching adds a click that changes
10
+ nothing.
11
+ - **A sign-in CTA may render only after the session check has RESOLVED to no
12
+ user** — never while `isPending` is true (no CTA flash on load), and never
13
+ as a reaction to a data error (the `app-data` skill's error mapping owns
14
+ those states; only its `login` kind ever shows "Continue with Grok").
15
+ - **In preview, gate identity signs the owner in with zero clicks** — a
16
+ visible sign-in button for the owner in the preview is a bug to fix, not a
17
+ style choice (`grok-identity.md`).
18
+ - **Use `<SignInGate>` from `@/lib/auth/gates`** — `{ children, fallback? }`:
19
+ nothing while pending, `children` when signed in, `fallback` (or the
20
+ standard provider buttons) only once signed out is known. Do not hand-roll
21
+ sign-in CTAs from `useCurrentUser()`.
22
+
23
+ ## Reading the user / protecting routes
24
+
25
+ `@/lib/auth/use-current-user` (with auth on these reflect the REAL session, so a
26
+ preview visitor is signed out until they sign in):
27
+
28
+ - `useCurrentUser()` → `AppUser | null` — for display. `null` means *loading OR
29
+ signed out*, so never redirect on it alone.
30
+ - `useCurrentUserState()` → `{ user, isPending }` — for guards: wait for
31
+ `isPending` to clear before treating `user: null` as signed out, or a hard
32
+ reload bounces signed-in users to sign-in.
33
+
34
+ **State components** from `@/lib/auth/gates`: `SignedIn`, `SignedOut`,
35
+ `SignInGate` (`{ children, fallback? }` — nothing while pending, `children`
36
+ signed in, `fallback` or the standard provider buttons only once signed out is
37
+ known; prefer it over hand-rolled sign-in CTAs), `RedirectToSignIn`,
38
+ `UserButton`. (When auth is disabled via `VITE_AUTH_ENABLED=false` they apply
39
+ dev-user semantics so a non-auth app still renders.)
40
+
41
+ ```tsx
42
+ import { useCurrentUser, useCurrentUserState } from "@/lib/auth/use-current-user";
43
+ import { RedirectToSignIn, SignedIn, SignedOut, UserButton } from "@/lib/auth/gates";
44
+
45
+ function Navbar() {
46
+ const user = useCurrentUser(); // display only — null may just mean "loading"
47
+ return (
48
+ <>
49
+ <span>{user?.displayName ?? "Guest"}</span>
50
+ <SignedOut><a href="/login">Sign in</a></SignedOut>
51
+ <SignedIn><UserButton /></SignedIn>
52
+ </>
53
+ );
54
+ }
55
+
56
+ function AccountPage() {
57
+ const { user, isPending } = useCurrentUserState();
58
+ if (isPending) return null; // session still resolving
59
+ if (!user) return <RedirectToSignIn />; // client-side Navigate — not window.location
60
+ return <h1>Welcome, {user.displayName}</h1>;
61
+ }
62
+ ```
63
+
64
+ Sign out with `<UserButton />` or `signOut()` from `@/lib/auth/client`.
65
+
66
+ Session loading is the **same in live preview and when deployed**: wait for
67
+ `isPending` from `useCurrentUserState()` (backed by `/api/auth/get-session`).
68
+ The only live-preview difference is **how sign-in starts** (popup + bearer hand-off
69
+ instead of a full-page OAuth redirect) — not how guests vs signed-in users are
70
+ detected. Prefer `<RedirectToSignIn />` (TanStack `<Navigate>`) over
71
+ `window.location.href = "/login"` so a signed-out redirect does not full-reload
72
+ the SPA.
73
+
74
+ ## Preventing auth flicker
75
+
76
+ `useSession()` resolves on the client, so a naive UI flashes signed-out →
77
+ signed-in on load. Rules:
78
+
79
+ 1. **Gate on `isPending`, not `user` alone — and render a same-sized skeleton.**
80
+ Showing the SAME placeholder while `isPending` (server render + first client
81
+ paint) makes it one clean swap (skeleton → content) with no flash and no SSR
82
+ hydration mismatch. Don't return `null` in a slot that then grows — reserve the
83
+ space:
84
+
85
+ ```tsx
86
+ import { useCurrentUserState } from "@/lib/auth/use-current-user";
87
+ import { UserButton } from "@/lib/auth/gates";
88
+
89
+ function AuthSlot() {
90
+ const { user, isPending } = useCurrentUserState();
91
+ if (isPending) return <div className="h-8 w-8 animate-pulse rounded-full bg-black/10" />;
92
+ return user ? <UserButton /> : <a href="/login">Sign in</a>;
93
+ }
94
+ ```
95
+
96
+ 2. **Guard at a layout boundary** (nav / page shell), not in leaf components that
97
+ mount/unmount — `useSession` is one shared store, so keep one stable consumer
98
+ per region instead of re-gating everywhere.
99
+
100
+ 3. **Zero-flash when deployed: SSR the session from the cookie.** On a deployed
101
+ app (and top-level navigations) the session cookie is same-origin, so the server
102
+ already knows the user on the first request — resolve it in the root route and
103
+ render the authed shell immediately:
104
+
105
+ ```tsx
106
+ // src/routes/__root.tsx (excerpt)
107
+ import { createServerFn } from "@tanstack/react-start";
108
+ import { createRootRoute } from "@tanstack/react-router";
109
+
110
+ const fetchSessionUser = createServerFn({ method: "GET" }).handler(async () => {
111
+ // Cookie path only — works when deployed / on top-level loads.
112
+ const { getSessionUser } = await import("@/lib/auth/verify.server");
113
+ const u = await getSessionUser();
114
+ return u ? { id: u.id, email: u.email } : null;
115
+ });
116
+
117
+ export const Route = createRootRoute({
118
+ beforeLoad: async () => ({ sessionUser: await fetchSessionUser() }),
119
+ // Merge into the existing root — keep the existing head().
120
+ // component: prefer `sessionUser` for the FIRST paint when deployed, then
121
+ // `useCurrentUserState()` for live in-page updates.
122
+ });
123
+ ```
124
+
125
+ Sign-in/out navigate, so `beforeLoad` re-runs and the context stays fresh; call
126
+ `router.invalidate()` if you change auth state without navigating.
127
+
128
+ In live preview the session often rides a bearer after popup sign-in, so cookie
129
+ SSR may still return null until the client `useSession()` runs with the bearer
130
+ attached — still gate on `isPending`, same as when deployed.
131
+
132
+ The template already enables Better Auth's `session.cookieCache`, so `/get-session`
133
+ answers from a cookie when one is present (no DB round-trip).
@@ -0,0 +1,55 @@
1
+ # Supported sign-in methods (Google, X, email/password — and nothing else)
2
+
3
+ Use **only** these three — no other method is supported:
4
+
5
+ - **Google** and **X** — federated through the Grok broker (pre-wired here). The
6
+ broker federates these two upstreams and nothing else, so do **not** add entries
7
+ to `GROK_PROVIDERS` beyond them (the broker rejects an unknown `idp`).
8
+ - **Email + password** — this app's OWN Better Auth, persisted in your database
9
+ (never the broker, never mocked). Better Auth is DB-backed in BOTH modes — real
10
+ Postgres when deployed and the embedded PGLite in the sandbox preview — so
11
+ email/password accounts are stored and survive across requests, **in preview
12
+ too**. It's off by default. Enable it by editing **only**
13
+ `src/lib/auth/email-password.ts`:
14
+
15
+ ```ts
16
+ // src/lib/auth/email-password.ts
17
+ export const emailAndPasswordEnabled = true; // was false
18
+ ```
19
+
20
+ **Do not edit or rewrite `src/lib/auth/server.ts`** (or any other file under
21
+ `src/lib/auth/` except `email-password.ts` for this flag). That file is
22
+ pre-wired; "fixing" it by regenerating Better Auth config breaks live-preview
23
+ sign-in.
24
+
25
+ The pre-applied schema already has the `account.password` column — no migration
26
+ needed. Then build sign-up / sign-in forms with `authClient.signUp.email(...)`
27
+ and `authClient.signIn.email(...)` from `@/lib/auth/client`.
28
+
29
+ **Do not** add `emailAndPassword` as a plugin entry (that is a syntax/type
30
+ error). **Do not** invent a new Better Auth config.
31
+
32
+ If sign-up/sign-in returns **"Invalid origin"**, do **not** disable CSRF and
33
+ do **not** edit `server.ts`. The template's `trustedOrigins` already covers
34
+ `*.grok-sandbox.com` and local loopback on port 8080 (`localhost` /
35
+ `127.0.0.1` / `[::1]`). Open the app at one of those origins (not a random
36
+ host/port).
37
+
38
+ Do **NOT** add or use anything else: no other social / OAuth providers (GitHub,
39
+ Apple, Discord, Microsoft, Facebook, …), and no magic links, passkeys, one-time
40
+ codes / OTP, phone / SMS, or anonymous sign-in.
41
+
42
+ ## Security model (already handled — don't undo it)
43
+
44
+ - **Headless broker**: the broker offers the upstream sign-in methods
45
+ and holds their shared secrets; this app only holds its own per-app client
46
+ id/secret and names the upstream it wants via each provider's `idp` hint. The
47
+ broker forwards straight to Google/X. Users never see the broker.
48
+ - **`__Host-` cookies + `trustedOrigins`**: a sibling `*.grok.me` app can't toss a
49
+ `Domain=.grok.me` cookie, and Better Auth rejects cross-origin `/api/auth`
50
+ calls.
51
+ - **Sibling isolation**: `authMiddleware` rejects scripted cross-site/same-site
52
+ requests (Fetch-Metadata), so a sibling can't ride this app's session cookie
53
+ into its server functions.
54
+ - The upstream Google/X tokens live only on the broker; this app only ever gets a
55
+ broker-issued identity and mints its own local session.
@@ -0,0 +1,71 @@
1
+ # Wiring the routes (do this once)
2
+
3
+ **Live-preview popup is PRE-WIRED — do not create it.**
4
+ `signIn` opens `/auth/popup`; the template Vite plugin
5
+ (`authPopupPlugin` in `vite.config.ts`) serves it via `popup.server.ts`.
6
+ **Never** add `src/routes/auth/popup.tsx` (or any React page / client OAuth at
7
+ that path). Doing so loads the full app shell in the popup ("the app opened
8
+ instead of Google") — that is always wrong.
9
+
10
+ **1. Mount Better Auth** — create the catch-all API route (this is what makes
11
+ `/api/auth/*` work; the broker's OAuth callback lands here):
12
+
13
+ ```ts
14
+ // src/routes/api/auth/$.ts
15
+ import { createFileRoute } from "@tanstack/react-router";
16
+ import { auth } from "@/lib/auth/server";
17
+
18
+ export const Route = createFileRoute("/api/auth/$")({
19
+ server: {
20
+ handlers: {
21
+ GET: ({ request }) => auth.handler(request),
22
+ POST: ({ request }) => auth.handler(request),
23
+ },
24
+ },
25
+ });
26
+ ```
27
+
28
+ **2. Add a sign-in page** — buttons that kick off the broker flow. Import from
29
+ `@/lib/auth/client`. With the flag on, `authEnabled` is true in preview and
30
+ deployed, so the buttons show and work in the live preview; the `else` branch
31
+ shows while auth is still disabled (`VITE_AUTH_ENABLED=false`):
32
+
33
+ ```tsx
34
+ // src/routes/login.tsx
35
+ import { createFileRoute } from "@tanstack/react-router";
36
+ import { GROK_PROVIDERS, authEnabled, signIn } from "@/lib/auth/client";
37
+
38
+ export const Route = createFileRoute("/login")({ component: Login });
39
+
40
+ function Login() {
41
+ return (
42
+ <main className="grid min-h-screen place-items-center p-6">
43
+ <div className="w-full max-w-sm space-y-3">
44
+ <h1 className="text-xl font-semibold">Sign in</h1>
45
+ {authEnabled ? (
46
+ GROK_PROVIDERS.map((p) => (
47
+ <button
48
+ key={p.providerId}
49
+ type="button"
50
+ onClick={() => signIn(p.providerId, { callbackURL: "/" })}
51
+ className="w-full cursor-pointer rounded-md border border-neutral-300 px-4 py-2 hover:bg-neutral-100 dark:border-neutral-700 dark:hover:bg-neutral-900"
52
+ >
53
+ Continue with {p.label}
54
+ </button>
55
+ ))
56
+ ) : (
57
+ <p className="text-sm text-neutral-500">Sign-in is disabled.</p>
58
+ )}
59
+ </div>
60
+ </main>
61
+ );
62
+ }
63
+ ```
64
+
65
+ `RedirectToSignIn` sends signed-out users to `/login` by default (override with
66
+ `<RedirectToSignIn to="/somewhere" />`). Style the page however you like — see
67
+ the `design-ui` skill.
68
+
69
+ That's it — call `signIn(providerId)` from your sign-in buttons. The popup,
70
+ bearer-token hand-off, and request attachment are all inside `src/lib/auth` +
71
+ the Vite plugin; leave them alone.
@@ -0,0 +1,213 @@
1
+ ---
2
+ name: building-games
3
+ description: >
4
+ Build browser games and interactive/canvas/3D experiences in this TanStack
5
+ Start + React app. Use for any game, simulation, or WebGL/Canvas experience —
6
+ 2D or 3D, single-player. Covers the game loop & timing, 3D orientation/camera
7
+ conventions, collision, performance, assets, audio, save, game feel, and
8
+ per-genre playbooks. For WASD / vehicle / flight **input signs and inverted
9
+ A/D**, open the **`controls`** skill — do not rely on this file or racing-kart
10
+ alone. Triggers on "game", "minecraft", "fps", "platformer", "racing",
11
+ "tetris", "snake", "shooter", "3d", "three.js", "canvas", "voxel", "physics".
12
+ metadata:
13
+ short-description: "Browser games: loop, 3D orientation, camera, perf, assets, genres"
14
+ user-invocable: false
15
+ ---
16
+
17
+ # Building Games
18
+
19
+ Build a **playable, correct** browser game — not a static screenshot. A game is
20
+ just a React route with a `<canvas>` (or `<Canvas>` for R3F) plus DOM overlay UI.
21
+ Style the overlay (start screen, HUD, menus) with the **`design-ui`** skill; this
22
+ skill owns the gameplay loop and world.
23
+
24
+ **Controls / inverted A/D:** open **`.grok/skills/controls/SKILL.md`** **before**
25
+ writing WASD, steering, or flight input. Vehicle/flight demos often ship with
26
+ A/D flipped if you only read this file or a single genre playbook.
27
+
28
+ **Scope note — single-player, bots, or small P2P co-op:**
29
+ - Ship **single-player** or **single-player + AI/bots** by default.
30
+ - **2–8 player co-op / casual realtime** (shared cursors, party games, casual
31
+ action among friends) is supported — use the **`multiplayer-p2p` skill**
32
+ (WebRTC mesh, signaled at `/api/rtc`). Read its trust model first.
33
+ - P2P is the only supported multiplayer right now. Do not half-build sockets
34
+ that can’t connect.
35
+
36
+ **References (load on demand):**
37
+ - **`controls` skill** (`../controls/`) — **required** for movement/steer/flight:
38
+ player-visible A/D, inverted-steer anti-pattern, flight ailerons, mandatory
39
+ self-test + `window.__controlsTest`. Not optional for vehicles/planes.
40
+ - `references/threejs-foundational.md` — the deep 3D/loop/perf reference. Read for 3D.
41
+ - `references/3d-libs.md` — three.js + @react-three/fiber + drei + rapier usage.
42
+ - **`threejs` skill** (`../threejs/`) — official full Three.js + TSL API dump
43
+ (`llms-full.txt`). Load for advanced materials/shaders/WebGPU/loaders; not for
44
+ simple 2D canvas games.
45
+ - `references/babylon.md` — Babylon.js, the batteries-included 3D engine alternative.
46
+ - `references/phaser.md` — Phaser 3, the default engine for 2D games.
47
+ - `references/ecs-architecture.md` — entity-component-system structure for larger games.
48
+ - `references/genres/*.md` — per-genre playbooks (fps, platformer-2d, racing-kart,
49
+ puzzle-match3-tetris, voxel-minecraft, endless-runner, topdown-twin-stick,
50
+ tower-defense, board-card-chess). Genre files **do not** replace **`controls`**.
51
+ - `references/game-feel-juice.md`, `input.md`, `audio.md`, `collision-physics.md`,
52
+ `save-persistence.md`, `procedural-generation.md`, `ai-pathfinding.md`.
53
+ - **`game-asset-core`** (+ `game-animation-frames` / `game-tilesets` /
54
+ `game-character-consistency` / `game-ui-icons`) — engine-ready 2D art defaults
55
+ and verification when generating sprites, sheets, tiles, or UI (see §6).
56
+
57
+ Pick the specific genre/topic reference for the build; this file is the universal
58
+ core for loop/world. **Input signs → `controls`.** **2D game art → `game-asset-core`.**
59
+
60
+ ---
61
+
62
+ ## 1. Game loop & timing (the #1 correctness issue)
63
+
64
+ - Drive the loop with the engine's RAF loop (`renderer.setAnimationLoop`, R3F
65
+ `useFrame`, or `requestAnimationFrame` for 2D canvas). **Never** `setInterval`/
66
+ `setTimeout`/`Date.now()` for game timing.
67
+ - **Scale ALL movement/animation by delta time** (seconds) so speed is frame-rate
68
+ independent (60Hz vs 144Hz). Compute delta **once per frame** and reuse it.
69
+ - three.js: use `THREE.Timer` (not `Clock` — `Clock.getDelta()` returns ~0 on a
70
+ second call in the same frame, a classic freeze bug).
71
+ - **Cap delta** (`min(delta, 0.1)`) so a backgrounded tab doesn't teleport things.
72
+ - **Fixed timestep for physics/gameplay:** accumulate delta and step simulation at
73
+ a fixed rate (e.g. 1/60) while rendering at display rate — prevents tunneling and
74
+ non-determinism.
75
+
76
+ ## 2. Controls (delegate to the `controls` skill)
77
+
78
+ **Open `.grok/skills/controls/SKILL.md` before implementing any WASD / steer /
79
+ flight code.** That skill is the source of truth for:
80
+
81
+ - Player-visible **A = left / D = right** (chase cam, while moving forward)
82
+ - Why **`KeyA → steer−` + `yaw += steer * +rate` inverts** (most common bug)
83
+ - Vehicle vs FPS (strafe ≠ steer), fixed-wing ailerons, heli/drone notes
84
+ - Mandatory self-test + `window.__controlsTest` probe
85
+
86
+ Do **not** treat `genres/racing-kart.md` as the only place steer signs live —
87
+ planes, jetskis, and mechs never open it.
88
+
89
+ **Short reminder (full detail in `controls`):**
90
+
91
+ ```
92
+ // Vehicle yaw body (chase cam): A must increase yaw with this basis
93
+ forward = (-sin(yaw), 0, -cos(yaw))
94
+ // KeyA → steer = +1; yaw += steer * turnRate * speedFactor * dt
95
+ // WRONG (ships inverted): KeyA → steer = -1; yaw += steer * turnRate * dt
96
+ ```
97
+
98
+ - **Pointer lock:** mouse-look only — implement WASD yourself; click-to-play
99
+ overlay; dismiss on lock.
100
+ - Track keys with held state + **dt**; unify devices via `references/input.md`.
101
+ - **Finish:** run the `controls` skill checklist. Screenshot-only is insufficient
102
+ for vehicles/flight.
103
+
104
+ ## 3. 3D orientation & world objects (the "sideways/backwards" bugs)
105
+
106
+ - three.js is **right-handed, +Y up**: +X right, +Y up, +Z toward viewer. **Meshes
107
+ face +Z; cameras look −Z** (the classic "camera backwards" gotcha).
108
+ - Primitives like `Cone`/`Cylinder` point **+Y** by default → rotate to align a
109
+ tip with forward (`geo.rotateX(Math.PI/2)`).
110
+ - **Orienting a mesh to face `forward`** (meshes face **+Z**): simplest correct way
111
+ is `mesh.lookAt(mesh.position.clone().add(forward))`. To build the basis by hand,
112
+ set the **+Z column to `forward`** and choose the x-axis that keeps it a *proper*
113
+ right-handed rotation (`det = +1`):
114
+ `xAxis = normalize(cross(up, forward))`, then `makeBasis(xAxis, up, forward)`.
115
+ Note this is `cross(up, forward)` — **not** the movement `right = cross(forward, up)`
116
+ from §2. Targeting +Z (instead of a camera's −Z) flips the x-axis sign so that
117
+ `xAxis × up = forward`; the frame stays right-handed (no mirroring). Do **not** use
118
+ `makeBasis(xAxis, up, -forward)` for a mesh — that targets −forward (the *camera*
119
+ convention) so the mesh faces **backwards**.
120
+ - **Orienting a camera** to look along `forward` (cameras look **−Z**): set the +Z
121
+ column to `-forward` — `xAxis = normalize(cross(forward, up))`, then
122
+ `makeBasis(xAxis, up, -forward)` (or just `camera.lookAt(target)`).
123
+ - Keep a consistent world `up` so objects stay upright; only rotate flat primitives
124
+ to stand up.
125
+ - Verify glTF import orientation; debug with `AxesHelper`/`ArrowHelper`. Upright
126
+ self-test: characters stand on the ground plane, not lying/sunk.
127
+
128
+ ## 4. Camera must agree with movement
129
+
130
+ - Keep a **dedicated `moveForward`/`moveRight`** for movement, computed once and
131
+ never mutated by camera code (aliasing a shared temp vector makes camera and
132
+ movement disagree — a real repro bug).
133
+ - Third-person follow: `desired = playerPos + up*height + moveForward*(-followDist)`;
134
+ lerp the camera toward it (use exp-based smoothing, delta-scaled), `lookAt(player)`.
135
+ - Isolate-the-layer debug order: (1) keys register → (2) movement signs correct →
136
+ (3) camera agrees. Fix in that order.
137
+
138
+ ## 5. Performance
139
+
140
+ - **Minimize draw calls** (`renderer.info.render.calls`, target <100): share
141
+ materials, `InstancedMesh`/`BatchedMesh` for repeated objects, atlases.
142
+ - **Dispose GPU resources yourself** (`geometry/material/texture.dispose()`) on
143
+ level change — three.js does not GC them. **Pool** bullets/enemies/particles.
144
+ - No per-frame allocations (reuse temp vectors). Compress textures; LOD for distance.
145
+
146
+ ## 6. Assets (avoid the generated-photo trap)
147
+
148
+ - **Interactive 3D elements** (weapon viewmodels, characters, props, projectiles)
149
+ → build from **3D geometry / glTF**, not a generated image. A flat photorealistic
150
+ JPG of a gun-in-hands used as an FPS viewmodel looks wrong, can't animate, and
151
+ (JPG has **no alpha**) renders as a black box. Parent a real 3D viewmodel to the
152
+ camera as an overlay render layer.
153
+ - Reserve image generation for **flat 2D** assets only (textures, sky/menu
154
+ backgrounds, 2D sprites, UI art). **Never** use a generated photo as a 3D mesh,
155
+ viewmodel, or character substitute — build those in 3D geometry / glTF.
156
+ Set `crossOrigin="anonymous"` on images drawn to canvas/textures.
157
+ See the **`imagine`** skill (2D only — image tools cannot produce real 3D).
158
+ - **Engine-ready game art doctrine** → open **`game-asset-core`**
159
+ (`../game-asset-core/`) for defaults + blind verify + retry discipline, then the
160
+ matching specialist: **`game-animation-frames`** (loop / motion laws),
161
+ **`game-tilesets`**, **`game-character-consistency`**, **`game-ui-icons`**.
162
+ These are **QC/doctrine**, not the export pipeline. Do not ship stick-figure
163
+ placeholders when real art is expected.
164
+ - **2D game sprites / animation sheets** → run **`generate2dsprite`**
165
+ (`.grok/skills/generate2dsprite/SKILL.md`): solid **`#FF00FF`** magenta
166
+ `imagine_text_to_image` sheets + chroma postprocess scripts (magenta is required for the
167
+ processor). Wire transparent PNGs/GIFs into Canvas/Phaser. Still apply
168
+ **`game-asset-core`** (+ animation/character specialists when relevant).
169
+ - **2D maps / levels / prop packs** → open **`generate2dmap`**
170
+ (`.grok/skills/generate2dmap/SKILL.md`). Prefer foundation-only base + separate
171
+ props/collision for playable maps. Browser default: `raw_canvas` / Phaser.
172
+ Tileable ground/walls → also **`game-tilesets`** for 2×2 seam checks.
173
+ - **Optional denser locomotion** → run **`video2dsprite`** (Grok
174
+ `imagine_image_to_video` + sandbox scripts; magenta base). Prefer `generate2dsprite`
175
+ for crisp production heroes. Use **`game-animation-frames`** for loop/flip-test
176
+ laws; prefer **`video2dsprite`** over ad-hoc ffmpeg-only harvest in this
177
+ sandbox.
178
+
179
+ ## 7. Audio, save, feel
180
+ - **Audio**: unlock `AudioContext` on the first user gesture (tap-to-start) or iOS
181
+ is silent; re-resume on `visibilitychange`. (`references/audio.md`)
182
+ - **Save**: `localStorage`/IndexedDB with a `version` field + migrations.
183
+ - **Juice**: screen shake, hit-stop, eased tweens, particles — cheap, huge
184
+ perceived-quality lift. Keep presentation separate from simulation.
185
+
186
+ ## 8. Mobile
187
+ - Distinguish canvas buffer size from CSS size; respect `devicePixelRatio`.
188
+ - `touch-action: none`, letterbox-fit to a base resolution, handle orientation.
189
+ - Touch controls (virtual joystick + action buttons), ≥44px targets.
190
+
191
+ ---
192
+
193
+ ## Stack / engine choice
194
+ - **3D → three.js**, ideally via **@react-three/fiber + drei** (fits the React
195
+ app; drei gives pointer-lock/controls/loaders) + **@react-three/rapier** for
196
+ physics/character controllers. See `references/3d-libs.md`.
197
+ - **2D →** native Canvas 2D is enough for snake/tetris/flappy/platformer; reach for
198
+ Phaser only when the genre needs it.
199
+ - These game deps are **not preinstalled** — `npm install` them (and make sure they
200
+ land in `package.json` so the Vercel build has them).
201
+
202
+ ## Finish criteria (before "done")
203
+ - Loads with **no console errors**; visible gameplay (not a blank canvas).
204
+ - **`controls` skill self-test passed** (A = left / D = right from chase cam
205
+ while moving forward; flip one sign if inverted). Not screenshot-only.
206
+ - 3D upright & camera-agrees self-tests pass (§3, §4).
207
+ - Runs on mobile viewport with touch controls.
208
+ - Production build (`npm run build`) renders the built output, not just dev.
209
+ - **Share / X card:** open the **`og`** skill — custom `public/og.jpg` **and**
210
+ `"type": "x:game"` in `src/lib/og/site.json`. X uses `og:type="x:game"`
211
+ to present the unfurl as a game card; do not use `twitter:card` or invent
212
+ `x:type` for this. `browser-smoke` / `brand-check` warn when canvas apps omit
213
+ the `site.json` field.
@@ -0,0 +1,25 @@
1
+ {
2
+ "schema": "agentsam.skill.v1",
3
+ "id": "grok-building-games",
4
+ "name": "Grok \u00b7 building-games",
5
+ "description": "Browser games: loop, 3D orientation, camera, perf, assets, genres",
6
+ "icon": "skill",
7
+ "slash": {
8
+ "suggested": "/grok-building-games"
9
+ },
10
+ "instructions": {
11
+ "source": "local_file",
12
+ "ref": "SKILL.md"
13
+ },
14
+ "execution": {
15
+ "mode": "turn",
16
+ "tools": [],
17
+ "operations": [],
18
+ "capabilities": []
19
+ },
20
+ "provenance": {
21
+ "source": "apps/local-studio/.grok/skills",
22
+ "vendor": "grok",
23
+ "status": "imported"
24
+ }
25
+ }
@@ -0,0 +1,64 @@
1
+ # 3D libraries for this stack (three.js + React Three Fiber + drei + rapier)
2
+
3
+ The app is React/TanStack. The idiomatic way to do 3D here is **React Three
4
+ Fiber (R3F)** — write three.js as React components inside a `<Canvas>` on a
5
+ route. It deploys like any other page.
6
+
7
+ > These are **not preinstalled**. Install and confirm they land in `package.json`:
8
+ > `npm i three @react-three/fiber @react-three/drei @react-three/rapier`
9
+ > (+ `npm i -D @types/three`). If the deploy build has no three, the game is blank.
10
+
11
+ ## When to use what
12
+ - **three.js** — the engine. Raw three is fine for a self-contained canvas; prefer
13
+ R3F when the game has React UI/state around it.
14
+ - **@react-three/fiber** — renders three as React; `useFrame((state, delta) => …)`
15
+ is your game loop (delta is seconds — scale movement by it, see SKILL §1).
16
+ - **@react-three/drei** — helpers so you don't hand-roll bug-prone code:
17
+ `<PointerLockControls/>`, `useKeyboardControls`, `<OrbitControls/>`,
18
+ `useGLTF`, `<Environment/>`, `<Instances/>`, `<Stats/>`.
19
+ - **@react-three/rapier** — physics + **character controller** (capsule +
20
+ autostep + snap-to-ground). Use for FPS/platformer movement and collisions
21
+ instead of hand-rolled raycasts. `<Physics>`, `<RigidBody>`, `useRapier`.
22
+
23
+ ## Minimal R3F shape
24
+ ```tsx
25
+ import { Canvas, useFrame } from "@react-three/fiber";
26
+ import { PointerLockControls, useKeyboardControls } from "@react-three/drei";
27
+
28
+ function Player() {
29
+ useFrame((_, delta) => {
30
+ const d = Math.min(delta, 0.1); // cap delta (SKILL §1)
31
+ // move with a dedicated moveForward/moveRight basis (SKILL §2/§4)
32
+ });
33
+ return null;
34
+ }
35
+
36
+ export default function Game() {
37
+ return (
38
+ <Canvas camera={{ position: [0, 1.7, 5], fov: 75 }} shadows dpr={[1, 2]}>
39
+ {/* scene */}
40
+ <PointerLockControls /> {/* mouse-look ONLY — implement WASD yourself */}
41
+ <Player />
42
+ </Canvas>
43
+ );
44
+ }
45
+ ```
46
+
47
+ ## Gotchas (map to the SKILL universals)
48
+ - **Controls:** drei `PointerLockControls` is mouse-look only — WASD is yours
49
+ (SKILL §2). Gate `.lock()` behind a "click to play" overlay and dismiss it on lock.
50
+ - **Orientation:** meshes face +Z, camera looks −Z; right-handed +Y up (SKILL §3).
51
+ - **Delta:** `useFrame` delta is seconds; cap it; fixed-step physics via rapier's
52
+ own stepping. Don't read `THREE.Clock.getDelta()` twice a frame.
53
+ - **Perf:** `<Instances>`/`InstancedMesh` for repeats; dispose on unmount (R3F
54
+ auto-disposes objects it created, but not manual textures/loaders — dispose those).
55
+ Set `dpr={[1, 2]}` to cap retina cost.
56
+ - **Mobile:** R3F sets pixel ratio via `dpr`; still add touch controls + `touch-action:none`.
57
+
58
+ ## Alternatives
59
+ - **Babylon.js** (`references/babylon.md`) — batteries-included 3D (Havok physics,
60
+ inspector, SceneOptimizer). Viable if you want an all-in-one engine, but it's a
61
+ separate paradigm from React; default to three/R3F for consistency with the app.
62
+
63
+ Sources: R3F docs (https://r3f.docs.pmnd.rs), drei (https://github.com/pmndrs/drei),
64
+ react-three-rapier (https://github.com/pmndrs/react-three-rapier), three.js docs.