@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,34 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+ import { getCliCommand } from '../../src/cli/command-catalog.js';
7
+ import { resolveMachineBinary } from '../../src/commands/machine-binary.js';
8
+
9
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
10
+
11
+ test('machine command is catalogued as machine.inspect', () => {
12
+ const entry = getCliCommand('machine');
13
+ assert.equal(entry?.id, 'machine');
14
+ assert.equal(entry?.operation, 'machine.inspect');
15
+ assert.equal(entry?.common, true);
16
+ });
17
+
18
+ test('machine crate + CLI sources exist for graduation', () => {
19
+ assert.equal(fs.existsSync(path.join(root, 'native/agentsam-machine/Cargo.toml')), true);
20
+ assert.equal(fs.existsSync(path.join(root, 'native/agentsam-machine/cli/src/main.rs')), true);
21
+ assert.equal(fs.existsSync(path.join(root, 'src/commands/machine.js')), true);
22
+ assert.equal(fs.existsSync(path.join(root, 'src/commands/machine-binary.js')), true);
23
+ });
24
+
25
+ test('resolveMachineBinary finds crate binary or cargo fallback in this repo', () => {
26
+ const resolution = resolveMachineBinary();
27
+ assert.notEqual(resolution.kind, 'missing');
28
+ if (resolution.kind === 'binary') {
29
+ assert.equal(fs.existsSync(resolution.path), true);
30
+ } else {
31
+ assert.equal(resolution.kind, 'cargo');
32
+ assert.equal(fs.existsSync(resolution.manifest), true);
33
+ }
34
+ });
@@ -0,0 +1,5 @@
1
+ {
2
+ "schema": "agentsam.app-install.v1",
3
+ "app_id": "my-product",
4
+ "mount": "apps/my-product"
5
+ }
@@ -0,0 +1 @@
1
+ export const productName = 'Generic Customer Product';
@@ -0,0 +1,17 @@
1
+ name = "customer-product-worker"
2
+
3
+ [ai]
4
+ binding = "MY_AI"
5
+
6
+ [[vectorize]]
7
+ binding = "MY_VECTORS"
8
+ index_name = "customer-code-index"
9
+
10
+ [[d1_databases]]
11
+ binding = "DB"
12
+ database_name = "customer-db"
13
+ database_id = "00000000-0000-0000-0000-000000000001"
14
+
15
+ [[r2_buckets]]
16
+ binding = "CONTENT"
17
+ bucket_name = "customer-assets"
@@ -0,0 +1,51 @@
1
+ import assert from 'node:assert/strict';
2
+ import { execFileSync } from 'node:child_process';
3
+ import fs from 'node:fs';
4
+ import os from 'node:os';
5
+ import path from 'node:path';
6
+ import test from 'node:test';
7
+ import { fileURLToPath } from 'node:url';
8
+
9
+ const repoRoot = fileURLToPath(new URL('../..', import.meta.url));
10
+ const bin = path.join(repoRoot, 'bin', 'agentsam');
11
+ const fixture = path.join(repoRoot, 'test', 'fixtures', 'project-authority', 'customer-app');
12
+
13
+ function runAutorag(root, ...args) {
14
+ const stdout = execFileSync(process.execPath, [bin, 'autorag', ...args, '--cwd', root], {
15
+ cwd: root,
16
+ encoding: 'utf8',
17
+ env: { ...process.env, CLOUDFLARE_API_TOKEN: '', CLOUDFLARE_ACCOUNT_ID: '' },
18
+ });
19
+ return JSON.parse(stdout);
20
+ }
21
+
22
+ test('generic customer fixture discovers existing project resources and adopts Vectorize', () => {
23
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-project-authority-fixture-'));
24
+ try {
25
+ fs.cpSync(fixture, root, { recursive: true });
26
+ const status = runAutorag(root, 'status');
27
+ assert.deepEqual(status.discovery.scopes, ['apps']);
28
+ assert.equal(status.project_context.schema, 'agentsam.project-context.v1');
29
+ assert.equal(status.project_context.project.host_install.app_id, 'my-product');
30
+ assert.equal(status.project_context.resources.workers_ai.binding, 'MY_AI');
31
+ assert.equal(status.project_context.resources.vectorize[0].binding, 'MY_VECTORS');
32
+ assert.equal(status.project_context.resources.vectorize[0].index, 'customer-code-index');
33
+ assert.equal(status.project_context.resources.d1[0].binding, 'DB');
34
+ assert.equal(status.project_context.resources.r2[0].binding, 'CONTENT');
35
+ assert.equal(status.project_context.resources.vectorize[0].locally_executable, false);
36
+ assert.equal(status.project_context.resources.vectorize[0].remotely_executable, true);
37
+
38
+ const setup = runAutorag(root, 'setup', '--yes');
39
+ assert.deepEqual(setup.recommendation.scope, ['apps']);
40
+ assert.equal(setup.config.lane.backend, 'cloudflare_vectorize');
41
+ assert.equal(setup.config.lane.binding, 'MY_VECTORS');
42
+ assert.equal(setup.config.lane.index, 'customer-code-index');
43
+ assert.equal(setup.config.embedding.provider, 'none');
44
+
45
+ const policy = JSON.parse(fs.readFileSync(path.join(root, '.agentsam', 'knowledge.json'), 'utf8'));
46
+ assert.equal(policy.lane.binding, 'MY_VECTORS');
47
+ assert.equal(policy.lane.index, 'customer-code-index');
48
+ } finally {
49
+ fs.rmSync(root, { recursive: true, force: true });
50
+ }
51
+ });
@@ -0,0 +1,107 @@
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 { discoverKnowledgeRuntime } from '../../src/knowledge/runtime-discovery.js';
7
+
8
+ test('AutoRAG runtime discovery sees local index and Cloudflare Vectorize without local knowledge config', () => {
9
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-autorag-runtime-'));
10
+ try {
11
+ fs.mkdirSync(path.join(root, '.agentsam', 'knowledge'), { recursive: true });
12
+ fs.writeFileSync(path.join(root, '.agentsam', 'knowledge', 'index.sqlite'), '');
13
+ fs.writeFileSync(
14
+ path.join(root, 'wrangler.toml'),
15
+ [
16
+ 'name = "demo-worker"',
17
+ '',
18
+ '[ai]',
19
+ 'binding = "AGENTSAM_WAI"',
20
+ '',
21
+ '[[vectorize]]',
22
+ 'binding = "DEMO_VECTORIZE"',
23
+ 'index_name = "demo-index-1024"',
24
+ '',
25
+ ].join('\n'),
26
+ );
27
+
28
+ const runtime = discoverKnowledgeRuntime(root);
29
+ assert.equal(runtime.local_index.exists, true);
30
+ assert.equal(runtime.cloudflare.configured, true);
31
+ assert.equal(runtime.cloudflare.worker_name, 'demo-worker');
32
+ assert.equal(runtime.cloudflare.ai_binding, 'AGENTSAM_WAI');
33
+ assert.deepEqual(runtime.cloudflare.vectorize, [{
34
+ binding: 'DEMO_VECTORIZE',
35
+ index: 'demo-index-1024',
36
+ source: 'wrangler_config',
37
+ }]);
38
+ assert.deepEqual(runtime.lanes.map((lane) => lane.backend), [
39
+ 'local_exact',
40
+ 'cloudflare_vectorize',
41
+ ]);
42
+ } finally {
43
+ fs.rmSync(root, { recursive: true, force: true });
44
+ }
45
+ });
46
+
47
+ test('project context receipt separates observed deployment resources from local executability', () => {
48
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-project-context-'));
49
+ try {
50
+ fs.mkdirSync(path.join(root, '.agentsam'), { recursive: true });
51
+ fs.writeFileSync(path.join(root, '.agentsam', 'app.json'), JSON.stringify({ schema: 'agentsam.app-install.v1', app_id: 'my-product' }));
52
+ fs.writeFileSync(path.join(root, 'wrangler.toml'), [
53
+ 'name = "customer-worker"',
54
+ '[ai]',
55
+ 'binding = "MY_AI"',
56
+ '[[vectorize]]',
57
+ 'binding = "MY_VECTORS"',
58
+ 'index_name = "customer-code-index"',
59
+ '[[d1_databases]]',
60
+ 'binding = "DB"',
61
+ 'database_name = "customer-db"',
62
+ 'database_id = "00000000-0000-0000-0000-000000000001"',
63
+ '[[r2_buckets]]',
64
+ 'binding = "CONTENT"',
65
+ 'bucket_name = "customer-assets"',
66
+ '',
67
+ ].join('\n'));
68
+
69
+ const runtime = discoverKnowledgeRuntime(root, { env: {} });
70
+ assert.equal(runtime.schema, 'agentsam.project-context.v1');
71
+ assert.equal(runtime.project.host_install.app_id, 'my-product');
72
+ assert.equal(runtime.resources.workers_ai.binding, 'MY_AI');
73
+ assert.equal(runtime.resources.workers_ai.locally_executable, false);
74
+ assert.equal(runtime.resources.workers_ai.remotely_executable, true);
75
+ assert.equal(runtime.resources.vectorize[0].binding, 'MY_VECTORS');
76
+ assert.equal(runtime.resources.vectorize[0].index, 'customer-code-index');
77
+ assert.equal(runtime.resources.vectorize[0].locally_executable, false);
78
+ assert.equal(runtime.resources.vectorize[0].remotely_executable, true);
79
+ assert.equal(runtime.resources.d1[0].binding, 'DB');
80
+ assert.equal(runtime.resources.r2[0].binding, 'CONTENT');
81
+ assert.equal(runtime.knowledge.policy_configured, false);
82
+ assert.equal(runtime.knowledge.suggested_backend, 'cloudflare_vectorize');
83
+ } finally {
84
+ fs.rmSync(root, { recursive: true, force: true });
85
+ }
86
+ });
87
+
88
+ test('project context receipt surfaces knowledge policy versus Wrangler drift', () => {
89
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-project-context-drift-'));
90
+ try {
91
+ fs.writeFileSync(path.join(root, 'wrangler.toml'), [
92
+ 'name = "customer-worker"',
93
+ '[[vectorize]]',
94
+ 'binding = "MY_VECTORS"',
95
+ 'index_name = "customer-code-index"',
96
+ '',
97
+ ].join('\n'));
98
+ const runtime = discoverKnowledgeRuntime(root, {
99
+ env: {},
100
+ knowledgeConfig: { lane: { backend: 'cloudflare_vectorize', binding: 'OTHER_VECTORS', index: 'other-index' } },
101
+ });
102
+ assert.equal(runtime.conflicts.length, 1);
103
+ assert.equal(runtime.conflicts[0].kind, 'knowledge_deployment_drift');
104
+ } finally {
105
+ fs.rmSync(root, { recursive: true, force: true });
106
+ }
107
+ });
@@ -9,7 +9,7 @@ import { fileURLToPath } from 'node:url';
9
9
  const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
10
10
  const cmsBin = path.join(root, 'apps/client-cms-editor/bin/agentsam-cms.mjs');
11
11
 
12
- function scaffold(persistence) {
12
+ function scaffold(persistence, extraArgs = []) {
13
13
  const temp = fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-cms-scaffold-'));
14
14
  const target = path.join(temp, 'editor');
15
15
  execFileSync(process.execPath, [
@@ -18,6 +18,7 @@ function scaffold(persistence) {
18
18
  target,
19
19
  '--persistence',
20
20
  persistence,
21
+ ...extraArgs,
21
22
  ], { cwd: root, stdio: 'pipe' });
22
23
  return { temp, target };
23
24
  }
@@ -25,46 +26,51 @@ function scaffold(persistence) {
25
26
  test('CMS editor scaffold is self-contained and records SQLite authority', () => {
26
27
  const { temp, target } = scaffold('sqlite');
27
28
  try {
28
- assert.equal(fs.existsSync(path.join(target, 'bin/agentsam-cms.mjs')), true);
29
29
  assert.equal(fs.existsSync(path.join(target, 'agentsam.app.json')), true);
30
- assert.equal(fs.existsSync(path.join(target, 'packages/agentsam-contracts/package.json')), true);
31
- assert.equal(fs.existsSync(path.join(target, 'packages/agentsam-workbench/package.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);
32
34
 
33
- const rootPkg = JSON.parse(fs.readFileSync(path.join(target, 'package.json'), 'utf8'));
34
- assert.ok(rootPkg.workspaces.includes('packages/*'));
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');
35
41
 
36
- const frontendPkg = JSON.parse(fs.readFileSync(path.join(target, 'frontend/package.json'), 'utf8'));
37
- assert.equal(frontendPkg.dependencies['@inneranimalmedia/agentsam-contracts'], '0.1.0');
38
- assert.equal(frontendPkg.dependencies['@inneranimalmedia/agentsam-workbench'], '0.1.0');
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');
39
46
 
40
- const sharedPkg = JSON.parse(fs.readFileSync(path.join(target, 'shared/cms/package.json'), 'utf8'));
41
- assert.equal(sharedPkg.dependencies['@inneranimalmedia/agentsam-contracts'], '0.1.0');
42
-
43
- const escaped = [
44
- ...Object.values(frontendPkg.dependencies || {}),
45
- ...Object.values(sharedPkg.dependencies || {}),
46
- ].filter((value) => String(value).startsWith('file:'));
47
- assert.deepEqual(escaped, []);
48
-
49
- const runtime = JSON.parse(fs.readFileSync(path.join(target, '.agentsam/cms-runtime.json'), 'utf8'));
50
- assert.equal(runtime.schema, 'agentsam.cms.runtime.v1');
51
- assert.equal(runtime.app_id, 'client-cms-editor');
52
- assert.equal(runtime.authority, 'sqlite');
53
- assert.equal(runtime.cache, 'localStorage');
54
- assert.equal(runtime.cache_only, false);
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);
55
50
  } finally {
56
51
  fs.rmSync(temp, { recursive: true, force: true });
57
52
  }
58
53
  });
59
54
 
60
- test('CMS editor localStorage option is explicitly cache-only', () => {
61
- const { temp, target } = scaffold('localStorage');
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');
62
58
  try {
63
- const runtime = JSON.parse(fs.readFileSync(path.join(target, '.agentsam/cms-runtime.json'), 'utf8'));
64
- assert.equal(runtime.authority, null);
65
- assert.equal(runtime.cache, 'localStorage');
66
- assert.equal(runtime.cache_only, true);
67
- assert.match(runtime.note, /cache only/i);
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);
68
74
  } finally {
69
75
  fs.rmSync(temp, { recursive: true, force: true });
70
76
  }
@@ -88,30 +88,41 @@ test('CMS D1 queries all enforce project-scoped tenancy without cross-tenant lea
88
88
  }
89
89
  });
90
90
 
91
- test('Local Studio package.json explicitly declares client-cms-editor dependencies', () => {
91
+ test('Local Studio declares portable registry versions for client-cms-editor dependencies', () => {
92
92
  const pkgPath = at('apps', 'local-studio', 'frontend', 'package.json');
93
93
  const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
94
-
95
- assert.ok(pkg.dependencies['@inneranimalmedia/agentsam-cms-frontend'], 'missing @inneranimalmedia/agentsam-cms-frontend');
96
- assert.ok(pkg.dependencies['@inneranimalmedia/agentsam-cms-backend'], 'missing @inneranimalmedia/agentsam-cms-backend');
97
- assert.ok(pkg.dependencies['@inneranimalmedia/agentsam-cms-shared'], 'missing @inneranimalmedia/agentsam-cms-shared');
98
-
99
- assert.equal(pkg.dependencies['@inneranimalmedia/agentsam-cms-frontend'], 'file:../../client-cms-editor/frontend');
100
- assert.equal(pkg.dependencies['@inneranimalmedia/agentsam-cms-backend'], 'file:../../client-cms-editor/backend');
101
- assert.equal(pkg.dependencies['@inneranimalmedia/agentsam-cms-shared'], 'file:../../client-cms-editor/shared/cms');
94
+ const rootPkg = JSON.parse(fs.readFileSync(at('package.json'), 'utf8'));
95
+
96
+ for (const name of [
97
+ '@inneranimalmedia/agentsam-cms-frontend',
98
+ '@inneranimalmedia/agentsam-cms-backend',
99
+ '@inneranimalmedia/agentsam-cms-shared',
100
+ ]) {
101
+ const declared = pkg.dependencies[name];
102
+ assert.ok(declared, 'missing ' + name);
103
+ assert.equal(declared, rootPkg.version, name + ' must track the lockstep SDK release');
104
+ assert.doesNotMatch(declared, /^(?:file:|link:|workspace:)/, name + ' must install from the registry');
105
+ }
102
106
  });
103
107
 
104
108
  test('Local Studio mounts CMS route with default site agentsam-sdk', () => {
105
- assert.ok(fs.existsSync(at('apps', 'local-studio', 'frontend', 'src', 'routes', '_app', 'cms.tsx')));
106
- const routeContent = read('apps', 'local-studio', 'frontend', 'src', 'routes', '_app', 'cms.tsx');
107
-
108
- // Must default to agentsam-sdk
109
- assert.match(routeContent, /"agentsam-sdk"/);
109
+ const liveRoute = at('apps', 'local-studio', 'frontend', 'src', 'routes', '(apps)', 'cms.tsx');
110
+ assert.ok(fs.existsSync(liveRoute), 'live CMS route must be routes/(apps)/cms.tsx');
111
+ const routeContent = read('apps', 'local-studio', 'frontend', 'src', 'routes', '(apps)', 'cms.tsx');
112
+
113
+ // Superseded donor must stay inert — do not revive obsolete _app/cms.tsx contracts.
114
+ const donor = read('apps', 'local-studio', 'frontend', 'src', 'routes', '_app', 'cms.tsx');
115
+ assert.match(donor, /SUPERSEDED/);
116
+ assert.doesNotMatch(donor, /from ["']@inneranimalmedia\/agentsam-cms-frontend["']/);
117
+ assert.doesNotMatch(donor, /createFileRoute\(/);
118
+ assert.match(donor, /export\s*\{\s*\}\s*;/);
119
+
120
+ // Live route defaults to agentsam-sdk and uses HttpCmsAdapter + site catalog.
121
+ assert.match(routeContent, /createHttpCmsAdapter/);
122
+ assert.match(routeContent, /slug:\s*"agentsam-sdk"/);
123
+ assert.match(routeContent, /search\.site \|\| search\.project_slug \|\| search\.project \|\| "agentsam-sdk"/);
110
124
  assert.doesNotMatch(routeContent, /default\s*:\s*["']inneranimalmedia["']/);
111
125
 
112
- // Must use same-origin relative basePath
113
- assert.match(routeContent, /basePath="\/cms"/);
114
-
115
126
  // NavRail must include CMS entry
116
127
  const navRail = read('apps', 'local-studio', 'frontend', 'src', 'components', 'shell', 'nav-rail.tsx');
117
128
  assert.match(navRail, /to:\s*"\/cms"/);
@@ -150,6 +150,47 @@ describe('codebaseindex real execution', () => {
150
150
  );
151
151
  assert.ok(result.search_smoke.sources_included >= 1);
152
152
  });
153
+ it('executes a declared Vectorize lane through the Worker binding before publish', async () => {
154
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'agentsam-codebaseindex-vectorize-'));
155
+ fs.mkdirSync(path.join(root, 'src'), { recursive: true });
156
+ fs.writeFileSync(path.join(root, 'src', 'demo.js'), 'export const vectorized = true;\n');
157
+ fs.writeFileSync(path.join(root, 'wrangler.toml'), [
158
+ 'name = \"customer-worker\"',
159
+ '[[vectorize]]',
160
+ 'binding = \"MY_VECTORS\"',
161
+ 'index_name = \"customer-code-index\"',
162
+ '',
163
+ ].join('\n'));
164
+ const upserts = [];
165
+ const workerBinding = {
166
+ async upsert(records) { upserts.push(records); return { mutationId: 'fixture' }; },
167
+ async query() { return { matches: [] }; },
168
+ async getByIds(ids) { return ids.map(id => ({ id })); },
169
+ async deleteByIds() { return { mutationId: 'fixture-delete' }; },
170
+ };
171
+
172
+ const result = await runCodebaseindexIngest({
173
+ root,
174
+ include: ['src'],
175
+ exclude: [],
176
+ embeddingChoice: 'fixture|deterministic|3',
177
+ embed: true,
178
+ vectors: 'vectorize',
179
+ workerBinding,
180
+ planOnly: false,
181
+ });
182
+
183
+ assert.equal(result.index.published, true);
184
+ assert.equal(result.index.vector_upsert?.transport, 'worker_binding');
185
+ assert.equal(result.storage_lanes.vectors, 'vectorize');
186
+ assert.equal(upserts.length, 1);
187
+ assert.ok(upserts[0].length >= 1);
188
+ assert.equal(upserts[0][0].values.length, 3);
189
+ const config = JSON.parse(fs.readFileSync(path.join(root, '.agentsam', 'knowledge.json'), 'utf8'));
190
+ assert.equal(config.lane.backend, 'cloudflare_vectorize');
191
+ assert.equal(config.lane.binding, 'MY_VECTORS');
192
+ assert.equal(config.lane.index, 'customer-code-index');
193
+ });
153
194
  });
154
195
 
155
196
  describe('catalog-driven help', () => {
@@ -0,0 +1,49 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+ import { readFileSync } from "node:fs";
4
+ import { fileURLToPath } from "node:url";
5
+ import path from "node:path";
6
+
7
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
8
+
9
+ test("listSources prefers oauth catalog and annotates deployment bindings", () => {
10
+ const src = readFileSync(
11
+ path.join(root, "apps/local-studio/backend/worker/database-service.js"),
12
+ "utf8",
13
+ );
14
+ assert.match(src, /source_kind: 'oauth_resource'/);
15
+ assert.match(src, /source_kind: 'deployment_binding'/);
16
+ assert.match(src, /owner_scope: 'deployment'/);
17
+ assert.match(src, /\.\.\.oauthD1,\s*\n\s*\.\.\.deploymentSources/s);
18
+ assert.match(src, /isOpaqueBindingDatabaseId/);
19
+ assert.match(src, /Never treat env\.DB as a generic user's Cloudflare catalog/);
20
+ });
21
+
22
+ test("local sqlite bridge hard-fails on hosted Worker runtime", () => {
23
+ const src = readFileSync(
24
+ path.join(root, "apps/local-studio/frontend/src/routes/api/database.local.bridge.ts"),
25
+ "utf8",
26
+ );
27
+ assert.match(src, /requires_local_runtime/);
28
+ assert.match(src, /isHostedWorkerRuntime/);
29
+ assert.match(src, /WebSocketPair/);
30
+ assert.match(src, /status: 501/);
31
+ });
32
+
33
+ test("database editor preserves null metrics and uses host font tokens", () => {
34
+ const app = readFileSync(
35
+ path.join(root, "packages/agentsam-database-editor/src/ui/DatabaseEditorApp.tsx"),
36
+ "utf8",
37
+ );
38
+ const css = readFileSync(
39
+ path.join(root, "packages/agentsam-database-editor/src/ui/database-editor.css"),
40
+ "utf8",
41
+ );
42
+ assert.doesNotMatch(app, /Number\(point\.queries \|\| 0\)/);
43
+ assert.match(app, /numOrNull/);
44
+ assert.match(app, /data-metrics-wired/);
45
+ assert.match(css, /var\(--font-sans/);
46
+ assert.match(css, /var\(--font-mono/);
47
+ assert.match(css, /data-provider="cloudflare"/);
48
+ assert.match(css, /data-provider="supabase"/);
49
+ });
@@ -0,0 +1,45 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { readFileSync } from 'node:fs';
4
+
5
+ const main = readFileSync(new URL('../../packages/agentsam-desktop-shell/src-tauri/src/main.rs', import.meta.url), 'utf8');
6
+ const keychain = readFileSync(new URL('../../packages/agentsam-desktop-shell/src-tauri/src/commands/keychain.rs', import.meta.url), 'utf8');
7
+ const tauriClient = readFileSync(new URL('../../apps/local-studio/frontend/src/lib/desktop/tauri.ts', import.meta.url), 'utf8');
8
+ const identityBridge = readFileSync(new URL('../../packages/identity/src/frontend/auth-portal/shared/desktop-identity-bridge.js', import.meta.url), 'utf8');
9
+ const localIdentity = readFileSync(new URL('../../packages/agentsam-desktop-shell/src-tauri/src/commands/local_identity.rs', import.meta.url), 'utf8');
10
+ const googleIdentity = readFileSync(new URL('../../packages/agentsam-desktop-shell/src-tauri/src/commands/google_desktop_identity.rs', import.meta.url), 'utf8');
11
+
12
+ test('desktop webview cannot invoke a generic secure-store read', () => {
13
+ for (const forbidden of [
14
+ 'keychain::get_token',
15
+ 'keychain::secure_store_get',
16
+ '"secure_store_get"',
17
+ ]) {
18
+ assert.equal(main.includes(forbidden), false, `main.rs must not register ${forbidden}`);
19
+ assert.equal(tauriClient.includes(forbidden), false, `frontend must not invoke ${forbidden}`);
20
+ assert.equal(identityBridge.includes(forbidden), false, `desktop identity bridge must not invoke ${forbidden}`);
21
+ }
22
+ });
23
+
24
+ test('provider key command surface never exposes get', () => {
25
+ assert.match(main, /keychain::provider_key_exists/);
26
+ assert.match(main, /keychain::provider_key_set/);
27
+ assert.match(main, /keychain::provider_key_delete/);
28
+ assert.doesNotMatch(main, /keychain::provider_key_get/);
29
+ assert.match(keychain, /pub\(crate\) fn provider_key_get_internal/);
30
+ assert.doesNotMatch(keychain, /#\[tauri::command\]\s*\npub\(crate\) fn provider_key_get_internal/);
31
+ });
32
+
33
+ test('keychain app namespace is derived natively', () => {
34
+ assert.match(keychain, /const KEYCHAIN_APP_ID: &str = "local-studio"/);
35
+ assert.doesNotMatch(keychain, /pub fn .*\(app_id:/);
36
+ });
37
+
38
+ test('desktop bearer sessions stay behind Rust', () => {
39
+ assert.doesNotMatch(tauriClient, /identity_store_get|identity_store_set|identity_store_delete/);
40
+ assert.doesNotMatch(identityBridge, /identity_store_get|identity_store_set|identity_store_delete/);
41
+ assert.match(localIdentity, /identity_session_get_internal/);
42
+ assert.match(localIdentity, /identity_session_set_internal/);
43
+ assert.match(googleIdentity, /#\[serde\(skip_serializing\)\]\s*pub session_id/);
44
+ assert.match(googleIdentity, /identity_session_set_internal/);
45
+ });
@@ -0,0 +1,47 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+ import { readFileSync } from "node:fs";
4
+ import { fileURLToPath } from "node:url";
5
+ import { dirname, join } from "node:path";
6
+
7
+ const root = join(dirname(fileURLToPath(import.meta.url)), "../..");
8
+
9
+ test("LocalStudioWorkPage defaults to HTTP WorkHost, not populated fixture", () => {
10
+ const source = readFileSync(
11
+ join(root, "apps/local-studio/frontend/src/components/work/LocalStudioWorkPage.tsx"),
12
+ "utf8",
13
+ );
14
+ assert.match(source, /createHttpWorkHost/);
15
+ assert.match(source, /resolveWorkHostMode/);
16
+ assert.match(source, /VITE_WORK_FIXTURE/);
17
+ // Fixture must be opt-in only
18
+ assert.match(source, /fixture === "populated"/);
19
+ assert.doesNotMatch(
20
+ source,
21
+ /createFixtureWorkHost\(populatedWorkFixture\)\s*,\s*\[\s*\]/,
22
+ );
23
+ });
24
+
25
+ test("agentsam-work theme does not hardcode Inter", () => {
26
+ const css = readFileSync(
27
+ join(root, "packages/agentsam-work/src/frontend/theme.css"),
28
+ "utf8",
29
+ );
30
+ assert.doesNotMatch(css, /font-family:\s*Inter/);
31
+ assert.match(css, /--font-sans/);
32
+ });
33
+
34
+ test("worker mounts /api/work/snapshot", () => {
35
+ const index = readFileSync(
36
+ join(root, "apps/local-studio/backend/worker/index.js"),
37
+ "utf8",
38
+ );
39
+ const service = readFileSync(
40
+ join(root, "apps/local-studio/backend/worker/work-service.js"),
41
+ "utf8",
42
+ );
43
+ assert.match(index, /handleWorkRequest/);
44
+ assert.match(service, /\/api\/work\/snapshot/);
45
+ assert.match(service, /fixtureName: 'live'/);
46
+ assert.doesNotMatch(service, /Companions of CPAS|AgentSamRemix|runtime-receipts\.md/);
47
+ });
@@ -0,0 +1,59 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+
4
+ import { discoverOpenAIModels, discoverGeminiModels, discoverCursorModels } from '../../src/models/discovery.js';
5
+ import { sanitizeInventoryForClient } from '../../src/models/inventory-core.js';
6
+
7
+ function json(body) {
8
+ return new Response(JSON.stringify(body), { status: 200, headers: { 'content-type': 'application/json' } });
9
+ }
10
+
11
+ function sanitized(models) {
12
+ return sanitizeInventoryForClient({
13
+ providers: [],
14
+ discovery: {},
15
+ availableModels: models,
16
+ }).availableModels;
17
+ }
18
+
19
+ test('known OpenAI Responses reference is selectable while unknown live models stay visible', async () => {
20
+ const result = await discoverOpenAIModels('user-key', async () => json({
21
+ data: [{ id: 'gpt-5.6-sol' }, { id: 'brand-new-unclassified-model' }],
22
+ }));
23
+ const rows = sanitized(result.models);
24
+ assert.equal(rows.length, 2);
25
+ assert.equal(rows.find((row) => row.model_id === 'gpt-5.6-sol')?.chat_eligible, true);
26
+ const unknown = rows.find((row) => row.model_id === 'brand-new-unclassified-model');
27
+ assert.equal(unknown?.chat_eligible, false);
28
+ assert.equal(unknown?.eligibility_reason, 'capability_unknown');
29
+ });
30
+
31
+ test('Cursor inventory is preserved but reports adapter unavailability', async () => {
32
+ const result = await discoverCursorModels('cursor-key', async () => json({
33
+ items: [{ id: 'gpt-5.6-sol', displayName: 'GPT-5.6 Sol', parameters: [] }],
34
+ }));
35
+ const [row] = sanitized(result.models);
36
+ assert.equal(row.provider, 'cursor');
37
+ assert.equal(row.model_id, 'gpt-5.6-sol');
38
+ assert.equal(row.chat_eligible, false);
39
+ assert.equal(row.eligibility_reason, 'provider_adapter_unavailable');
40
+ });
41
+
42
+ test('Gemini provider description keeps TTS visible outside the chat picker', async () => {
43
+ const result = await discoverGeminiModels('gemini-key', async () => json({
44
+ models: [{
45
+ name: 'models/gemini-tts-fixture',
46
+ baseModelId: 'gemini-tts-fixture',
47
+ displayName: 'Voice fixture',
48
+ description: 'Preview Text-to-Speech model',
49
+ supportedGenerationMethods: ['generateContent'],
50
+ inputTokenLimit: 8192,
51
+ outputTokenLimit: 8192,
52
+ }],
53
+ }));
54
+ const [row] = sanitized(result.models);
55
+ assert.equal(row.model_id, 'gemini-tts-fixture');
56
+ assert.equal(row.chat_eligible, false);
57
+ assert.equal(row.eligibility_reason, 'specialized_output_model');
58
+ assert.equal(row.eligibility_source, 'provider_api');
59
+ });