@inneranimalmedia/agentsam-sdk 2.6.4 → 2.6.5

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 (418) hide show
  1. package/AGENTSAM.md +11 -0
  2. package/README.md +15 -9
  3. package/apps/client-cms-editor/AGENTS.md +12 -0
  4. package/apps/client-cms-editor/IMPORT_PROVENANCE.json +8 -0
  5. package/apps/client-cms-editor/README.md +72 -0
  6. package/apps/client-cms-editor/agentsam.app.json +57 -0
  7. package/apps/client-cms-editor/backend/README.md +5 -0
  8. package/apps/client-cms-editor/backend/package.json +22 -0
  9. package/apps/client-cms-editor/backend/src/api/client.ts +200 -0
  10. package/apps/client-cms-editor/backend/src/demo-bootstrap.ts +145 -0
  11. package/apps/client-cms-editor/backend/src/index.ts +6 -0
  12. package/apps/client-cms-editor/backend/src/model.ts +115 -0
  13. package/apps/client-cms-editor/backend/src/preview/bridge.ts +79 -0
  14. package/apps/client-cms-editor/backend/src/preview/urls.ts +55 -0
  15. package/apps/client-cms-editor/backend/src/routing/cms-route.js +293 -0
  16. package/apps/client-cms-editor/backend/src/routing/index.js +10 -0
  17. package/apps/client-cms-editor/backend/src/storefront.ts +52 -0
  18. package/apps/client-cms-editor/backend/tsconfig.json +15 -0
  19. package/apps/client-cms-editor/backend/worker/index.js +34 -0
  20. package/apps/client-cms-editor/backend/wrangler.jsonc +11 -0
  21. package/apps/client-cms-editor/bin/agentsam-cms.mjs +229 -0
  22. package/apps/client-cms-editor/frontend/index.html +12 -0
  23. package/apps/client-cms-editor/frontend/package.json +33 -0
  24. package/apps/client-cms-editor/frontend/src/AgentSamDrawer.tsx +188 -0
  25. package/apps/client-cms-editor/frontend/src/CmsAgentSurface.tsx +191 -0
  26. package/apps/client-cms-editor/frontend/src/CmsEditor.tsx +1345 -0
  27. package/apps/client-cms-editor/frontend/src/env.d.ts +14 -0
  28. package/apps/client-cms-editor/frontend/src/index.ts +8 -0
  29. package/apps/client-cms-editor/frontend/src/lib/content-safety.ts +63 -0
  30. package/apps/client-cms-editor/frontend/src/main.tsx +17 -0
  31. package/apps/client-cms-editor/frontend/src/mount.tsx +51 -0
  32. package/apps/client-cms-editor/frontend/src/styles/agentsam-drawer.css +214 -0
  33. package/apps/client-cms-editor/frontend/src/styles/cmsShell.css +1739 -0
  34. package/apps/client-cms-editor/frontend/src/styles/studio.css +106 -0
  35. package/apps/client-cms-editor/frontend/src/surfaces/CmsDashboard.tsx +313 -0
  36. package/apps/client-cms-editor/frontend/src/surfaces/CmsGuidedChatHero.tsx +121 -0
  37. package/apps/client-cms-editor/frontend/src/surfaces/CmsHubPage.tsx +132 -0
  38. package/apps/client-cms-editor/frontend/src/surfaces/CmsSiteSwitcher.tsx +176 -0
  39. package/apps/client-cms-editor/frontend/src/surfaces/index.ts +5 -0
  40. package/apps/client-cms-editor/frontend/src/surfaces/types.ts +48 -0
  41. package/apps/client-cms-editor/frontend/tsconfig.json +25 -0
  42. package/apps/client-cms-editor/frontend/vite.config.ts +13 -0
  43. package/apps/client-cms-editor/package-lock.json +3832 -0
  44. package/apps/client-cms-editor/package.json +23 -0
  45. package/apps/client-cms-editor/reference/DONOR_README.md +52 -0
  46. package/apps/client-cms-editor/reference/DONOR_package-lock.json +1253 -0
  47. package/apps/client-cms-editor/reference/DONOR_tsconfig.json +15 -0
  48. package/apps/client-cms-editor/shared/cms/package.json +21 -0
  49. package/apps/client-cms-editor/shared/cms/src/agent-context.ts +35 -0
  50. package/apps/client-cms-editor/shared/cms/src/cloudflare-bindings.ts +51 -0
  51. package/apps/client-cms-editor/shared/cms/src/editor-types.ts +58 -0
  52. package/apps/client-cms-editor/shared/cms/src/index.ts +5 -0
  53. package/apps/client-cms-editor/shared/cms/src/publication.ts +24 -0
  54. package/apps/client-cms-editor/shared/cms/src/routes.ts +11 -0
  55. package/apps/client-cms-editor/shared/cms/tsconfig.json +12 -0
  56. package/bin/agentsam-rapid-rust +36 -0
  57. package/docs/AUTH_IDENTITY_CONTRACT.md +2 -0
  58. package/docs/MACHINE_INTELLIGENCE.md +120 -0
  59. package/docs/WINDOWS_RUNTIME_INSTALL.md +30 -0
  60. package/docs/architecture/AGENTSAM_APPLICATION_CONTRACT.md +188 -0
  61. package/docs/architecture/AGENTSAM_RUNTIME_PROTOCOL.md +151 -0
  62. package/docs/architecture/LOCAL_STUDIO_CLOUDFLARE_OAUTH.md +12 -4
  63. package/docs/architecture/R2_SLUG_NAMESPACE.md +20 -0
  64. package/docs/architecture/WORK_PRODUCT_EXTRACTION.md +97 -0
  65. package/docs/brand/AGENT_SAM_ICON_GRAMMAR.md +70 -0
  66. package/docs/content-studio/HOST_MOUNT_CHECKLIST.md +71 -0
  67. package/docs/content-studio/REVISION_GATE_2026-09-27.md +501 -0
  68. package/docs/contracts/capability-install-planner.md +67 -0
  69. package/docs/contracts/environment-vocabulary.md +195 -0
  70. package/docs/contracts/google-cloud-oauth-setup.md +199 -0
  71. package/docs/local-studio/WORKMODE_DONOR_NOTES.md +1 -1
  72. package/docs/plans/LOCAL-STUDIO-GRADUATION-2026-09-26.md +290 -0
  73. package/docs/plans/LOCAL-STUDIO-REAL-APP-CONTRACT-ADDENDUM-2026-09-27.md +394 -0
  74. package/docs/plans/MACHINE-FIRST-APPS-TUI-2026-09-24.md +227 -0
  75. package/docs/plans/TOMORROW-EXTENSIVE-TODO-2026-09-26.md +221 -0
  76. package/docs/plans/TOMORROW-MACHINE-FIRST-BRIEFING.md +145 -0
  77. package/docs/plans/UNIVERSAL-INGEST-MACHINE-FIRST-2026-09-24.md +215 -0
  78. package/docs/plugins.md +2 -2
  79. package/docs/product/AGENTSAM_PRODUCT_EXPERIENCE_STANDARD.md +280 -0
  80. package/docs/product/LOCAL_STUDIO_DESKTOP_EXPERIENCE.md +139 -0
  81. package/docs/product/README.md +8 -0
  82. package/docs/rapid-rust-wasm.md +35 -0
  83. package/migrations/d1/0016_cloudflare_oauth_user_oauth_tokens_ssot.sql +14 -0
  84. package/package.json +73 -14
  85. package/packages/agentsam-brand/README.md +106 -11
  86. package/packages/agentsam-brand/bin/agentsam-brand.mjs +9 -0
  87. package/packages/agentsam-brand/package.json +39 -7
  88. package/packages/agentsam-brand/src/adapters/cloudflare-images.js +453 -0
  89. package/packages/agentsam-brand/src/adapters/cloudflare-r2.js +74 -0
  90. package/packages/agentsam-brand/src/adapters/d1-registry.js +26 -0
  91. package/packages/agentsam-brand/src/adapters/filesystem.js +59 -0
  92. package/packages/agentsam-brand/src/adapters/memory.js +31 -0
  93. package/packages/agentsam-brand/src/cli/controller.js +503 -0
  94. package/packages/agentsam-brand/src/cli/wizard.js +526 -0
  95. package/packages/agentsam-brand/src/core/capabilities.js +201 -0
  96. package/packages/agentsam-brand/src/core/derivatives.js +211 -0
  97. package/packages/agentsam-brand/src/core/errors.js +12 -0
  98. package/packages/agentsam-brand/src/core/ingest.js +195 -0
  99. package/packages/agentsam-brand/src/core/inspect.js +109 -0
  100. package/packages/agentsam-brand/src/core/keys.js +83 -0
  101. package/packages/agentsam-brand/src/core/naming.js +142 -0
  102. package/packages/agentsam-brand/src/core/optimize.js +316 -0
  103. package/packages/agentsam-brand/src/core/pack.js +305 -0
  104. package/packages/agentsam-brand/src/core/plan.js +276 -0
  105. package/packages/agentsam-brand/src/core/preview.js +159 -0
  106. package/packages/agentsam-brand/src/core/processors/cloudflare.js +68 -0
  107. package/packages/agentsam-brand/src/core/processors/contract.js +203 -0
  108. package/packages/agentsam-brand/src/core/processors/index.js +148 -0
  109. package/packages/agentsam-brand/src/core/processors/native.js +82 -0
  110. package/packages/agentsam-brand/src/core/processors/sharp.js +113 -0
  111. package/packages/agentsam-brand/src/core/processors/squoosh-binary.js +195 -0
  112. package/packages/agentsam-brand/src/core/promote.js +288 -0
  113. package/packages/agentsam-brand/src/core/receipts.js +155 -0
  114. package/packages/agentsam-brand/src/core/v2/compile.js +280 -0
  115. package/packages/agentsam-brand/src/core/v2/derivatives-semantic.js +207 -0
  116. package/packages/agentsam-brand/src/core/v2/ingest-graph.js +387 -0
  117. package/packages/agentsam-brand/src/core/v2/roles.js +180 -0
  118. package/packages/agentsam-brand/src/core/v2/schema.js +209 -0
  119. package/packages/agentsam-brand/src/core/v2/templates.js +114 -0
  120. package/packages/agentsam-brand/src/index.js +193 -36
  121. package/packages/agentsam-brand/src/presets/app-icon.json +16 -0
  122. package/packages/agentsam-brand/src/presets/favicon.json +17 -0
  123. package/packages/agentsam-brand/src/presets/hero.json +12 -0
  124. package/packages/agentsam-brand/src/presets/index.js +40 -0
  125. package/packages/agentsam-brand/src/presets/logo.json +12 -0
  126. package/packages/agentsam-brand/src/presets/model.json +8 -0
  127. package/packages/agentsam-brand/src/presets/og-image.json +10 -0
  128. package/packages/agentsam-brand/src/presets/product-shot.json +11 -0
  129. package/packages/agentsam-brand/src/presets/social-image.json +10 -0
  130. package/packages/agentsam-brand/src/presets/web-image.json +10 -0
  131. package/packages/agentsam-contracts/src/artifacts.ts +41 -0
  132. package/packages/agentsam-knowledge/src/autorag/index.js +1 -1
  133. package/packages/agentsam-knowledge/src/providers/index.js +6 -4
  134. package/packages/agentsam-knowledge/src/providers/ollama-endpoint.js +31 -0
  135. package/packages/agentsam-knowledge/test/autorag.test.mjs +22 -1
  136. package/packages/agentsam-nav/package.json +2 -2
  137. package/packages/agentsam-rapid-rust/Cargo.lock +344 -0
  138. package/packages/agentsam-rapid-rust/Cargo.toml +18 -0
  139. package/packages/agentsam-rapid-rust/README.md +5 -0
  140. package/packages/agentsam-rapid-rust/src/main.rs +718 -0
  141. package/packages/agentsam-rapid-rust/templates/api/Cargo.toml.tmpl +18 -0
  142. package/packages/agentsam-rapid-rust/templates/api/src/lib.rs.tmpl +17 -0
  143. package/packages/agentsam-rapid-rust/templates/common/README.md.tmpl +22 -0
  144. package/packages/agentsam-rapid-rust/templates/common/package.json.tmpl +12 -0
  145. package/packages/agentsam-rapid-rust/templates/common/wrangler.toml.tmpl +6 -0
  146. package/packages/agentsam-rapid-rust/templates/crypto-auth/Cargo.toml.tmpl +21 -0
  147. package/packages/agentsam-rapid-rust/templates/crypto-auth/src/lib.rs.tmpl +32 -0
  148. package/packages/agentsam-rapid-rust/templates/data-processor/Cargo.toml.tmpl +18 -0
  149. package/packages/agentsam-rapid-rust/templates/data-processor/src/lib.rs.tmpl +41 -0
  150. package/packages/agentsam-rapid-rust/templates/shared-core/Cargo.toml.tmpl +9 -0
  151. package/packages/agentsam-rapid-rust/templates/shared-core/core/Cargo.toml.tmpl +7 -0
  152. package/packages/agentsam-rapid-rust/templates/shared-core/core/src/lib.rs.tmpl +23 -0
  153. package/packages/agentsam-rapid-rust/templates/shared-core/worker/Cargo.toml.tmpl +12 -0
  154. package/packages/agentsam-rapid-rust/templates/shared-core/worker/src/lib.rs.tmpl +16 -0
  155. package/packages/agentsam-rapid-rust/templates/shared-core/wrangler.toml.tmpl +6 -0
  156. package/packages/agentsam-repository/src/index.js +1 -0
  157. package/packages/agentsam-repository/src/merkle/semantic.js +3 -10
  158. package/packages/agentsam-repository/src/source-types.js +85 -0
  159. package/packages/agentsam-vault/README.md +96 -0
  160. package/packages/agentsam-vault/package.json +32 -0
  161. package/packages/agentsam-vault/src/contracts/credential.d.ts +78 -0
  162. package/packages/agentsam-vault/src/contracts/credential.js +132 -0
  163. package/packages/agentsam-vault/src/crypto/aes-gcm.d.ts +30 -0
  164. package/packages/agentsam-vault/src/crypto/aes-gcm.js +107 -0
  165. package/packages/agentsam-vault/src/crypto/oauth-envelope.js +150 -0
  166. package/packages/agentsam-vault/src/index.d.ts +9 -0
  167. package/packages/agentsam-vault/src/index.js +27 -0
  168. package/packages/agentsam-vault/src/providers/registry.js +90 -0
  169. package/packages/agentsam-vault/src/runtime/resolver.js +77 -0
  170. package/packages/agentsam-workbench/README.md +24 -0
  171. package/packages/agentsam-workbench/package.json +38 -0
  172. package/packages/agentsam-workbench/src/agent/AgentPanel.tsx +41 -0
  173. package/packages/agentsam-workbench/src/agent/ArtifactCard.tsx +9 -0
  174. package/packages/agentsam-workbench/src/agent/Composer.tsx +102 -0
  175. package/packages/agentsam-workbench/src/agent/ConnectedAgentPanel.tsx +194 -0
  176. package/packages/agentsam-workbench/src/agent/ContextualComposer.tsx +788 -0
  177. package/packages/agentsam-workbench/src/agent/GoalStatusStrip.tsx +38 -0
  178. package/packages/agentsam-workbench/src/agent/MiniAgentSam.tsx +86 -0
  179. package/packages/agentsam-workbench/src/agent/ModelSelect.tsx +19 -0
  180. package/packages/agentsam-workbench/src/agent/Thread.tsx +56 -0
  181. package/packages/agentsam-workbench/src/agent/ToolReceipt.tsx +11 -0
  182. package/packages/agentsam-workbench/src/agent/contextual-composer.css +611 -0
  183. package/packages/agentsam-workbench/src/agent/index.ts +10 -0
  184. package/packages/agentsam-workbench/src/agent/mini-agentsam.css +12 -0
  185. package/packages/agentsam-workbench/src/browser/BrowserFrame.tsx +37 -0
  186. package/packages/agentsam-workbench/src/browser/index.ts +1 -0
  187. package/packages/agentsam-workbench/src/index.ts +6 -0
  188. package/packages/agentsam-workbench/src/project-control.css +160 -0
  189. package/packages/agentsam-workbench/src/projects/ProjectsSurface.tsx +131 -0
  190. package/packages/agentsam-workbench/src/projects/index.ts +1 -0
  191. package/packages/agentsam-workbench/src/shell/Breadcrumb.tsx +35 -0
  192. package/packages/agentsam-workbench/src/shell/ResizableStage.tsx +99 -0
  193. package/packages/agentsam-workbench/src/shell/SidePanel.tsx +5 -0
  194. package/packages/agentsam-workbench/src/shell/index.ts +4 -0
  195. package/packages/agentsam-workbench/src/shell/surfaceRegistry.ts +29 -0
  196. package/packages/agentsam-workbench/src/terminal/TerminalSurface.tsx +5 -0
  197. package/packages/agentsam-workbench/src/terminal/index.ts +1 -0
  198. package/packages/agentsam-workbench/src/timeline/GanttBoard.tsx +258 -0
  199. package/packages/agentsam-workbench/src/timeline/index.ts +1 -0
  200. package/packages/agentsam-workbench/tsconfig.json +13 -0
  201. package/packages/connectors/cloudflare/OAUTH_STORAGE_AUDIT.md +53 -0
  202. package/packages/connectors/cloudflare/package.json +3 -1
  203. package/packages/connectors/cloudflare/src/api-client.js +279 -0
  204. package/packages/connectors/cloudflare/src/capabilities.js +585 -0
  205. package/packages/connectors/cloudflare/src/credential.js +318 -0
  206. package/packages/connectors/cloudflare/src/families/brand-protection.js +123 -0
  207. package/packages/connectors/cloudflare/src/families/keyless.js +114 -0
  208. package/packages/connectors/cloudflare/src/families/pages.js +151 -0
  209. package/packages/connectors/cloudflare/src/families/scanner.js +123 -0
  210. package/packages/connectors/cloudflare/src/families/snippets.js +207 -0
  211. package/packages/connectors/cloudflare/src/families/tag-gateway.js +46 -0
  212. package/packages/connectors/cloudflare/src/families/tags.js +124 -0
  213. package/packages/connectors/cloudflare/src/families/token-validation.js +95 -0
  214. package/packages/connectors/cloudflare/src/families/workflows.js +156 -0
  215. package/packages/connectors/cloudflare/src/index.js +102 -265
  216. package/packages/connectors/cloudflare/src/oauth-persist.js +336 -0
  217. package/packages/connectors/cloudflare/src/owner.js +42 -12
  218. package/packages/connectors/cloudflare/src/permission-options.js +1064 -0
  219. package/packages/connectors/cloudflare/src/routes.js +309 -144
  220. package/packages/connectors/cloudflare/src/scope-catalog.js +345 -0
  221. package/packages/connectors/cloudflare/src/vault.js +2 -2
  222. package/packages/connectors/cloudflare/tests/capabilities.test.mjs +276 -0
  223. package/packages/connectors/cloudflare/tests/connector.test.mjs +26 -30
  224. package/packages/connectors/cloudflare/tests/oauth-persist.test.mjs +125 -0
  225. package/packages/identity/.agentsam/features/oauth-login-portal/providers.json +22 -2
  226. package/packages/identity/.agentsam/features/oauth-login-portal/resources.json +10 -4
  227. package/packages/identity/.agentsam/features/oauth-login-portal/routes.json +20 -0
  228. package/packages/identity/README.md +1 -1
  229. package/packages/identity/backend/README.md +1 -1
  230. package/packages/identity/migrations/D1_SCHEMA_MAPPING.md +3 -2
  231. package/packages/identity/migrations/sqlite/004_identity_oauth_consent_catalog.sql +48 -0
  232. package/packages/identity/package.json +4 -3
  233. package/packages/identity/scripts/local-identity-bridge.mjs +184 -0
  234. package/packages/identity/scripts/preview-auth-portal.mjs +7 -7
  235. package/packages/identity/src/adapters/cloudflare-d1/index.js +31 -2
  236. package/packages/identity/src/adapters/sqlite/index.js +4 -1
  237. package/packages/identity/src/contracts/auth-config.js +28 -8
  238. package/packages/identity/src/contracts/external-identity.js +1 -1
  239. package/packages/identity/src/contracts/provider.js +1 -0
  240. package/packages/identity/src/frontend/auth-portal/README.md +2 -1
  241. package/packages/identity/src/frontend/auth-portal/pages/login.html +6 -5
  242. package/packages/identity/src/frontend/auth-portal/pages/reset.html +6 -5
  243. package/packages/identity/src/frontend/auth-portal/pages/signup.html +6 -5
  244. package/packages/identity/src/frontend/auth-portal/shared/company-branding.js +1 -1
  245. package/packages/identity/src/frontend/auth-portal/shared/desktop-identity-bridge.js +207 -0
  246. package/packages/identity/src/index.js +16 -0
  247. package/packages/identity/src/migrations/0001_identity_core.sql +19 -2
  248. package/packages/identity/src/migrations/0003_accounts_ssot.sql +20 -0
  249. package/packages/identity/src/migrations/README.md +5 -2
  250. package/packages/identity/src/oauth/README.md +10 -5
  251. package/packages/identity/src/oauth/consent-view.js +388 -0
  252. package/packages/identity/src/oauth/credentials.js +31 -11
  253. package/packages/identity/src/oauth/google-desktop-exchange.js +173 -0
  254. package/packages/identity/src/providers/cloudflare/oauth.js +3 -4
  255. package/packages/identity/src/providers/cloudflare/profile.js +49 -14
  256. package/packages/identity/src/providers/iam/index.js +27 -5
  257. package/packages/identity/src/server/identity-service.js +31 -2
  258. package/packages/identity/src/server/worker-router.js +111 -81
  259. package/packages/identity/tests/auth-config.test.mjs +3 -2
  260. package/packages/identity/tests/identity-init-scaffold.test.mjs +3 -0
  261. package/packages/identity/tests/identity-service.test.mjs +16 -0
  262. package/packages/identity/tests/native-session-worker.test.mjs +64 -0
  263. package/packages/identity/tests/oauth-consent-view.test.mjs +106 -0
  264. package/packages/identity/tests/oauth-credentials.test.mjs +17 -4
  265. package/packages/identity/tests/oauth-presets-accounts-ssot.test.mjs +58 -0
  266. package/packages/identity/tests/preview-auth-portal.test.mjs +3 -3
  267. package/packages/runtime-protocol/src/index.js +154 -0
  268. package/packages/theme-scenes/README.md +164 -0
  269. package/packages/theme-scenes/package.json +53 -0
  270. package/packages/theme-scenes/src/blocks/index.js +30 -0
  271. package/packages/theme-scenes/src/contracts/index.js +286 -0
  272. package/packages/theme-scenes/src/demos/index.js +65 -0
  273. package/packages/theme-scenes/src/index.js +75 -0
  274. package/packages/theme-scenes/src/presets/index.js +263 -0
  275. package/packages/theme-scenes/src/runtime/compile.js +119 -0
  276. package/packages/theme-scenes/src/scenes/index.js +146 -0
  277. package/packages/theme-scenes/src/shell/index.js +47 -0
  278. package/packages/theme-scenes/src/themes/index.js +129 -0
  279. package/packages/theme-scenes/src/visuals/index.js +41 -0
  280. package/packages/theme-scenes/test/theme-scenes.test.mjs +179 -0
  281. package/packages/work-graph/src/index.js +34 -1
  282. package/packages/work-graph/src/renderers/gantt-model.js +24 -0
  283. package/packages/work-graph/test/work-graph.test.mjs +27 -7
  284. package/protocol/README.md +15 -7
  285. package/protocol/apps/agentsam.app.v1.schema.json +89 -7
  286. package/protocol/apps/agentsam.host-install.v1.schema.json +36 -0
  287. package/protocol/assets/README.md +9 -0
  288. package/protocol/assets/asset-record.v1.schema.json +64 -0
  289. package/protocol/runtime/agentsam.runtime.v1.schema.json +75 -0
  290. package/protocol/scoring/README.md +10 -0
  291. package/protocol/scoring/scorecard.v1.schema.json +65 -0
  292. package/protocol/ui/icon-registry.mjs +1 -0
  293. package/registry/cms-rust-machine-20260928/installable-products.json +31 -0
  294. package/registry/cms-rust-machine-20260928/manifest.json +22 -0
  295. package/registry/cms-rust-machine-20260928/migration.sql +237 -0
  296. package/registry/cms-rust-machine-20260928/receipt.json +21 -0
  297. package/registry/cms-rust-machine-20260928/receipt.sql +27 -0
  298. package/scripts/build_rapid_rust_cli.py +83 -0
  299. package/src/attachments/index.js +6 -0
  300. package/src/attachments/intake.js +235 -0
  301. package/src/capabilities/repository-snapshot.js +19 -2
  302. package/src/cli/command-catalog.js +8 -0
  303. package/src/cli.js +182 -26
  304. package/src/commands/account-auth.js +94 -8
  305. package/src/commands/app.js +307 -3
  306. package/src/commands/billing.js +127 -0
  307. package/src/commands/brand.js +74 -60
  308. package/src/commands/cheat-sheet.js +154 -0
  309. package/src/commands/cloudflare-login.js +222 -0
  310. package/src/commands/cloudflare.js +453 -23
  311. package/src/commands/codebaseindex.js +6 -1
  312. package/src/commands/compute.js +4 -0
  313. package/src/commands/connections.js +11 -5
  314. package/src/commands/credentials.js +116 -0
  315. package/src/commands/gcloud-auth.js +427 -0
  316. package/src/commands/google-cloud.js +375 -0
  317. package/src/commands/identity-init.js +2 -2
  318. package/src/commands/mcp.js +226 -33
  319. package/src/commands/ollama.js +3 -2
  320. package/src/commands/plugins.js +7 -2
  321. package/src/commands/product.js +36 -0
  322. package/src/commands/runtime-status.js +28 -9
  323. package/src/commands/runtime.js +313 -0
  324. package/src/commands/rust.js +24 -0
  325. package/src/commands/setup.js +279 -0
  326. package/src/commands/shell.js +16 -3
  327. package/src/commands/start-local.js +2 -2
  328. package/src/commands/terminal.js +171 -0
  329. package/src/commands/update.js +140 -0
  330. package/src/commands/whoami.js +329 -65
  331. package/src/features/resolve.js +1 -0
  332. package/src/index.js +4 -0
  333. package/src/indexing/ingest/inventory.js +254 -19
  334. package/src/indexing/ingest/materials.js +3 -9
  335. package/src/indexing/ingest/style-evidence.js +181 -0
  336. package/src/knowledge/source.js +3 -3
  337. package/src/lib/account-session.js +11 -4
  338. package/src/lib/app-authority.js +172 -0
  339. package/src/lib/auth.js +94 -21
  340. package/src/lib/core-client.js +5 -6
  341. package/src/lib/credentials-audit.js +451 -0
  342. package/src/lib/deploy/health.js +24 -6
  343. package/src/lib/detect-context.js +7 -1
  344. package/src/lib/google-cloud-connection.js +270 -0
  345. package/src/lib/google-cloud-inventory.js +385 -0
  346. package/src/lib/google-desktop-oauth.js +372 -0
  347. package/src/lib/google-studio-brokered-oauth.js +158 -0
  348. package/src/lib/identity-scaffold.js +24 -6
  349. package/src/lib/init-options.js +192 -0
  350. package/src/lib/local-scaffold.js +48 -16
  351. package/src/lib/provider-command-remediation.js +308 -0
  352. package/src/lib/provider-credentials.js +8 -0
  353. package/src/lib/scaffold/index.js +8 -2
  354. package/src/lib/scaffold/mcp-server.js +43 -0
  355. package/src/lib/scaffold/templates/mcp-server/index.js +397 -0
  356. package/src/lib/scaffold/templates/mcp-server/presets.js +39 -0
  357. package/src/lib/scaffold/wizards/cms.js +93 -0
  358. package/src/lib/scaffold/wizards/mcp-server.js +61 -0
  359. package/src/lib/setup/contract.js +26 -0
  360. package/src/lib/setup/discover.js +116 -0
  361. package/src/lib/setup/execute.js +205 -0
  362. package/src/lib/setup/planner.js +134 -0
  363. package/src/lib/setup/recipes.js +235 -0
  364. package/src/lib/setup/runtime-persist.js +197 -0
  365. package/src/lib/setup/runtime.js +394 -0
  366. package/src/lib/slash-commands.js +2 -0
  367. package/src/lib/terminal/machine-identity.js +95 -0
  368. package/src/lib/terminal-local.js +164 -0
  369. package/src/lib/terminal-scopes.js +52 -0
  370. package/src/lib/whoami-capabilities.js +184 -0
  371. package/src/local-pty/server.js +34 -5
  372. package/src/mcp/authority.js +58 -108
  373. package/src/mcp/client-adapters.js +68 -144
  374. package/src/mcp/client.js +142 -122
  375. package/src/mcp/cloudflare-bundles.js +225 -0
  376. package/src/mcp/index.js +12 -0
  377. package/src/plugins/cloudflare.js +1 -1
  378. package/src/providers/ollama-chat.js +2 -1
  379. package/src/sam/types.js +27 -2
  380. package/src/security/inventory.js +12 -2
  381. package/src/security/local-vault.js +2 -0
  382. package/src/security/scan.js +1 -1
  383. package/test/account-session.test.mjs +3 -3
  384. package/test/app-authority-context.test.mjs +32 -0
  385. package/test/cli/codebaseindex-plan-ux.test.mjs +1 -1
  386. package/test/cli/mcp-client.test.mjs +21 -10
  387. package/test/cli/runtime-persist.test.mjs +56 -0
  388. package/test/cli/rust-command.test.mjs +21 -0
  389. package/test/credentials-audit.test.mjs +113 -0
  390. package/test/deploy-health-scan.test.mjs +29 -1
  391. package/test/gcloud-auth.test.mjs +111 -0
  392. package/test/google-cloud-connection.test.mjs +83 -0
  393. package/test/google-cloud-inventory.test.mjs +64 -0
  394. package/test/init-options.test.mjs +35 -0
  395. package/test/integration/app-command.test.mjs +30 -0
  396. package/test/integration/cad-project.test.mjs +4 -1
  397. package/test/integration/cms-app-scaffold.test.mjs +71 -0
  398. package/test/integration/cms-site-tenancy-contract.test.mjs +3 -2
  399. package/test/integration/codebaseindex-ingest.test.mjs +48 -0
  400. package/test/integration/features-resolve.test.mjs +30 -11
  401. package/test/integration/inspect-path-cli.test.mjs +46 -0
  402. package/test/integration/inventory-evidence.test.mjs +125 -0
  403. package/test/integration/runtime-status.integration.test.mjs +2 -1
  404. package/test/knowledge.test.mjs +35 -1
  405. package/test/loopback-oauth.test.mjs +53 -0
  406. package/test/ollama.test.mjs +22 -0
  407. package/test/security.test.mjs +23 -0
  408. package/test/setup-planner.test.mjs +74 -0
  409. package/test/setup-runtime.test.mjs +51 -0
  410. package/test/terminal/local-pty.mock.test.mjs +3 -1
  411. package/test/terminal-machine-identity.test.mjs +88 -0
  412. package/test/whoami-resume.test.mjs +27 -6
  413. package/packages/agentsam-brand/test/brand-scan.test.mjs +0 -106
  414. package/packages/work-graph/prototype/README.md +0 -32
  415. package/packages/work-graph/prototype/data/demo-workgraph.js +0 -47
  416. package/packages/work-graph/prototype/renderers/timeline-model.js +0 -21
  417. package/packages/work-graph/prototype/renderers/workgraph-runtime.js +0 -38
  418. package/packages/work-graph/prototype-gnantt.html +0 -655
@@ -0,0 +1,106 @@
1
+ import assert from 'node:assert/strict';
2
+ import test from 'node:test';
3
+ import {
4
+ buildOAuthConsentView,
5
+ normalizeOAuthConsentCompany,
6
+ renderOAuthConsentHtml,
7
+ } from '../src/oauth/consent-view.js';
8
+
9
+ test('OAuth consent uses company as issuer brand SSOT without product-specific copy', () => {
10
+ const company = normalizeOAuthConsentCompany({
11
+ id: 'co_default',
12
+ name: 'Fuel & Free Time',
13
+ logo_url: 'https://assets.example.test/logo.png',
14
+ primary_color: '#f15a24',
15
+ auth_bg_color: '#101214',
16
+ });
17
+ const view = buildOAuthConsentView({
18
+ company,
19
+ resource: {
20
+ id: 'res_fnf_mcp',
21
+ audience: 'https://fuelnfreetime.com/mcp',
22
+ display_name: 'Fuel & Free Time MCP',
23
+ description: 'Store, content, and experience tools.',
24
+ },
25
+ client: {
26
+ client_id: 'chatgpt',
27
+ display_name: 'ChatGPT',
28
+ },
29
+ signed_in_email: 'customer@example.test',
30
+ scopes: [
31
+ {
32
+ scope: 'fnf:store.read',
33
+ label: 'Store data',
34
+ description: 'Read published store and CMS data.',
35
+ sort_order: 20,
36
+ },
37
+ {
38
+ scope: 'fnf:experience.read',
39
+ label: 'Interactive experiences',
40
+ description: 'Read published interactive scene metadata.',
41
+ sort_order: 10,
42
+ },
43
+ ],
44
+ });
45
+
46
+ assert.equal(view.issuer.name, 'Fuel & Free Time');
47
+ assert.equal(view.issuer.primaryColor, '#f15a24');
48
+ assert.equal(view.copy.headline, 'Fuel & Free Time MCP wants to connect to ChatGPT');
49
+ assert.equal(view.copy.footer, 'Authorization secured by Fuel & Free Time');
50
+ assert.deepEqual(view.scopes.map((scope) => scope.scope), [
51
+ 'fnf:experience.read',
52
+ 'fnf:store.read',
53
+ ]);
54
+ });
55
+
56
+ test('OAuth consent rejects missing resource audience instead of inventing one', () => {
57
+ assert.throws(
58
+ () => buildOAuthConsentView({
59
+ company: { name: 'Example' },
60
+ resource: { display_name: 'Example MCP' },
61
+ client: { client_id: 'client', display_name: 'Client' },
62
+ }),
63
+ /oauth_consent_resource_audience_required/,
64
+ );
65
+ });
66
+
67
+
68
+ test('OAuth consent renderer escapes malicious strings in every dynamic field', () => {
69
+ const evil = '<script>alert(1)</script>"><img src=x onerror=alert(2)>';
70
+
71
+ const html = renderOAuthConsentHtml({
72
+ company: {
73
+ name: evil,
74
+ logo_url: 'javascript:alert(3)', // must be dropped (not http/https)
75
+ primary_color: 'red; } body { background: url(javascript:alert(4)) } .x {',
76
+ },
77
+ resource: {
78
+ audience: 'https://example.test/mcp',
79
+ display_name: evil,
80
+ description: evil,
81
+ },
82
+ client: {
83
+ client_id: 'evil-client',
84
+ display_name: evil,
85
+ },
86
+ signed_in_email: evil,
87
+ scopes: [
88
+ { scope: 's1', label: evil, description: evil },
89
+ ],
90
+ }, { authorizationId: evil, csrfToken: evil });
91
+
92
+ // Nothing from any dynamic field should survive as a live tag/attribute.
93
+ assert.ok(!html.includes('<script>'), 'raw <script> tag leaked unescaped');
94
+ assert.ok(!html.includes('<img src=x'), 'raw <img> tag leaked unescaped (would fire onerror as a live element)');
95
+ // The dangerous substring is fine to appear as INERT escaped text -- what matters
96
+ // is that it never appears as a live, browser-parsed tag (i.e. preceded by a raw '<').
97
+ assert.ok(!html.includes('javascript:alert'), 'javascript: URL was not rejected by safeHttpUrl');
98
+ assert.ok(!html.includes('background: url(javascript'), 'invalid color value leaked into <style> unescaped');
99
+
100
+ // The escaped form of the payload should be present wherever it was rendered.
101
+ const escaped = '&lt;script&gt;alert(1)&lt;/script&gt;&quot;&gt;&lt;img src=x onerror=alert(2)&gt;';
102
+ assert.ok(html.includes(escaped), 'expected HTML-escaped payload not found in output');
103
+
104
+ // Invalid color input must fall back to the safe default, not pass through raw.
105
+ assert.ok(html.includes('#171717') || html.includes('#0b1020'), 'expected safe fallback brand color not found');
106
+ });
@@ -1,5 +1,6 @@
1
1
  import assert from 'node:assert/strict';
2
2
  import { describe, it } from 'node:test';
3
+ import { PLATFORM_ACCOUNT_ISSUER } from '../src/contracts/auth-config.js';
3
4
  import {
4
5
  requireIamPlatformCredentials,
5
6
  resolveIamPlatformCredentials,
@@ -7,11 +8,21 @@ import {
7
8
  } from '../src/oauth/credentials.js';
8
9
 
9
10
  describe('oauth credentials', () => {
10
- it('requires IAM_CLIENT_ID and IAM_CLIENT_SECRET together', () => {
11
+ it('requires IAM client credentials and defaults the issuer to the platform authority', () => {
11
12
  assert.equal(resolveIamPlatformCredentials({ IAM_CLIENT_ID: 'x' }), null);
13
+ const defaults = resolveIamPlatformCredentials({
14
+ IAM_CLIENT_ID: 'x',
15
+ IAM_CLIENT_SECRET: 'y',
16
+ });
17
+ assert.equal(defaults?.clientId, 'x');
18
+ assert.equal(defaults?.issuer, PLATFORM_ACCOUNT_ISSUER);
12
19
  assert.equal(
13
- resolveIamPlatformCredentials({ IAM_CLIENT_ID: 'x', IAM_CLIENT_SECRET: 'y' })?.clientId,
14
- 'x',
20
+ resolveIamPlatformCredentials({
21
+ IAM_CLIENT_ID: 'x',
22
+ IAM_CLIENT_SECRET: 'y',
23
+ IAM_OAUTH_ISSUER: 'https://iam.example.test',
24
+ })?.issuer,
25
+ 'https://iam.example.test',
15
26
  );
16
27
  });
17
28
 
@@ -26,6 +37,7 @@ describe('oauth credentials', () => {
26
37
  const env = {
27
38
  IAM_CLIENT_ID: 'iam_dcr_legendary',
28
39
  IAM_CLIENT_SECRET: 'secret',
40
+ IAM_OAUTH_ISSUER: 'https://iam.example.test',
29
41
  };
30
42
  const lane = resolveOAuthCredentialLane(env, 'google');
31
43
  assert.equal(lane?.lane, 'iam_platform');
@@ -36,6 +48,7 @@ describe('oauth credentials', () => {
36
48
  const env = {
37
49
  IAM_CLIENT_ID: 'iam_dcr_legendary',
38
50
  IAM_CLIENT_SECRET: 'secret',
51
+ IAM_OAUTH_ISSUER: 'https://iam.example.test',
39
52
  GOOGLE_CLIENT_ID: 'google-byok',
40
53
  GOOGLE_CLIENT_SECRET: 'gsecret',
41
54
  };
@@ -63,7 +76,7 @@ describe('oauth credentials', () => {
63
76
  const creds = resolveIamPlatformCredentials({
64
77
  IAM_CLIENT_ID: 'c',
65
78
  IAM_CLIENT_SECRET: 's',
66
- IAM_OAUTH_ISSUER: 'https://staging.inneranimalmedia.com/',
79
+ IAM_ORIGIN: 'https://staging.inneranimalmedia.com/',
67
80
  });
68
81
  assert.equal(creds?.origin, 'https://staging.inneranimalmedia.com');
69
82
  });
@@ -0,0 +1,58 @@
1
+ import assert from 'node:assert/strict';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { describe, it } from 'node:test';
5
+ import { fileURLToPath } from 'node:url';
6
+ import { resolveOAuthCredentialLane } from '../src/oauth/credentials.js';
7
+ import { resolveGoogleExchangeSecret } from '../src/oauth/google-desktop-exchange.js';
8
+ import { IdentityProviders } from '../src/contracts/provider.js';
9
+ import { loadIdentityProviders, normalizeProviderTemplateId } from '../../../src/features/resolve.js';
10
+
11
+ const PKG = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
12
+ const MIGRATION = path.join(PKG, 'src/migrations/0001_identity_core.sql');
13
+
14
+ describe('identity OAuth presets + accounts SSOT', () => {
15
+ it('migration declares accounts as SSOT before account_identities', () => {
16
+ const sql = fs.readFileSync(MIGRATION, 'utf8');
17
+ assert.match(sql, /CREATE TABLE IF NOT EXISTS accounts/);
18
+ assert.match(sql, /account_identities[`']?\s+is IdP linkage only/i);
19
+ assert.match(sql, /never the account SSOT/i);
20
+ const accountsAt = sql.indexOf('CREATE TABLE IF NOT EXISTS accounts');
21
+ const identitiesAt = sql.indexOf('CREATE TABLE IF NOT EXISTS account_identities');
22
+ assert.ok(accountsAt >= 0 && identitiesAt > accountsAt);
23
+ });
24
+
25
+ it('provider catalog includes google_desktop + cloudflare', () => {
26
+ const providers = loadIdentityProviders();
27
+ const ids = providers.map((p) => p.id);
28
+ assert.ok(ids.includes('google_desktop'));
29
+ assert.ok(ids.includes('cloudflare'));
30
+ assert.ok(IdentityProviders.includes('google_desktop'));
31
+ assert.equal(normalizeProviderTemplateId('google-desktop'), 'google_desktop');
32
+ });
33
+
34
+ it('resolves google_desktop and cloudflare credential lanes', () => {
35
+ const desktop = resolveOAuthCredentialLane(
36
+ { GOOGLE_DESKTOP_CLIENT_ID: 'desk.apps.googleusercontent.com' },
37
+ 'google_desktop',
38
+ );
39
+ assert.equal(desktop?.lane, 'byok_google_desktop');
40
+ assert.equal(desktop?.provider, 'google_desktop');
41
+
42
+ const cf = resolveOAuthCredentialLane(
43
+ { CLOUDFLARE_OAUTH_CLIENT_ID: 'cf-client' },
44
+ 'cloudflare',
45
+ );
46
+ assert.equal(cf?.lane, 'byok_cloudflare');
47
+ assert.equal(cf?.clientSecret, '');
48
+ });
49
+
50
+ it('desktop exchange secret resolution prefers public PKCE', () => {
51
+ const resolved = resolveGoogleExchangeSecret(
52
+ { GOOGLE_DESKTOP_CLIENT_ID: 'desk.apps.googleusercontent.com' },
53
+ 'desk.apps.googleusercontent.com',
54
+ );
55
+ assert.equal(resolved.mode, 'desktop_public_pkce');
56
+ assert.equal(resolved.clientSecret, null);
57
+ });
58
+ });
@@ -13,7 +13,7 @@ describe('auth portal preview server', () => {
13
13
  }
14
14
  });
15
15
 
16
- it('serves IAM auth paths and login HTML', async () => {
16
+ it('serves portable auth paths and login HTML', async () => {
17
17
  const started = await createAuthPortalPreviewServer({ port: 0, host: '127.0.0.1' });
18
18
  server = started.server;
19
19
  baseUrl = started.baseUrl;
@@ -21,7 +21,7 @@ describe('auth portal preview server', () => {
21
21
  const loginRes = await fetch(`${baseUrl}/auth/login`);
22
22
  assert.equal(loginRes.status, 200);
23
23
  const loginHtml = await loginRes.text();
24
- assert.match(loginHtml, /Sign in \| Inner Animal Media/);
24
+ assert.match(loginHtml, /Sign in \| AgentSam/);
25
25
 
26
26
  const signupRes = await fetch(`${baseUrl}/auth/signup`);
27
27
  assert.equal(signupRes.status, 200);
@@ -34,7 +34,7 @@ describe('auth portal preview server', () => {
34
34
  const companyRes = await fetch(`${baseUrl}/api/company`);
35
35
  const companyJson = await companyRes.json();
36
36
  assert.equal(companyJson.ok, true);
37
- assert.equal(companyJson.company.supportEmail, 'hey@inneranimalmedia.com');
37
+ assert.equal(companyJson.company.supportEmail, 'support@agentsam.dev');
38
38
 
39
39
  const apiRes = await fetch(`${baseUrl}/api/auth/login`, {
40
40
  method: 'POST',
@@ -0,0 +1,154 @@
1
+ /**
2
+ * agentsam.runtime.v1 — Runtime Registry vocabulary (JS).
3
+ * Physical D1 tables remain terminal_* ; domain nouns are Runtime*.
4
+ * Schema SSOT: protocol/runtime/agentsam.runtime.v1.schema.json
5
+ * Law: docs/architecture/AGENTSAM_RUNTIME_PROTOCOL.md
6
+ */
7
+
8
+ export const RUNTIME_PROTOCOL_SCHEMA = 'agentsam.runtime.v1';
9
+
10
+ /** Compute owner / cloud. Application-validated (no aggressive D1 CHECK). */
11
+ export const RUNTIME_PROVIDERS = Object.freeze([
12
+ 'local',
13
+ 'google_cloud',
14
+ 'cloudflare',
15
+ 'aws',
16
+ 'azure',
17
+ 'fly',
18
+ 'custom',
19
+ ]);
20
+
21
+ /** What kind of computer/environment. */
22
+ export const RUNTIME_SUBSTRATES = Object.freeze([
23
+ 'host',
24
+ 'vm',
25
+ 'container',
26
+ 'sandbox',
27
+ 'workstation',
28
+ 'microvm',
29
+ 'kubernetes',
30
+ ]);
31
+
32
+ export const RUNTIME_LIFECYCLES = Object.freeze([
33
+ 'persistent',
34
+ 'scale_to_zero',
35
+ 'ephemeral',
36
+ 'job',
37
+ ]);
38
+
39
+ /**
40
+ * What speaks agentsam.runtime.v1 on the instance.
41
+ * ExecOS is an adapter implementation — never a transport.
42
+ */
43
+ export const RUNTIME_ADAPTERS = Object.freeze([
44
+ 'agentsamd',
45
+ 'execos_legacy',
46
+ 'cloudflare_sandbox',
47
+ 'docker_engine',
48
+ 'ssh',
49
+ 'provider_native',
50
+ ]);
51
+
52
+ /** How Studio/IAM reaches the adapter. */
53
+ export const RUNTIME_TRANSPORTS = Object.freeze([
54
+ 'direct_https',
55
+ 'direct_wss',
56
+ 'cloudflare_tunnel',
57
+ 'vpc_service',
58
+ 'vpc_network',
59
+ 'service_binding',
60
+ 'local_socket',
61
+ 'provider_api',
62
+ 'ssh',
63
+ ]);
64
+
65
+ export const RUNTIME_AUTH_MODES = Object.freeze([
66
+ 'connection_token',
67
+ 'platform_bridge',
68
+ 'bridge_key',
69
+ 'service_binding',
70
+ ]);
71
+
72
+ /** Capability keys — discovered, never inferred from provider alone. */
73
+ export const RUNTIME_CAPABILITY_KEYS = Object.freeze([
74
+ 'exec',
75
+ 'pty',
76
+ 'filesystem',
77
+ 'persistent_filesystem',
78
+ 'process',
79
+ 'git',
80
+ 'docker',
81
+ 'gpu',
82
+ 'browser',
83
+ 'gui',
84
+ 'ports',
85
+ 'snapshot',
86
+ ]);
87
+
88
+ /** @deprecated use RUNTIME_ADAPTERS */
89
+ export const RUNTIME_KINDS = RUNTIME_ADAPTERS;
90
+
91
+ /**
92
+ * Map legacy terminal_instances.kind → substrate.
93
+ * @param {'local_device'|'vm'|'sandbox'|string} kind
94
+ */
95
+ export function substrateFromLegacyKind(kind) {
96
+ const k = String(kind || '').trim().toLowerCase();
97
+ if (k === 'local_device') return { substrate: 'host', target_lane: 'local', provider_hint: 'local' };
98
+ if (k === 'vm') return { substrate: 'vm', target_lane: 'remote', provider_hint: 'google_cloud' };
99
+ if (k === 'sandbox') return { substrate: 'sandbox', target_lane: 'sandbox', provider_hint: 'cloudflare' };
100
+ return { substrate: null, target_lane: null, provider_hint: null };
101
+ }
102
+
103
+ /**
104
+ * Map legacy connection transport + transport_provider → adapter + transport.
105
+ * @param {{ transport?: string, transport_provider?: string }} row
106
+ */
107
+ export function normalizeLegacyConnection(row = {}) {
108
+ const legacyTransport = String(row.transport || '').trim().toLowerCase();
109
+ const legacyProvider = String(row.transport_provider || '').trim().toLowerCase();
110
+ let runtime_adapter = 'agentsamd';
111
+ if (legacyTransport === 'execos') runtime_adapter = 'execos_legacy';
112
+ else if (legacyTransport === 'container') runtime_adapter = 'cloudflare_sandbox';
113
+
114
+ let transport = legacyProvider || null;
115
+ if (!transport || transport === 'platform_vpc') {
116
+ transport = transport === 'platform_vpc' ? 'vpc_service' : 'direct_https';
117
+ }
118
+ if (legacyTransport === 'container' && !legacyProvider) {
119
+ transport = 'service_binding';
120
+ }
121
+
122
+ return {
123
+ protocol: RUNTIME_PROTOCOL_SCHEMA,
124
+ runtime_adapter,
125
+ transport,
126
+ };
127
+ }
128
+
129
+ /**
130
+ * Normalize arch vocabulary (live GCP still has x64).
131
+ * @param {string|null|undefined} arch
132
+ */
133
+ export function normalizeArch(arch) {
134
+ const a = String(arch || '').trim().toLowerCase();
135
+ if (!a) return null;
136
+ if (a === 'x64' || a === 'amd64' || a === 'x86_64') return 'x86_64';
137
+ if (a === 'arm64' || a === 'aarch64') return 'arm64';
138
+ return a;
139
+ }
140
+
141
+ /**
142
+ * Hard-constraint check: every required capability must be true on candidate.
143
+ * @param {Record<string, boolean>} required
144
+ * @param {Record<string, boolean>} available
145
+ * @returns {{ ok: boolean, missing: string[] }}
146
+ */
147
+ export function capabilitiesSatisfy(required = {}, available = {}) {
148
+ const missing = [];
149
+ for (const [key, need] of Object.entries(required)) {
150
+ if (!need) continue;
151
+ if (available[key] !== true) missing.push(key);
152
+ }
153
+ return { ok: missing.length === 0, missing };
154
+ }
@@ -0,0 +1,164 @@
1
+ # @inneranimalmedia/theme-scenes
2
+
3
+ Reusable **scene / shell / block** vocabulary for branded website experiences.
4
+
5
+ | Layer | Owns |
6
+ | --- | --- |
7
+ | `@inneranimalmedia/agentsam-sdk-brand` | BrandPack — assets, tokens, roles, delivery |
8
+ | **`@inneranimalmedia/theme-scenes`** | How brands compose into experiences |
9
+ | Page content | What this page says/shows |
10
+ | Demo adapters | Real product surfaces inside scenes |
11
+
12
+ Scenes never hardcode CDN URLs, nav hrefs, or product copy. They consume `SECTION_CONTENT`, route refs, and asset roles.
13
+
14
+ ## Install
15
+
16
+ Workspace package (private for now):
17
+
18
+ ```js
19
+ import {
20
+ createWorkPreset,
21
+ compilePage,
22
+ createCopyBlock,
23
+ createActionBlock,
24
+ composeCardCollection,
25
+ } from '@inneranimalmedia/theme-scenes';
26
+ ```
27
+
28
+ ## Hierarchy
29
+
30
+ ```
31
+ PAGE_CONTENT
32
+ └── SECTION_CONTENT[] → scene kind + theme + scroll + motion
33
+ └── SECTION_GROUP[]
34
+ └── CONTENT_BLOCK[] copy | media | action | cards | demo | …
35
+ ```
36
+
37
+ ## Scene kinds (harvested from Work/Create HTML)
38
+
39
+ | Former HTML piece | Scene / shell |
40
+ | --- | --- |
41
+ | Sticky glass headers | `shell.adaptive-header` |
42
+ | Dark / light globe heroes | `hero.scroll-product` / `hero.editorial` + `visual.orbital-field` |
43
+ | Light→dark gradient | `bridge.theme` |
44
+ | Brand storyboard lanes | `gallery.storyboard` |
45
+ | Icon marquee | `gallery.rail` (loop is one *behavior*) |
46
+ | Service bento | `capability.grid` |
47
+ | MeauxIDE mock | `product.demo` + `agentsam-mini-composer` |
48
+ | MeauxSQL card | `product.demo` + `database-editor` |
49
+ | Staggered tools | `product.stack` |
50
+ | Chess / 3D stage | `interactive.stage` |
51
+ | Footers | `shell.site-footer` |
52
+
53
+ See `SCENE_ORIGIN` in `src/scenes/index.js`.
54
+
55
+ ## Laws
56
+
57
+ 1. No raw colors in scene contracts — use theme tokens / CSS vars.
58
+ 2. No hardcoded internal URLs — use `{ type: 'route', ref: '…' }`.
59
+ 3. No direct CDN URLs — use `{ assetRole: '…' }` + BrandPack resolver.
60
+ 4. No product copy inside generic scenes — inject via groups/blocks.
61
+ 5. No required card counts — empty collections disappear; adaptive layout.
62
+ 6. Major media slots support image / video / model / demo.
63
+ 7. Animated scenes declare reduced-motion behavior.
64
+ 8. Scenes declare theme intent (`surface`, `headerTone`, …).
65
+ 9. Product marketing uses real DemoAdapters, not fake UIs.
66
+ 10. Motion must communicate something (story/scrub), not decorate forever.
67
+
68
+ ## Quick example
69
+
70
+ ```js
71
+ import {
72
+ createWorkPreset,
73
+ createCopyBlock,
74
+ createActionBlock,
75
+ createDemoBlock,
76
+ composeCardCollection,
77
+ compilePage,
78
+ } from '@inneranimalmedia/theme-scenes';
79
+
80
+ const page = createWorkPreset({
81
+ theme: 'inneranimal',
82
+ heroGroups: [{
83
+ blocks: [
84
+ createCopyBlock({
85
+ variant: 'display',
86
+ eyebrow: 'Selected Work',
87
+ title: 'Interface clarity.\nSystem discipline.',
88
+ body: 'Digital products with refined UI and production-grade foundations.',
89
+ }),
90
+ createActionBlock({
91
+ label: 'View the system',
92
+ target: { type: 'route', ref: 'product.agentsam' },
93
+ }),
94
+ ],
95
+ }],
96
+ agentsamGroups: [{
97
+ blocks: [
98
+ createCopyBlock({ title: 'AgentSam', body: 'Unified workspace shell.' }),
99
+ createDemoBlock('agentsam-mini-composer'),
100
+ ],
101
+ }],
102
+ productGroups: [{
103
+ blocks: [
104
+ composeCardCollection([
105
+ { title: 'Database', body: '…', target: { type: 'route', ref: 'product.database' } },
106
+ { title: 'Cloud', body: '…', target: { type: 'route', ref: 'product.cloud' } },
107
+ ]),
108
+ ],
109
+ }],
110
+ });
111
+
112
+ const plan = compilePage(page);
113
+ // plan.sections[].demoHost, plan.cssVars, plan.validation
114
+ ```
115
+
116
+ ## Presets
117
+
118
+ - `agency-home` — institutional flagship narrative
119
+ - `work` — Work page (dark or canvas hero via `heroTone`)
120
+ - `product` — single product landing
121
+ - `services` — capability grid
122
+ - `brand-story` — Create/guideline storyboard
123
+
124
+ ```js
125
+ import { createPreset, listPresets } from '@inneranimalmedia/theme-scenes';
126
+ ```
127
+
128
+ ## Themes
129
+
130
+ `foundation` → `inneranimal` → `agentsam` / `autodidact`
131
+
132
+ Semantic tokens only (`color.surface.canvas`, `type.display.xl`, …). `themeToCssVars()` emits `--scene-*` for hosts.
133
+
134
+ ## Scroll presets
135
+
136
+ | Mode | Typical | Purpose |
137
+ | --- | --- | --- |
138
+ | `natural` | content height | ordinary |
139
+ | `viewport` | ~100vh | focused statement |
140
+ | `linger` | 120–160vh | visual + copy |
141
+ | `sticky-story` | 180–260vh | narrative scrub |
142
+ | `cinematic` | 240–320vh | flagship product |
143
+ | `bridge` | 40–80vh | world transition |
144
+
145
+ Hosts receive normalized `progress` 0→1 (`computeScrollProgress` / `stageAtProgress`).
146
+
147
+ ## Demo adapters
148
+
149
+ | Adapter | Product surface |
150
+ | --- | --- |
151
+ | `agentsam-mini-composer` | AgentSam / MiniComposer |
152
+ | `database-editor` | MeauxSQL-class DB editor |
153
+ | `cad-viewer` | GLB turntable |
154
+ | `generic-iframe` | last-resort embed |
155
+
156
+ ## Studio (next)
157
+
158
+ Reusable `studio-shell` (navigator / canvas / inspector) sits *above* this package. Moon Glass mock → Brand Studio panels over BrandPack + theme-scenes — not another one-off HTML page. See AgentSam BrandPack README for the compiler side.
159
+
160
+ ## Tests
161
+
162
+ ```bash
163
+ npm --prefix packages/theme-scenes test
164
+ ```
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@inneranimalmedia/theme-scenes",
3
+ "version": "0.1.0",
4
+ "description": "Reusable scene / shell / block vocabulary for branded website experiences. BrandPack owns look; theme-scenes owns composition.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "engines": {
8
+ "node": ">=22 <25"
9
+ },
10
+ "main": "./src/index.js",
11
+ "exports": {
12
+ ".": "./src/index.js",
13
+ "./contracts": "./src/contracts/index.js",
14
+ "./scenes": "./src/scenes/index.js",
15
+ "./shell": "./src/shell/index.js",
16
+ "./blocks": "./src/blocks/index.js",
17
+ "./visuals": "./src/visuals/index.js",
18
+ "./demos": "./src/demos/index.js",
19
+ "./themes": "./src/themes/index.js",
20
+ "./presets": "./src/presets/index.js",
21
+ "./package.json": "./package.json"
22
+ },
23
+ "files": [
24
+ "src",
25
+ "README.md"
26
+ ],
27
+ "scripts": {
28
+ "test": "node --test test/*.test.mjs"
29
+ },
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+ssh://git@github.com/SamPrimeaux/agentsam-sdk.git",
33
+ "directory": "packages/theme-scenes"
34
+ },
35
+ "publishConfig": {
36
+ "access": "restricted"
37
+ },
38
+ "keywords": [
39
+ "agentsam",
40
+ "theme",
41
+ "scenes",
42
+ "sections",
43
+ "brand",
44
+ "cms"
45
+ ],
46
+ "agentsam": {
47
+ "kind": "theme-runtime",
48
+ "slug": "theme-scenes",
49
+ "depends_on": [
50
+ "@inneranimalmedia/agentsam-sdk-brand"
51
+ ]
52
+ }
53
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Block helpers — scenes compose these; they never own brand URLs.
3
+ */
4
+
5
+ export {
6
+ createCopyBlock,
7
+ createMediaBlock,
8
+ createActionBlock,
9
+ createCardsBlock,
10
+ createDemoBlock,
11
+ composeCardCollection,
12
+ BLOCK_KINDS,
13
+ } from '../contracts/index.js';
14
+
15
+ /** Resolve whether a block should render (empty collections disappear). */
16
+ export function shouldRenderBlock(block) {
17
+ if (!block?.kind) return false;
18
+ if (block.kind === 'cards') return Array.isArray(block.items) && block.items.length > 0;
19
+ if (block.kind === 'copy') {
20
+ return Boolean(block.title || block.body || block.eyebrow || (block.bullets && block.bullets.length));
21
+ }
22
+ if (block.kind === 'action') return Boolean(block.label);
23
+ if (block.kind === 'demo') return Boolean(block.adapter);
24
+ if (block.kind === 'media') return Boolean(block.media?.assetRole || block.media?.ref);
25
+ return true;
26
+ }
27
+
28
+ export function filterRenderableBlocks(blocks = []) {
29
+ return blocks.filter(shouldRenderBlock);
30
+ }