@inneranimalmedia/agentsam-sdk 2.6.3 → 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 (608) hide show
  1. package/AGENTSAM.md +17 -0
  2. package/README.md +31 -10
  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 +16 -1
  57. package/bin/agentsam-rapid-rust +36 -0
  58. package/docs/AUTH_IDENTITY_CONTRACT.md +2 -0
  59. package/docs/BRAND_INTELLIGENCE.md +1 -1
  60. package/docs/MACHINE_INTELLIGENCE.md +120 -0
  61. package/docs/WINDOWS_RUNTIME_INSTALL.md +30 -0
  62. package/docs/architecture/AGENTSAM_APPLICATION_CONTRACT.md +188 -0
  63. package/docs/architecture/AGENTSAM_DISTRIBUTION_OWNERSHIP.md +176 -0
  64. package/docs/architecture/AGENTSAM_GO_RUNTIME.md +282 -0
  65. package/docs/architecture/AGENTSAM_RUNTIME_PROTOCOL.md +151 -0
  66. package/docs/architecture/CODEBASEINDEX_GUIDED_PATH.md +202 -0
  67. package/docs/architecture/FS_E2E_CLOSURE_RECEIPT.md +59 -0
  68. package/docs/architecture/LOCAL_FS_AUTHORITY.md +38 -0
  69. package/docs/architecture/LOCAL_STUDIO_CLOUDFLARE_OAUTH.md +36 -0
  70. package/docs/architecture/PLAN_CLI_AND_LOCAL_STUDIO_DESKTOP.md +96 -0
  71. package/docs/architecture/R2_SLUG_NAMESPACE.md +20 -0
  72. package/docs/architecture/SAM_ACTIVITY_RECOVERY_RECEIPT.md +39 -0
  73. package/docs/architecture/SAM_DECISION_WORK_RECEIPT.md +54 -0
  74. package/docs/architecture/SAM_KERNEL.md +181 -0
  75. package/docs/architecture/SAM_MACHINE_NORMALIZATION_PRECOMMIT_REPORT.md +208 -0
  76. package/docs/architecture/SLASH_SKILLS_PORTABLE.md +116 -0
  77. package/docs/architecture/WORK_PRODUCT_EXTRACTION.md +97 -0
  78. package/docs/architecture/fs-e2e-receipt.latest.json +42 -0
  79. package/docs/architecture/previews/codebaseindex-guided-path/CODEBASEINDEX_GUIDED_PATH.md +202 -0
  80. package/docs/architecture/previews/codebaseindex-guided-path/index.html +321 -0
  81. package/docs/brand/AGENT_SAM_ICON_GRAMMAR.md +70 -0
  82. package/docs/content-studio/HOST_MOUNT_CHECKLIST.md +71 -0
  83. package/docs/content-studio/REVISION_GATE_2026-09-27.md +501 -0
  84. package/docs/contracts/capability-install-planner.md +67 -0
  85. package/docs/contracts/environment-vocabulary.md +195 -0
  86. package/docs/contracts/google-cloud-oauth-setup.md +199 -0
  87. package/docs/local-studio/WORKMODE_DONOR_NOTES.md +1 -1
  88. package/docs/plans/LOCAL-STUDIO-GRADUATION-2026-09-26.md +290 -0
  89. package/docs/plans/LOCAL-STUDIO-REAL-APP-CONTRACT-ADDENDUM-2026-09-27.md +394 -0
  90. package/docs/plans/MACHINE-FIRST-APPS-TUI-2026-09-24.md +227 -0
  91. package/docs/plans/TOMORROW-EXTENSIVE-TODO-2026-09-26.md +221 -0
  92. package/docs/plans/TOMORROW-MACHINE-FIRST-BRIEFING.md +145 -0
  93. package/docs/plans/UNIVERSAL-INGEST-MACHINE-FIRST-2026-09-24.md +215 -0
  94. package/docs/plugins.md +2 -2
  95. package/docs/product/AGENTSAM_PRODUCT_EXPERIENCE_STANDARD.md +280 -0
  96. package/docs/product/LOCAL_STUDIO_DESKTOP_EXPERIENCE.md +139 -0
  97. package/docs/product/README.md +8 -0
  98. package/docs/rapid-rust-wasm.md +35 -0
  99. package/migrations/d1/0010_portable_tickets_memory.sql +140 -0
  100. package/migrations/d1/0011_agentsam_skill_v2.sql +185 -0
  101. package/migrations/d1/0011b_agentsam_skill_v2_cutover.sql +22 -0
  102. package/migrations/d1/0011c_agentsam_skill_v2_backfill.sql +76 -0
  103. package/migrations/d1/0011d_agentsam_skill_v2_retrieval_revisions.sql +50 -0
  104. package/migrations/d1/0012_agentsam_tools_required_seed.sql +67 -0
  105. package/migrations/d1/0013_identity_oauth_states.sql +15 -0
  106. package/migrations/d1/0014_auth_event_log.sql +20 -0
  107. package/migrations/d1/0015_identity_oauth_state_app_id.sql +3 -0
  108. package/migrations/d1/0016_cloudflare_oauth_user_oauth_tokens_ssot.sql +14 -0
  109. package/migrations/d1/README_PORTABLE_CONTROL_PLANE.md +16 -0
  110. package/migrations/sqlite/agentsam_skill_retrieval.portable.sql +42 -0
  111. package/package.json +88 -14
  112. package/packages/agentsam-brand/README.md +106 -11
  113. package/packages/agentsam-brand/bin/agentsam-brand.mjs +9 -0
  114. package/packages/agentsam-brand/package.json +39 -7
  115. package/packages/agentsam-brand/src/adapters/cloudflare-images.js +453 -0
  116. package/packages/agentsam-brand/src/adapters/cloudflare-r2.js +74 -0
  117. package/packages/agentsam-brand/src/adapters/d1-registry.js +26 -0
  118. package/packages/agentsam-brand/src/adapters/filesystem.js +59 -0
  119. package/packages/agentsam-brand/src/adapters/memory.js +31 -0
  120. package/packages/agentsam-brand/src/cli/controller.js +503 -0
  121. package/packages/agentsam-brand/src/cli/wizard.js +526 -0
  122. package/packages/agentsam-brand/src/core/capabilities.js +201 -0
  123. package/packages/agentsam-brand/src/core/derivatives.js +211 -0
  124. package/packages/agentsam-brand/src/core/errors.js +12 -0
  125. package/packages/agentsam-brand/src/core/ingest.js +195 -0
  126. package/packages/agentsam-brand/src/core/inspect.js +109 -0
  127. package/packages/agentsam-brand/src/core/keys.js +83 -0
  128. package/packages/agentsam-brand/src/core/naming.js +142 -0
  129. package/packages/agentsam-brand/src/core/optimize.js +316 -0
  130. package/packages/agentsam-brand/src/core/pack.js +305 -0
  131. package/packages/agentsam-brand/src/core/plan.js +276 -0
  132. package/packages/agentsam-brand/src/core/preview.js +159 -0
  133. package/packages/agentsam-brand/src/core/processors/cloudflare.js +68 -0
  134. package/packages/agentsam-brand/src/core/processors/contract.js +203 -0
  135. package/packages/agentsam-brand/src/core/processors/index.js +148 -0
  136. package/packages/agentsam-brand/src/core/processors/native.js +82 -0
  137. package/packages/agentsam-brand/src/core/processors/sharp.js +113 -0
  138. package/packages/agentsam-brand/src/core/processors/squoosh-binary.js +195 -0
  139. package/packages/agentsam-brand/src/core/promote.js +288 -0
  140. package/packages/agentsam-brand/src/core/receipts.js +155 -0
  141. package/packages/agentsam-brand/src/core/v2/compile.js +280 -0
  142. package/packages/agentsam-brand/src/core/v2/derivatives-semantic.js +207 -0
  143. package/packages/agentsam-brand/src/core/v2/ingest-graph.js +387 -0
  144. package/packages/agentsam-brand/src/core/v2/roles.js +180 -0
  145. package/packages/agentsam-brand/src/core/v2/schema.js +209 -0
  146. package/packages/agentsam-brand/src/core/v2/templates.js +114 -0
  147. package/packages/agentsam-brand/src/index.js +193 -36
  148. package/packages/agentsam-brand/src/presets/app-icon.json +16 -0
  149. package/packages/agentsam-brand/src/presets/favicon.json +17 -0
  150. package/packages/agentsam-brand/src/presets/hero.json +12 -0
  151. package/packages/agentsam-brand/src/presets/index.js +40 -0
  152. package/packages/agentsam-brand/src/presets/logo.json +12 -0
  153. package/packages/agentsam-brand/src/presets/model.json +8 -0
  154. package/packages/agentsam-brand/src/presets/og-image.json +10 -0
  155. package/packages/agentsam-brand/src/presets/product-shot.json +11 -0
  156. package/packages/agentsam-brand/src/presets/social-image.json +10 -0
  157. package/packages/agentsam-brand/src/presets/web-image.json +10 -0
  158. package/packages/agentsam-contracts/src/artifacts.ts +41 -0
  159. package/packages/agentsam-contracts/src/errors.ts +16 -0
  160. package/packages/agentsam-errors/src/envelope.js +53 -0
  161. package/packages/agentsam-errors/src/index.js +1 -0
  162. package/packages/agentsam-errors/src/recovery.js +301 -0
  163. package/packages/agentsam-knowledge/src/autorag/index.js +1 -1
  164. package/packages/agentsam-knowledge/src/providers/index.js +20 -6
  165. package/packages/agentsam-knowledge/src/providers/ollama-endpoint.js +31 -0
  166. package/packages/agentsam-knowledge/test/autorag.test.mjs +22 -1
  167. package/packages/agentsam-nav/package.json +2 -2
  168. package/packages/agentsam-rapid-rust/Cargo.lock +344 -0
  169. package/packages/agentsam-rapid-rust/Cargo.toml +18 -0
  170. package/packages/agentsam-rapid-rust/README.md +5 -0
  171. package/packages/agentsam-rapid-rust/src/main.rs +718 -0
  172. package/packages/agentsam-rapid-rust/templates/api/Cargo.toml.tmpl +18 -0
  173. package/packages/agentsam-rapid-rust/templates/api/src/lib.rs.tmpl +17 -0
  174. package/packages/agentsam-rapid-rust/templates/common/README.md.tmpl +22 -0
  175. package/packages/agentsam-rapid-rust/templates/common/package.json.tmpl +12 -0
  176. package/packages/agentsam-rapid-rust/templates/common/wrangler.toml.tmpl +6 -0
  177. package/packages/agentsam-rapid-rust/templates/crypto-auth/Cargo.toml.tmpl +21 -0
  178. package/packages/agentsam-rapid-rust/templates/crypto-auth/src/lib.rs.tmpl +32 -0
  179. package/packages/agentsam-rapid-rust/templates/data-processor/Cargo.toml.tmpl +18 -0
  180. package/packages/agentsam-rapid-rust/templates/data-processor/src/lib.rs.tmpl +41 -0
  181. package/packages/agentsam-rapid-rust/templates/shared-core/Cargo.toml.tmpl +9 -0
  182. package/packages/agentsam-rapid-rust/templates/shared-core/core/Cargo.toml.tmpl +7 -0
  183. package/packages/agentsam-rapid-rust/templates/shared-core/core/src/lib.rs.tmpl +23 -0
  184. package/packages/agentsam-rapid-rust/templates/shared-core/worker/Cargo.toml.tmpl +12 -0
  185. package/packages/agentsam-rapid-rust/templates/shared-core/worker/src/lib.rs.tmpl +16 -0
  186. package/packages/agentsam-rapid-rust/templates/shared-core/wrangler.toml.tmpl +6 -0
  187. package/packages/agentsam-repository/src/index.js +1 -0
  188. package/packages/agentsam-repository/src/merkle/semantic.js +3 -10
  189. package/packages/agentsam-repository/src/source-types.js +85 -0
  190. package/packages/agentsam-vault/README.md +96 -0
  191. package/packages/agentsam-vault/package.json +32 -0
  192. package/packages/agentsam-vault/src/contracts/credential.d.ts +78 -0
  193. package/packages/agentsam-vault/src/contracts/credential.js +132 -0
  194. package/packages/agentsam-vault/src/crypto/aes-gcm.d.ts +30 -0
  195. package/packages/agentsam-vault/src/crypto/aes-gcm.js +107 -0
  196. package/packages/agentsam-vault/src/crypto/oauth-envelope.js +150 -0
  197. package/packages/agentsam-vault/src/index.d.ts +9 -0
  198. package/packages/agentsam-vault/src/index.js +27 -0
  199. package/packages/agentsam-vault/src/providers/registry.js +90 -0
  200. package/packages/agentsam-vault/src/runtime/resolver.js +77 -0
  201. package/packages/agentsam-workbench/README.md +24 -0
  202. package/packages/agentsam-workbench/package.json +38 -0
  203. package/packages/agentsam-workbench/src/agent/AgentPanel.tsx +41 -0
  204. package/packages/agentsam-workbench/src/agent/ArtifactCard.tsx +9 -0
  205. package/packages/agentsam-workbench/src/agent/Composer.tsx +102 -0
  206. package/packages/agentsam-workbench/src/agent/ConnectedAgentPanel.tsx +194 -0
  207. package/packages/agentsam-workbench/src/agent/ContextualComposer.tsx +788 -0
  208. package/packages/agentsam-workbench/src/agent/GoalStatusStrip.tsx +38 -0
  209. package/packages/agentsam-workbench/src/agent/MiniAgentSam.tsx +86 -0
  210. package/packages/agentsam-workbench/src/agent/ModelSelect.tsx +19 -0
  211. package/packages/agentsam-workbench/src/agent/Thread.tsx +56 -0
  212. package/packages/agentsam-workbench/src/agent/ToolReceipt.tsx +11 -0
  213. package/packages/agentsam-workbench/src/agent/contextual-composer.css +611 -0
  214. package/packages/agentsam-workbench/src/agent/index.ts +10 -0
  215. package/packages/agentsam-workbench/src/agent/mini-agentsam.css +12 -0
  216. package/packages/agentsam-workbench/src/browser/BrowserFrame.tsx +37 -0
  217. package/packages/agentsam-workbench/src/browser/index.ts +1 -0
  218. package/packages/agentsam-workbench/src/index.ts +6 -0
  219. package/packages/agentsam-workbench/src/project-control.css +160 -0
  220. package/packages/agentsam-workbench/src/projects/ProjectsSurface.tsx +131 -0
  221. package/packages/agentsam-workbench/src/projects/index.ts +1 -0
  222. package/packages/agentsam-workbench/src/shell/Breadcrumb.tsx +35 -0
  223. package/packages/agentsam-workbench/src/shell/ResizableStage.tsx +99 -0
  224. package/packages/agentsam-workbench/src/shell/SidePanel.tsx +5 -0
  225. package/packages/agentsam-workbench/src/shell/index.ts +4 -0
  226. package/packages/agentsam-workbench/src/shell/surfaceRegistry.ts +29 -0
  227. package/packages/agentsam-workbench/src/terminal/TerminalSurface.tsx +5 -0
  228. package/packages/agentsam-workbench/src/terminal/index.ts +1 -0
  229. package/packages/agentsam-workbench/src/timeline/GanttBoard.tsx +258 -0
  230. package/packages/agentsam-workbench/src/timeline/index.ts +1 -0
  231. package/packages/agentsam-workbench/tsconfig.json +13 -0
  232. package/packages/connectors/cloudflare/OAUTH_STORAGE_AUDIT.md +53 -0
  233. package/packages/connectors/cloudflare/package.json +3 -1
  234. package/packages/connectors/cloudflare/src/api-client.js +279 -0
  235. package/packages/connectors/cloudflare/src/capabilities.js +585 -0
  236. package/packages/connectors/cloudflare/src/credential.js +318 -0
  237. package/packages/connectors/cloudflare/src/families/brand-protection.js +123 -0
  238. package/packages/connectors/cloudflare/src/families/keyless.js +114 -0
  239. package/packages/connectors/cloudflare/src/families/pages.js +151 -0
  240. package/packages/connectors/cloudflare/src/families/scanner.js +123 -0
  241. package/packages/connectors/cloudflare/src/families/snippets.js +207 -0
  242. package/packages/connectors/cloudflare/src/families/tag-gateway.js +46 -0
  243. package/packages/connectors/cloudflare/src/families/tags.js +124 -0
  244. package/packages/connectors/cloudflare/src/families/token-validation.js +95 -0
  245. package/packages/connectors/cloudflare/src/families/workflows.js +156 -0
  246. package/packages/connectors/cloudflare/src/index.js +102 -265
  247. package/packages/connectors/cloudflare/src/oauth-persist.js +336 -0
  248. package/packages/connectors/cloudflare/src/owner.js +42 -12
  249. package/packages/connectors/cloudflare/src/permission-options.js +1064 -0
  250. package/packages/connectors/cloudflare/src/routes.js +318 -144
  251. package/packages/connectors/cloudflare/src/scope-catalog.js +345 -0
  252. package/packages/connectors/cloudflare/src/vault.js +2 -2
  253. package/packages/connectors/cloudflare/tests/capabilities.test.mjs +276 -0
  254. package/packages/connectors/cloudflare/tests/connector.test.mjs +51 -30
  255. package/packages/connectors/cloudflare/tests/oauth-persist.test.mjs +125 -0
  256. package/packages/identity/.agentsam/features/oauth-login-portal/agentsam.feature.json +1 -1
  257. package/packages/identity/.agentsam/features/oauth-login-portal/providers.json +22 -2
  258. package/packages/identity/.agentsam/features/oauth-login-portal/resources.json +10 -4
  259. package/packages/identity/.agentsam/features/oauth-login-portal/routes.json +31 -2
  260. package/packages/identity/README.md +1 -1
  261. package/packages/identity/backend/README.md +1 -1
  262. package/packages/identity/docs/PORTABLE_IDENTITY_ARCHITECTURE.md +50 -0
  263. package/packages/identity/migrations/D1_SCHEMA_MAPPING.md +32 -0
  264. package/packages/identity/migrations/sqlite/001_identity_core.sql +99 -0
  265. package/packages/identity/migrations/sqlite/002_identity_oauth_client.sql +38 -0
  266. package/packages/identity/migrations/sqlite/003_identity_oauth_server.sql +64 -0
  267. package/packages/identity/migrations/sqlite/004_identity_oauth_consent_catalog.sql +48 -0
  268. package/packages/identity/package.json +3 -2
  269. package/packages/identity/scripts/local-identity-bridge.mjs +184 -0
  270. package/packages/identity/scripts/preview-auth-portal.mjs +7 -7
  271. package/packages/identity/src/adapters/cloudflare-d1/index.js +153 -24
  272. package/packages/identity/src/adapters/sqlite/index.js +322 -0
  273. package/packages/identity/src/app/verify-app.js +95 -0
  274. package/packages/identity/src/contracts/auth-config.js +28 -8
  275. package/packages/identity/src/contracts/external-identity.js +1 -1
  276. package/packages/identity/src/contracts/identity-store.js +115 -0
  277. package/packages/identity/src/contracts/provider.js +1 -0
  278. package/packages/identity/src/contracts/route-ids.js +30 -0
  279. package/packages/identity/src/contracts/route-projection.js +218 -0
  280. package/packages/identity/src/contracts/routes.js +11 -0
  281. package/packages/identity/src/core/browser-paths.js +4 -5
  282. package/packages/identity/src/core/constants.js +13 -8
  283. package/packages/identity/src/core/session-policy.js +32 -0
  284. package/packages/identity/src/frontend/auth-portal/README.md +2 -1
  285. package/packages/identity/src/frontend/auth-portal/pages/login.html +16 -15
  286. package/packages/identity/src/frontend/auth-portal/pages/reset.html +9 -8
  287. package/packages/identity/src/frontend/auth-portal/pages/signup.html +9 -8
  288. package/packages/identity/src/frontend/auth-portal/preview/dashboard-stub.html +1 -1
  289. package/packages/identity/src/frontend/auth-portal/shared/company-branding.js +1 -1
  290. package/packages/identity/src/frontend/auth-portal/shared/desktop-identity-bridge.js +207 -0
  291. package/packages/identity/src/index.js +41 -0
  292. package/packages/identity/src/migrations/0001_identity_core.sql +19 -2
  293. package/packages/identity/src/migrations/0003_accounts_ssot.sql +20 -0
  294. package/packages/identity/src/migrations/README.md +5 -2
  295. package/packages/identity/src/oauth/README.md +19 -8
  296. package/packages/identity/src/oauth/consent-view.js +388 -0
  297. package/packages/identity/src/oauth/credentials.js +46 -19
  298. package/packages/identity/src/oauth/finalize-inbound.js +1 -1
  299. package/packages/identity/src/oauth/google-desktop-exchange.js +173 -0
  300. package/packages/identity/src/oauth/iam-platform.js +8 -7
  301. package/packages/identity/src/oauth/redirect-paths.js +27 -36
  302. package/packages/identity/src/providers/cloudflare/oauth.js +3 -4
  303. package/packages/identity/src/providers/cloudflare/profile.js +49 -14
  304. package/packages/identity/src/providers/iam/index.js +27 -5
  305. package/packages/identity/src/server/identity-service.js +61 -15
  306. package/packages/identity/src/server/mount-policy.js +30 -0
  307. package/packages/identity/src/server/post-auth.js +79 -0
  308. package/packages/identity/src/server/worker-router.js +208 -146
  309. package/packages/identity/tests/auth-config.test.mjs +3 -2
  310. package/packages/identity/tests/finalize-inbound-oauth.test.mjs +6 -6
  311. package/packages/identity/tests/iam-provider.test.mjs +1 -1
  312. package/packages/identity/tests/identity-init-scaffold.test.mjs +3 -0
  313. package/packages/identity/tests/identity-service.test.mjs +52 -5
  314. package/packages/identity/tests/native-session-worker.test.mjs +64 -0
  315. package/packages/identity/tests/oauth-consent-view.test.mjs +106 -0
  316. package/packages/identity/tests/oauth-credentials.test.mjs +20 -5
  317. package/packages/identity/tests/oauth-presets-accounts-ssot.test.mjs +58 -0
  318. package/packages/identity/tests/portable-identity-architecture.test.mjs +157 -0
  319. package/packages/identity/tests/preview-auth-portal.test.mjs +3 -3
  320. package/packages/identity/tests/session-routes-policy.test.mjs +21 -0
  321. package/packages/runtime-protocol/src/index.js +154 -0
  322. package/packages/theme-church-site/package.json +2 -1
  323. package/packages/theme-church-site/src/index.js +1 -0
  324. package/packages/theme-companions-site/package.json +2 -1
  325. package/packages/theme-companions-site/src/index.js +1 -0
  326. package/packages/theme-floors-site/package.json +2 -1
  327. package/packages/theme-floors-site/src/index.js +1 -0
  328. package/packages/theme-fuelnfree-site/package.json +2 -1
  329. package/packages/theme-fuelnfree-site/src/index.js +1 -0
  330. package/packages/theme-handyman-site/package.json +2 -1
  331. package/packages/theme-handyman-site/src/index.js +1 -0
  332. package/packages/theme-insurance-site/package.json +2 -1
  333. package/packages/theme-insurance-site/src/index.js +1 -0
  334. package/packages/theme-scenes/README.md +164 -0
  335. package/packages/theme-scenes/package.json +53 -0
  336. package/packages/theme-scenes/src/blocks/index.js +30 -0
  337. package/packages/theme-scenes/src/contracts/index.js +286 -0
  338. package/packages/theme-scenes/src/demos/index.js +65 -0
  339. package/packages/theme-scenes/src/index.js +75 -0
  340. package/packages/theme-scenes/src/presets/index.js +263 -0
  341. package/packages/theme-scenes/src/runtime/compile.js +119 -0
  342. package/packages/theme-scenes/src/scenes/index.js +146 -0
  343. package/packages/theme-scenes/src/shell/index.js +47 -0
  344. package/packages/theme-scenes/src/themes/index.js +129 -0
  345. package/packages/theme-scenes/src/visuals/index.js +41 -0
  346. package/packages/theme-scenes/test/theme-scenes.test.mjs +179 -0
  347. package/packages/theme-shinshu-site/package.json +2 -1
  348. package/packages/theme-shinshu-site/src/index.js +1 -0
  349. package/packages/work-graph/src/index.js +34 -1
  350. package/packages/work-graph/src/renderers/gantt-model.js +24 -0
  351. package/packages/work-graph/test/work-graph.test.mjs +27 -7
  352. package/protocol/README.md +15 -7
  353. package/protocol/apps/agentsam.app.v1.schema.json +133 -0
  354. package/protocol/apps/agentsam.host-install.v1.schema.json +36 -0
  355. package/protocol/assets/README.md +9 -0
  356. package/protocol/assets/asset-record.v1.schema.json +64 -0
  357. package/protocol/brand/brandpack.v1.schema.json +43 -0
  358. package/protocol/credentials/issue.v1.schema.json +38 -0
  359. package/protocol/database/connection.v1.schema.json +41 -0
  360. package/protocol/embeddings/embedding-profile.v1.schema.json +20 -0
  361. package/protocol/errors/error-envelope.schema.json +135 -1
  362. package/protocol/errors/recovery.v1.schema.json +50 -0
  363. package/protocol/runtime/agentsam.runtime.v1.schema.json +75 -0
  364. package/protocol/runtime/workspace-fs.v1.schema.json +71 -0
  365. package/protocol/sam/activity.v1.schema.json +48 -0
  366. package/protocol/sam/answer.v1.schema.json +35 -0
  367. package/protocol/sam/calibration.v1.schema.json +21 -0
  368. package/protocol/sam/decision-receipt.v1.schema.json +29 -0
  369. package/protocol/sam/evaluation.v1.schema.json +19 -0
  370. package/protocol/sam/operation.schema.json +66 -0
  371. package/protocol/sam/outcome.v1.schema.json +36 -0
  372. package/protocol/sam/question.v1.schema.json +26 -0
  373. package/protocol/sam/registry.seed.json +153 -0
  374. package/protocol/sam/result.schema.json +53 -0
  375. package/protocol/sam/state.v1.schema.json +23 -0
  376. package/protocol/scoring/README.md +10 -0
  377. package/protocol/scoring/scorecard.v1.schema.json +65 -0
  378. package/protocol/skills/agentsam.interaction.v1.schema.json +50 -0
  379. package/protocol/skills/agentsam.skill.v1.schema.json +57 -0
  380. package/protocol/ui/icon-registry.mjs +227 -0
  381. package/protocol/ui/icon.v1.schema.json +51 -0
  382. package/registry/cms-rust-machine-20260928/installable-products.json +31 -0
  383. package/registry/cms-rust-machine-20260928/manifest.json +22 -0
  384. package/registry/cms-rust-machine-20260928/migration.sql +237 -0
  385. package/registry/cms-rust-machine-20260928/receipt.json +21 -0
  386. package/registry/cms-rust-machine-20260928/receipt.sql +27 -0
  387. package/scripts/build_rapid_rust_cli.py +83 -0
  388. package/skills/README.md +22 -9
  389. package/skills/agentsam-codebaseindex/SKILL.md +225 -0
  390. package/skills/catalog.json +14 -0
  391. package/src/attachments/index.js +6 -0
  392. package/src/attachments/intake.js +235 -0
  393. package/src/capabilities/repository-snapshot.js +19 -2
  394. package/src/cli/command-catalog.js +138 -0
  395. package/src/cli/dispatch.js +48 -0
  396. package/src/cli.js +225 -27
  397. package/src/commands/account-auth.js +94 -8
  398. package/src/commands/api-key.js +244 -0
  399. package/src/commands/app.js +365 -29
  400. package/src/commands/billing.js +127 -0
  401. package/src/commands/brand.js +86 -74
  402. package/src/commands/cheat-sheet.js +154 -0
  403. package/src/commands/cloudflare-login.js +222 -0
  404. package/src/commands/cloudflare.js +453 -23
  405. package/src/commands/codebaseindex.js +693 -0
  406. package/src/commands/compute.js +4 -0
  407. package/src/commands/connections.js +11 -5
  408. package/src/commands/credentials.js +116 -0
  409. package/src/commands/env.js +152 -25
  410. package/src/commands/gcloud-auth.js +427 -0
  411. package/src/commands/go.js +366 -53
  412. package/src/commands/google-cloud.js +375 -0
  413. package/src/commands/identity-init.js +2 -2
  414. package/src/commands/interaction-clack.js +115 -0
  415. package/src/commands/mcp.js +226 -33
  416. package/src/commands/models.js +1 -1
  417. package/src/commands/ollama.js +3 -2
  418. package/src/commands/plugins.js +7 -2
  419. package/src/commands/product.js +36 -0
  420. package/src/commands/providers.js +62 -14
  421. package/src/commands/runtime-status.js +28 -9
  422. package/src/commands/runtime.js +313 -0
  423. package/src/commands/rust.js +24 -0
  424. package/src/commands/setup.js +279 -0
  425. package/src/commands/shell.js +59 -5
  426. package/src/commands/skill.js +248 -0
  427. package/src/commands/skills.js +1 -1
  428. package/src/commands/start-local.js +6 -2
  429. package/src/commands/terminal.js +171 -0
  430. package/src/commands/update.js +140 -0
  431. package/src/commands/whoami.js +392 -56
  432. package/src/features/resolve.js +1 -0
  433. package/src/go/build.js +229 -39
  434. package/src/go/cloudflare.js +506 -105
  435. package/src/go/container.js +120 -0
  436. package/src/go/contract.js +9 -4
  437. package/src/go/discover.js +149 -33
  438. package/src/go/index.js +15 -3
  439. package/src/go/native-probe-runner.mjs +119 -0
  440. package/src/go/{registry.js → official-registry.js} +64 -7
  441. package/src/go/official-release.js +10 -0
  442. package/src/go/receipts.js +77 -10
  443. package/src/go/verify.js +9 -2
  444. package/src/index.js +31 -0
  445. package/src/indexing/ingest/discover-models.js +298 -0
  446. package/src/indexing/ingest/inventory.js +478 -0
  447. package/src/indexing/ingest/job-graph.js +181 -0
  448. package/src/indexing/ingest/materials.js +204 -0
  449. package/src/indexing/ingest/style-evidence.js +181 -0
  450. package/src/knowledge/source.js +3 -3
  451. package/src/lib/account-session.js +11 -4
  452. package/src/lib/app-authority.js +172 -0
  453. package/src/lib/auth.js +94 -21
  454. package/src/lib/core-client.js +5 -6
  455. package/src/lib/credentials-audit.js +451 -0
  456. package/src/lib/deploy/health.js +24 -6
  457. package/src/lib/detect-context.js +7 -1
  458. package/src/lib/google-cloud-connection.js +270 -0
  459. package/src/lib/google-cloud-inventory.js +385 -0
  460. package/src/lib/google-desktop-oauth.js +372 -0
  461. package/src/lib/google-studio-brokered-oauth.js +158 -0
  462. package/src/lib/identity-scaffold.js +24 -6
  463. package/src/lib/init-options.js +192 -0
  464. package/src/lib/local-scaffold.js +48 -16
  465. package/src/lib/provider-command-remediation.js +308 -0
  466. package/src/lib/provider-credentials.js +71 -21
  467. package/src/lib/scaffold/index.js +8 -2
  468. package/src/lib/scaffold/mcp-server.js +43 -0
  469. package/src/lib/scaffold/templates/mcp-server/index.js +397 -0
  470. package/src/lib/scaffold/templates/mcp-server/presets.js +39 -0
  471. package/src/lib/scaffold/wizards/cms.js +93 -0
  472. package/src/lib/scaffold/wizards/mcp-server.js +61 -0
  473. package/src/lib/setup/contract.js +26 -0
  474. package/src/lib/setup/discover.js +116 -0
  475. package/src/lib/setup/execute.js +205 -0
  476. package/src/lib/setup/planner.js +134 -0
  477. package/src/lib/setup/recipes.js +235 -0
  478. package/src/lib/setup/runtime-persist.js +197 -0
  479. package/src/lib/setup/runtime.js +394 -0
  480. package/src/lib/slash-commands.js +3 -0
  481. package/src/lib/terminal/machine-identity.js +95 -0
  482. package/src/lib/terminal-local.js +164 -0
  483. package/src/lib/terminal-scopes.js +52 -0
  484. package/src/lib/whoami-capabilities.js +184 -0
  485. package/src/local-fs/capability.js +121 -0
  486. package/src/local-fs/freshness.js +75 -0
  487. package/src/local-fs/index.js +385 -0
  488. package/src/local-fs/paths.js +100 -0
  489. package/src/local-pty/server.js +326 -21
  490. package/src/mcp/authority.js +58 -108
  491. package/src/mcp/client-adapters.js +68 -144
  492. package/src/mcp/client.js +142 -122
  493. package/src/mcp/cloudflare-bundles.js +225 -0
  494. package/src/mcp/index.js +12 -0
  495. package/src/models/ai-access-onboarding.js +112 -0
  496. package/src/models/discovery.js +10 -2
  497. package/src/models/inventory-core.js +9 -1
  498. package/src/plugins/cloudflare.js +1 -1
  499. package/src/providers/ollama-chat.js +2 -1
  500. package/src/sam/activity/index.js +183 -0
  501. package/src/sam/client.js +252 -0
  502. package/src/sam/decision/calibration.js +109 -0
  503. package/src/sam/decision/confidence.js +126 -0
  504. package/src/sam/decision/evaluate.js +157 -0
  505. package/src/sam/decision/evaluators/deterministic.js +341 -0
  506. package/src/sam/decision/evaluators/heuristic.js +61 -0
  507. package/src/sam/decision/evaluators/select.js +50 -0
  508. package/src/sam/decision/evaluators/semantic.js +149 -0
  509. package/src/sam/decision/hierarchical.js +61 -0
  510. package/src/sam/decision/index.js +53 -0
  511. package/src/sam/decision/policy.js +86 -0
  512. package/src/sam/decision/questions.js +120 -0
  513. package/src/sam/decision/receipt.js +148 -0
  514. package/src/sam/decision/state.js +117 -0
  515. package/src/sam/decision/types.js +22 -0
  516. package/src/sam/decision/validate.js +200 -0
  517. package/src/sam/define.js +51 -0
  518. package/src/sam/index.js +65 -0
  519. package/src/sam/operations/brand-scan.js +62 -0
  520. package/src/sam/operations/cad-blender-inspect.js +36 -0
  521. package/src/sam/operations/codebaseindex-ingest.js +49 -0
  522. package/src/sam/operations/decision-evaluate.js +59 -0
  523. package/src/sam/operations/planning-astar.js +77 -0
  524. package/src/sam/operations/planning-goap.js +60 -0
  525. package/src/sam/operations/repository-inspect.js +72 -0
  526. package/src/sam/operations/security-scan.js +33 -0
  527. package/src/sam/operations/terminal-exec.js +29 -0
  528. package/src/sam/planning/astar.js +311 -0
  529. package/src/sam/planning/goap.js +177 -0
  530. package/src/sam/planning/index.js +21 -0
  531. package/src/sam/planning/state.js +84 -0
  532. package/src/sam/registry.js +48 -0
  533. package/src/sam/result.js +77 -0
  534. package/src/sam/seed.js +44 -0
  535. package/src/sam/types.js +116 -0
  536. package/src/security/inventory.js +12 -2
  537. package/src/security/local-vault.js +2 -0
  538. package/src/security/scan.js +1 -1
  539. package/src/skills/catalog.js +64 -0
  540. package/src/skills/content-resolver.js +124 -0
  541. package/src/skills/hosted-store.js +37 -0
  542. package/src/skills/index.js +29 -64
  543. package/src/skills/interaction.js +102 -0
  544. package/src/skills/local-store.js +228 -0
  545. package/src/skills/manifest.js +104 -0
  546. package/src/skills/metrics.js +31 -0
  547. package/src/skills/registry.js +184 -0
  548. package/src/skills/runtime.js +287 -0
  549. package/src/skills/slash.js +44 -0
  550. package/src/ui/cli/help.js +94 -101
  551. package/test/account-session.test.mjs +3 -3
  552. package/test/app-authority-context.test.mjs +32 -0
  553. package/test/cli/api-key-env-whoami.test.mjs +129 -0
  554. package/test/cli/codebaseindex-plan-ux.test.mjs +37 -0
  555. package/test/cli/go.test.mjs +62 -5
  556. package/test/cli/mcp-client.test.mjs +21 -10
  557. package/test/cli/runtime-persist.test.mjs +56 -0
  558. package/test/cli/rust-command.test.mjs +21 -0
  559. package/test/cli/skill-npm-and-env.test.mjs +52 -0
  560. package/test/cli/wireframes-go-registry.test.mjs +87 -2
  561. package/test/credentials-audit.test.mjs +113 -0
  562. package/test/deploy-health-scan.test.mjs +29 -1
  563. package/test/gcloud-auth.test.mjs +111 -0
  564. package/test/go/build-source-identity.test.mjs +31 -0
  565. package/test/go/cloudflare-probe.test.mjs +274 -10
  566. package/test/go/distribution.test.mjs +28 -0
  567. package/test/google-cloud-connection.test.mjs +83 -0
  568. package/test/google-cloud-inventory.test.mjs +64 -0
  569. package/test/init-options.test.mjs +35 -0
  570. package/test/integration/ai-access-onboarding.test.mjs +47 -0
  571. package/test/integration/app-command.test.mjs +30 -0
  572. package/test/integration/cad-project.test.mjs +4 -1
  573. package/test/integration/cli-help.test.mjs +1 -1
  574. package/test/integration/cms-app-scaffold.test.mjs +71 -0
  575. package/test/integration/cms-site-tenancy-contract.test.mjs +9 -8
  576. package/test/integration/codebaseindex-ingest.test.mjs +214 -0
  577. package/test/integration/features-resolve.test.mjs +30 -11
  578. package/test/integration/icon-registry.test.mjs +67 -0
  579. package/test/integration/ingest-discover-models.test.mjs +30 -0
  580. package/test/integration/inspect-path-cli.test.mjs +46 -0
  581. package/test/integration/install-script.test.mjs +12 -9
  582. package/test/integration/inventory-evidence.test.mjs +125 -0
  583. package/test/integration/local-fs.test.mjs +113 -0
  584. package/test/integration/provider-env-cli.test.mjs +2 -1
  585. package/test/integration/runtime-status.integration.test.mjs +2 -1
  586. package/test/integration/sam-activity-recovery.test.mjs +147 -0
  587. package/test/integration/sam-decision.test.mjs +584 -0
  588. package/test/integration/sam-kernel.test.mjs +99 -0
  589. package/test/integration/sam-planning-astar.test.mjs +279 -0
  590. package/test/integration/skill-runtime.test.mjs +240 -0
  591. package/test/integration/studio-fs-pty-e2e.test.mjs +294 -0
  592. package/test/knowledge.test.mjs +35 -1
  593. package/test/loopback-oauth.test.mjs +53 -0
  594. package/test/models.test.mjs +14 -7
  595. package/test/ollama.test.mjs +22 -0
  596. package/test/security.test.mjs +23 -0
  597. package/test/setup-planner.test.mjs +74 -0
  598. package/test/setup-runtime.test.mjs +51 -0
  599. package/test/shell.test.mjs +4 -4
  600. package/test/terminal/local-pty.mock.test.mjs +3 -1
  601. package/test/terminal-machine-identity.test.mjs +88 -0
  602. package/test/whoami-resume.test.mjs +27 -6
  603. package/packages/agentsam-brand/test/brand-scan.test.mjs +0 -106
  604. package/packages/work-graph/prototype/README.md +0 -32
  605. package/packages/work-graph/prototype/data/demo-workgraph.js +0 -47
  606. package/packages/work-graph/prototype/renderers/timeline-model.js +0 -21
  607. package/packages/work-graph/prototype/renderers/workgraph-runtime.js +0 -38
  608. package/packages/work-graph/prototype-gnantt.html +0 -655
@@ -0,0 +1,372 @@
1
+ /**
2
+ * Native Desktop Google OAuth (PKCE + loopback) for Agent Sam CLI.
3
+ * Uses GOOGLE_DESKTOP_CLIENT_ID — never embeds a desktop client secret as a security boundary.
4
+ */
5
+ import { createHash, randomBytes } from 'node:crypto';
6
+ import {
7
+ createLoopbackCallbackListener,
8
+ createPkcePair,
9
+ } from './auth.js';
10
+ import { promptToOpenUrl, openExternalUrl } from './open-url.js';
11
+ import { setSecureProviderKey } from '../security/local-vault.js';
12
+ import { writeGoogleCloudConnection } from './google-cloud-connection.js';
13
+
14
+ /** Identity + Cloud Platform — what `agentsam gcloud auth login` requests by default. */
15
+ export const GOOGLE_CLOUD_CONNECTION_SCOPES = [
16
+ 'openid',
17
+ 'email',
18
+ 'profile',
19
+ 'https://www.googleapis.com/auth/cloud-platform',
20
+ ].join(' ');
21
+
22
+ const GOOGLE_AUTH_URL = 'https://accounts.google.com/o/oauth2/v2/auth';
23
+ const GOOGLE_TOKEN_URL = 'https://oauth2.googleapis.com/token';
24
+ const GOOGLE_USERINFO_URL = 'https://openidconnect.googleapis.com/v1/userinfo';
25
+
26
+ function clean(value) {
27
+ return value == null ? '' : String(value).trim();
28
+ }
29
+
30
+ function base64url(value) {
31
+ return Buffer.from(value)
32
+ .toString('base64')
33
+ .replace(/=/g, '')
34
+ .replace(/\+/g, '-')
35
+ .replace(/\//g, '_');
36
+ }
37
+
38
+ function randomState(randomBytesImpl = randomBytes) {
39
+ return base64url(randomBytesImpl(24));
40
+ }
41
+
42
+ /** Public Desktop client id — env first, then stock Studio public-config (not load-agent-env). */
43
+ export function resolveGoogleDesktopClientId(env = process.env) {
44
+ const id = clean(env.GOOGLE_DESKTOP_CLIENT_ID);
45
+ if (!id) {
46
+ const err = new Error(
47
+ 'GOOGLE_DESKTOP_CLIENT_ID is not configured. Stock path: fetch from Local Studio GET /api/public-config (Worker vars). Do not rely on another user\'s ~/.agentsam/load-agent-env.sh. Tip: agentsam gcloud auth login --permissions',
48
+ );
49
+ err.code = 'google_desktop_client_not_configured';
50
+ throw err;
51
+ }
52
+ return id;
53
+ }
54
+
55
+ /**
56
+ * Resolve desktop client id: env override, then Studio/public host public-config.
57
+ * @param {object} [env]
58
+ * @param {{ fetchImpl?: typeof fetch, publicConfigUrl?: string }} [opts]
59
+ */
60
+ export async function resolveGoogleDesktopClientIdAsync(env = process.env, opts = {}) {
61
+ const fromEnv = clean(env.GOOGLE_DESKTOP_CLIENT_ID);
62
+ if (fromEnv) return fromEnv;
63
+
64
+ const fetchImpl = opts.fetchImpl || fetch;
65
+ const candidates = [];
66
+ if (clean(opts.publicConfigUrl)) candidates.push(clean(opts.publicConfigUrl));
67
+ const studioOrigin = clean(env.AGENTSAM_STUDIO_ORIGIN) || 'https://agentsam.inneranimalmedia.com';
68
+ candidates.push(new URL('/api/public-config', `${studioOrigin}/`).toString());
69
+
70
+ for (const url of candidates) {
71
+ try {
72
+ const res = await fetchImpl(url, {
73
+ headers: { accept: 'application/json' },
74
+ signal: typeof AbortSignal?.timeout === 'function' ? AbortSignal.timeout(8000) : undefined,
75
+ });
76
+ if (!res.ok) continue;
77
+ const body = await res.json().catch(() => null);
78
+ const id = clean(body?.google_desktop_client_id);
79
+ if (id) return id;
80
+ } catch {
81
+ /* try next */
82
+ }
83
+ }
84
+
85
+ return resolveGoogleDesktopClientId(env);
86
+ }
87
+
88
+ export function buildGoogleDesktopAuthUrl({
89
+ clientId,
90
+ redirectUri,
91
+ state,
92
+ codeChallenge,
93
+ scope = GOOGLE_CLOUD_CONNECTION_SCOPES,
94
+ } = {}) {
95
+ const url = new URL(GOOGLE_AUTH_URL);
96
+ url.searchParams.set('client_id', clientId || '');
97
+ url.searchParams.set('redirect_uri', redirectUri || '');
98
+ url.searchParams.set('response_type', 'code');
99
+ url.searchParams.set('scope', scope || GOOGLE_CLOUD_CONNECTION_SCOPES);
100
+ url.searchParams.set('state', state || '');
101
+ url.searchParams.set('code_challenge', codeChallenge || '');
102
+ url.searchParams.set('code_challenge_method', 'S256');
103
+ url.searchParams.set('access_type', 'offline');
104
+ url.searchParams.set('prompt', 'consent');
105
+ url.searchParams.set('include_granted_scopes', 'true');
106
+ return url.toString();
107
+ }
108
+
109
+ export async function exchangeGoogleDesktopCode({
110
+ code,
111
+ codeVerifier,
112
+ clientId,
113
+ redirectUri,
114
+ fetchImpl = fetch,
115
+ timeoutMs = 20_000,
116
+ studioOrigin = '',
117
+ allowStudioBroker = true,
118
+ } = {}) {
119
+ const body = new URLSearchParams({
120
+ grant_type: 'authorization_code',
121
+ code: code || '',
122
+ code_verifier: codeVerifier || '',
123
+ client_id: clientId || '',
124
+ redirect_uri: redirectUri || '',
125
+ });
126
+ // Desktop public clients: secret is optional / not a confidentiality boundary.
127
+ const signal = typeof AbortSignal?.timeout === 'function'
128
+ ? AbortSignal.timeout(Math.max(1, Number(timeoutMs) || 20_000))
129
+ : undefined;
130
+ const res = await fetchImpl(GOOGLE_TOKEN_URL, {
131
+ method: 'POST',
132
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
133
+ body,
134
+ signal,
135
+ });
136
+ const data = await res.json().catch(() => ({}));
137
+ if (res.ok && data.access_token) return data;
138
+
139
+ const detail = data.error_description || data.error || `token_http_${res.status}`;
140
+ const needsSecret = /client_secret/i.test(String(detail));
141
+
142
+ // Stock mitigation: never put a Google client secret in the CLI. If this client_id
143
+ // was created as a Web app in Google Console, ask Local Studio to exchange using
144
+ // Worker-held secrets (GOOGLE_DESKTOP_CLIENT_SECRET or matching web secret).
145
+ if (needsSecret && allowStudioBroker) {
146
+ const origin = clean(studioOrigin)
147
+ || clean(process.env.AGENTSAM_STUDIO_ORIGIN)
148
+ || 'https://agentsam.inneranimalmedia.com';
149
+ try {
150
+ const brokerRes = await fetchImpl(new URL('/api/oauth/google/desktop-exchange', `${origin}/`).toString(), {
151
+ method: 'POST',
152
+ headers: { 'content-type': 'application/json', accept: 'application/json' },
153
+ body: JSON.stringify({
154
+ code,
155
+ code_verifier: codeVerifier,
156
+ redirect_uri: redirectUri,
157
+ client_id: clientId,
158
+ }),
159
+ signal,
160
+ });
161
+ const broker = await brokerRes.json().catch(() => ({}));
162
+ if (brokerRes.ok && broker.access_token) {
163
+ return {
164
+ access_token: broker.access_token,
165
+ refresh_token: broker.refresh_token || null,
166
+ token_type: broker.token_type || 'Bearer',
167
+ expires_in: broker.expires_in || null,
168
+ scope: broker.scope || null,
169
+ exchange_via: 'studio_broker',
170
+ };
171
+ }
172
+ const brokerDetail = broker.detail || broker.error || `broker_http_${brokerRes.status}`;
173
+ const err = new Error(
174
+ `google_token_exchange_failed: ${brokerDetail}. `
175
+ + 'Desktop clients must be type "Desktop app" in Google Console (no secret). '
176
+ + 'Or set Worker secret GOOGLE_DESKTOP_CLIENT_SECRET for a Web-typed client id. '
177
+ + 'Web app login uses GOOGLE_CLIENT_ID + GOOGLE_CLIENT_SECRET on the Worker only.',
178
+ );
179
+ err.code = 'google_token_exchange_failed';
180
+ err.remediation = broker.remediation || null;
181
+ throw err;
182
+ } catch (brokerErr) {
183
+ if (brokerErr?.code === 'google_token_exchange_failed') throw brokerErr;
184
+ // fall through to original error
185
+ }
186
+ }
187
+
188
+ const err = new Error(
189
+ needsSecret
190
+ ? `google_token_exchange_failed: ${detail}. `
191
+ + 'This client_id is confidential (Web) in Google Console. '
192
+ + 'Create an OAuth client type Desktop app and set GOOGLE_DESKTOP_CLIENT_ID, '
193
+ + 'or put that Web client\'s secret on the Worker as GOOGLE_DESKTOP_CLIENT_SECRET.'
194
+ : `google_token_exchange_failed: ${detail}`,
195
+ );
196
+ err.code = 'google_token_exchange_failed';
197
+ throw err;
198
+ }
199
+
200
+ export async function fetchGoogleUserInfo(accessToken, fetchImpl = fetch, timeoutMs = 15_000) {
201
+ const signal = typeof AbortSignal?.timeout === 'function'
202
+ ? AbortSignal.timeout(Math.max(1, Number(timeoutMs) || 15_000))
203
+ : undefined;
204
+ const res = await fetchImpl(GOOGLE_USERINFO_URL, {
205
+ headers: { Authorization: `Bearer ${accessToken}` },
206
+ signal,
207
+ });
208
+ if (!res.ok) return null;
209
+ return res.json().catch(() => null);
210
+ }
211
+
212
+ /**
213
+ * Full Desktop Google Cloud connection login.
214
+ * Opens system browser → loopback callback settles automatically (no second Enter).
215
+ */
216
+ export async function runGoogleDesktopCloudLogin(options = {}) {
217
+ const write = options.write || ((s) => process.stdout.write(s));
218
+ const env = options.env || process.env;
219
+ const clientId = await resolveGoogleDesktopClientIdAsync(env, {
220
+ fetchImpl: options.fetchImpl,
221
+ publicConfigUrl: options.publicConfigUrl,
222
+ });
223
+ const scope = clean(options.scope) || GOOGLE_CLOUD_CONNECTION_SCOPES;
224
+ const state = randomState(options.randomBytesImpl);
225
+ const pkce = createPkcePair({ randomBytesImpl: options.randomBytesImpl });
226
+
227
+ const listener = await createLoopbackCallbackListener({
228
+ state,
229
+ host: options.host || '127.0.0.1',
230
+ port: options.port,
231
+ callbackPath: options.callbackPath || '/callback',
232
+ timeoutMs: options.timeoutMs || 300_000,
233
+ createServerImpl: options.createServerImpl,
234
+ });
235
+
236
+ try {
237
+ const authUrl = buildGoogleDesktopAuthUrl({
238
+ clientId,
239
+ redirectUri: listener.redirectUri,
240
+ state,
241
+ codeChallenge: pkce.challenge,
242
+ scope,
243
+ });
244
+
245
+ write('\n Agent Sam · Google Cloud connection\n');
246
+ write(' ────────────────────────────────────────────────────────\n');
247
+ write(' Desktop OAuth + PKCE (loopback). Browser will return here automatically.\n');
248
+ write(` Client ${clientId.slice(0, 28)}…\n`);
249
+ write(` Redirect ${listener.redirectUri}\n`);
250
+ write(' Scopes\n');
251
+ for (const s of scope.split(/\s+/).filter(Boolean)) {
252
+ write(` • ${s}\n`);
253
+ }
254
+ write('\n');
255
+
256
+ if (options.json) {
257
+ write(JSON.stringify({
258
+ schema_version: 'agentsam-google-desktop-oauth-v1',
259
+ mode: 'desktop_pkce',
260
+ client_id: clientId,
261
+ redirect_uri: listener.redirectUri,
262
+ authorization_url: authUrl,
263
+ scopes: scope.split(/\s+/).filter(Boolean),
264
+ }, null, 2) + '\n');
265
+ }
266
+
267
+ if (!options.noLaunchBrowser) {
268
+ const promptImpl = options.promptToOpenUrlImpl || promptToOpenUrl;
269
+ await promptImpl(authUrl, {
270
+ heading: ' Continue to Agent Sam (Google Cloud) at:',
271
+ prompt: 'Press ENTER to open Google in your browser. When you finish, this terminal continues automatically.',
272
+ input: options.input,
273
+ output: options.output,
274
+ openImpl: options.openImpl || openExternalUrl,
275
+ });
276
+ } else {
277
+ write(` Open this URL manually:\n ${authUrl}\n\n`);
278
+ write(' Waiting for loopback callback…\n');
279
+ }
280
+
281
+ write(' Waiting for Google callback on loopback…\n');
282
+ const callback = await listener.waitForCallback();
283
+ write(' ✓ Loopback callback received\n');
284
+ // Release the port before network/keychain work so the browser tab can close cleanly.
285
+ try { await listener.close(); } catch { /* ignore */ }
286
+ write(' Exchanging authorization code with Google…\n');
287
+ const token = await exchangeGoogleDesktopCode({
288
+ code: callback.code,
289
+ codeVerifier: pkce.verifier,
290
+ clientId,
291
+ redirectUri: listener.redirectUri,
292
+ fetchImpl: options.fetchImpl,
293
+ });
294
+
295
+ write(' Fetching Google account profile…\n');
296
+ const profile = await fetchGoogleUserInfo(token.access_token, options.fetchImpl);
297
+ const email = clean(profile?.email) || null;
298
+ const expiresAt = token.expires_in
299
+ ? new Date(Date.now() + Number(token.expires_in) * 1000).toISOString()
300
+ : null;
301
+
302
+ const credentialPayload = JSON.stringify({
303
+ schema_version: 'agentsam-google-oauth-token-v1',
304
+ access_token: token.access_token,
305
+ refresh_token: token.refresh_token || null,
306
+ token_type: token.token_type || 'Bearer',
307
+ scope: token.scope || scope,
308
+ expires_at: expiresAt,
309
+ email,
310
+ client_id: clientId,
311
+ });
312
+
313
+ if (options.storeCredential !== false) {
314
+ write(' Storing credential (keychain / local vault)…\n');
315
+ setSecureProviderKey('google-cloud', {
316
+ value: credentialPayload,
317
+ accountId: email,
318
+ }, { home: options.home, env, disableOsStore: options.disableOsStore });
319
+ }
320
+
321
+ if (email && options.writeConnection !== false) {
322
+ writeGoogleCloudConnection(
323
+ { identity: email },
324
+ { home: options.home, env },
325
+ );
326
+ }
327
+
328
+ write('\n ✓ Google Cloud connection authorized\n');
329
+ if (email) write(` Identity ${email}\n`);
330
+ write(' Stored OS keychain / local vault (google-cloud)\n');
331
+ write(' Next\n');
332
+ write(' agentsam google-cloud connection set --project PROJECT_ID\n');
333
+ write(' agentsam google-cloud doctor\n');
334
+ write('\n');
335
+
336
+ return {
337
+ ok: true,
338
+ email,
339
+ scopes: (token.scope || scope).split(/\s+/).filter(Boolean),
340
+ expires_at: expiresAt,
341
+ has_refresh_token: Boolean(token.refresh_token),
342
+ };
343
+ } finally {
344
+ try { await listener.close(); } catch { /* already closed */ }
345
+ }
346
+ }
347
+
348
+ /**
349
+ * Console / IAM checklist for Google Cloud + MCP (not OAuth scopes).
350
+ */
351
+ export function googleCloudPermissionChecklist() {
352
+ return {
353
+ oauth_scopes_requested: GOOGLE_CLOUD_CONNECTION_SCOPES.split(/\s+/),
354
+ oauth_consent_screen: [
355
+ 'Google Auth Platform → Data Access: add cloud-platform (and openid/email/profile)',
356
+ 'Branding → App name: AgentSam Local Studio (name shows only after brand verification)',
357
+ 'Until verified, Google shows the authorized domain (often inneranimalmedia.com)',
358
+ 'Audience: Testing → add your Google accounts as test users',
359
+ ],
360
+ project_iam_roles: [
361
+ 'roles/viewer or stronger for read discovery',
362
+ 'roles/editor or roles/owner for provision/mutate',
363
+ 'roles/mcp.toolUser for Google/Google Cloud remote MCP (mcp.tools.call)',
364
+ 'Plus product roles (e.g. run.developer, bigquery.jobUser) for specific MCP servers',
365
+ ],
366
+ notes: [
367
+ 'OAuth scopes authorize the app to call APIs as you.',
368
+ 'IAM roles on the GCP project authorize what that principal can actually do.',
369
+ 'Both are required for Cloud operations.',
370
+ ],
371
+ };
372
+ }
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Stock CLI Google Cloud login via Local Studio Web client (secret stays on Worker).
3
+ * Browser: Studio /api/oauth/google/cli-cloud/* → loopback pickup → CLI stores tokens.
4
+ */
5
+ import { randomBytes } from 'node:crypto';
6
+ import {
7
+ createLoopbackCallbackListener,
8
+ } from './auth.js';
9
+ import { promptToOpenUrl, openExternalUrl } from './open-url.js';
10
+ import { setSecureProviderKey } from '../security/local-vault.js';
11
+ import { writeGoogleCloudConnection } from './google-cloud-connection.js';
12
+ import { GOOGLE_CLOUD_CONNECTION_SCOPES } from './google-desktop-oauth.js';
13
+
14
+ function clean(value) {
15
+ return value == null ? '' : String(value).trim();
16
+ }
17
+
18
+ function base64url(value) {
19
+ return Buffer.from(value)
20
+ .toString('base64')
21
+ .replace(/=/g, '')
22
+ .replace(/\+/g, '-')
23
+ .replace(/\//g, '_');
24
+ }
25
+
26
+ function randomState(randomBytesImpl = randomBytes) {
27
+ return base64url(randomBytesImpl(24));
28
+ }
29
+
30
+ /**
31
+ * Stock CLI Google Cloud login via Local Studio Web client (secret stays on Worker).
32
+ * Browser: Studio /api/oauth/google/cli-cloud/* → loopback pickup → CLI stores tokens.
33
+ */
34
+ export async function runGoogleStudioBrokeredCloudLogin(options = {}) {
35
+ const write = options.write || ((s) => process.stdout.write(s));
36
+ const env = options.env || process.env;
37
+ const fetchImpl = options.fetchImpl || fetch;
38
+ const studioOrigin = clean(options.studioOrigin)
39
+ || clean(env.AGENTSAM_STUDIO_ORIGIN)
40
+ || 'https://agentsam.inneranimalmedia.com';
41
+ const state = randomState(options.randomBytesImpl);
42
+
43
+ const listener = await createLoopbackCallbackListener({
44
+ state,
45
+ host: options.host || '127.0.0.1',
46
+ port: options.port,
47
+ callbackPath: options.callbackPath || '/callback',
48
+ timeoutMs: options.timeoutMs || 300_000,
49
+ createServerImpl: options.createServerImpl,
50
+ });
51
+
52
+ try {
53
+ const startUrl = new URL('/api/oauth/google/cli-cloud/start', `${studioOrigin}/`);
54
+ startUrl.searchParams.set('loopback', listener.redirectUri);
55
+ startUrl.searchParams.set('state', state);
56
+
57
+ write('\n Agent Sam · Google Cloud connection\n');
58
+ write(' ────────────────────────────────────────────────────────\n');
59
+ write(' Studio Web OAuth broker (GOOGLE_CLIENT_ID + Worker secret).\n');
60
+ write(' Desktop PKCE is optional via: agentsam gcloud auth login --desktop\n');
61
+ write(` Studio ${studioOrigin}\n`);
62
+ write(` Loopback ${listener.redirectUri}\n`);
63
+ write(' Scopes\n');
64
+ for (const s of GOOGLE_CLOUD_CONNECTION_SCOPES.split(/\s+/).filter(Boolean)) {
65
+ write(` • ${s}\n`);
66
+ }
67
+ write('\n');
68
+
69
+ if (!options.noLaunchBrowser) {
70
+ const promptImpl = options.promptToOpenUrlImpl || promptToOpenUrl;
71
+ await promptImpl(startUrl.toString(), {
72
+ heading: ' Continue to Agent Sam (Google Cloud) at:',
73
+ prompt: 'Press ENTER to open Google via Local Studio. When you finish, this terminal continues automatically.',
74
+ input: options.input,
75
+ output: options.output,
76
+ openImpl: options.openImpl || openExternalUrl,
77
+ });
78
+ } else {
79
+ write(` Open this URL manually:\n ${startUrl}\n\n`);
80
+ }
81
+
82
+ write(' Waiting for Studio → loopback handoff…\n');
83
+ const callback = await listener.waitForCallback();
84
+ write(' ✓ Loopback handoff received\n');
85
+ try { await listener.close(); } catch { /* ignore */ }
86
+
87
+ if (!callback?.pickup) {
88
+ throw Object.assign(new Error('studio_pickup_missing'), { code: 'studio_pickup_missing' });
89
+ }
90
+
91
+ write(' Collecting tokens from Studio…\n');
92
+ const pickupRes = await fetchImpl(new URL('/api/oauth/google/cli-cloud/pickup', `${studioOrigin}/`).toString(), {
93
+ method: 'POST',
94
+ headers: { 'content-type': 'application/json', accept: 'application/json' },
95
+ body: JSON.stringify({ pickup: callback.pickup, state }),
96
+ signal: typeof AbortSignal?.timeout === 'function' ? AbortSignal.timeout(20_000) : undefined,
97
+ });
98
+ const pickup = await pickupRes.json().catch(() => ({}));
99
+ if (!pickupRes.ok || !pickup.access_token) {
100
+ throw Object.assign(
101
+ new Error(`studio_pickup_failed: ${pickup.error || pickupRes.status}`),
102
+ { code: 'studio_pickup_failed' },
103
+ );
104
+ }
105
+
106
+ const email = clean(pickup.email) || null;
107
+ const expiresAt = pickup.expires_at
108
+ ? new Date(Number(pickup.expires_at) * 1000).toISOString()
109
+ : null;
110
+
111
+ const credentialPayload = JSON.stringify({
112
+ schema_version: 'agentsam-google-oauth-token-v1',
113
+ access_token: pickup.access_token,
114
+ refresh_token: pickup.refresh_token || null,
115
+ token_type: pickup.token_type || 'Bearer',
116
+ scope: pickup.scope || GOOGLE_CLOUD_CONNECTION_SCOPES,
117
+ expires_at: expiresAt,
118
+ email,
119
+ client_id: clean(env.GOOGLE_CLIENT_ID) || 'studio_web_broker',
120
+ exchange_via: 'studio_web_broker',
121
+ });
122
+
123
+ if (options.storeCredential !== false) {
124
+ write(' Storing credential (keychain / local vault)…\n');
125
+ setSecureProviderKey('google-cloud', {
126
+ value: credentialPayload,
127
+ accountId: email,
128
+ }, { home: options.home, env, disableOsStore: options.disableOsStore });
129
+ }
130
+
131
+ if (email && options.writeConnection !== false) {
132
+ writeGoogleCloudConnection(
133
+ { identity: email },
134
+ { home: options.home, env },
135
+ );
136
+ }
137
+
138
+ write('\n ✓ Google Cloud connection authorized\n');
139
+ if (email) write(` Identity ${email}\n`);
140
+ write(' Stored OS keychain / local vault (google-cloud)\n');
141
+ write(' Via Local Studio Web OAuth broker\n');
142
+ write(' Next\n');
143
+ write(' agentsam google-cloud connection set --project PROJECT_ID\n');
144
+ write(' agentsam google-cloud doctor\n');
145
+ write('\n');
146
+
147
+ return {
148
+ ok: true,
149
+ email,
150
+ scopes: String(pickup.scope || GOOGLE_CLOUD_CONNECTION_SCOPES).split(/\s+/).filter(Boolean),
151
+ expires_at: expiresAt,
152
+ has_refresh_token: Boolean(pickup.refresh_token),
153
+ exchange_via: 'studio_web_broker',
154
+ };
155
+ } finally {
156
+ try { await listener.close(); } catch { /* already closed */ }
157
+ }
158
+ }
@@ -17,7 +17,7 @@ export function buildIdentityAppScaffold(config) {
17
17
  const brandName = config.brandName || projectName;
18
18
  const logoUrl = config.logoUrl || '/brand/logo.svg';
19
19
  const sdkVersion = config.sdkVersion || 'alpha';
20
- const provider = config.provider || 'inneranimalmedia';
20
+ const provider = config.provider || 'email';
21
21
 
22
22
  const migrationSql = `${fs.readFileSync(MIGRATION_FILE, 'utf8')}\n${buildCompanySeedSql({ brandName, logoUrl })}\n`;
23
23
  const loginHtml = injectBrandingScript(applyBrandTokens(fs.readFileSync(path.join(AUTH_PAGES_DIR, 'login.html'), 'utf8'), {
@@ -78,11 +78,20 @@ migrations_dir = "migrations"
78
78
  # IAM_CLIENT_SECRET= # wrangler secret put only
79
79
  # IAM_ORIGIN=https://inneranimalmedia.com
80
80
 
81
- # Developer BYOK — takes /api/oauth/{google|github}/start when set
81
+ # Web browser OAuth (BYOK) — takes /api/oauth/{google|github}/start when set
82
82
  # GOOGLE_CLIENT_ID=
83
83
  # GOOGLE_CLIENT_SECRET=
84
84
  # GITHUB_CLIENT_ID=
85
85
  # GITHUB_CLIENT_SECRET=
86
+
87
+ # Google Desktop / CLI PKCE — Console type "Desktop app" (no secret required)
88
+ # GOOGLE_DESKTOP_CLIENT_ID=
89
+ # GOOGLE_DESKTOP_CLIENT_SECRET= # optional; only if client was mis-typed as Web
90
+ # Broker: POST /api/oauth/google/desktop-exchange (loopback redirect only)
91
+
92
+ # Cloudflare sign-in — same secrets as the CF resource connector
93
+ # CLOUDFLARE_OAUTH_CLIENT_ID=
94
+ # CLOUDFLARE_OAUTH_CLIENT_SECRET= # optional for PKCE-only clients
86
95
  `;
87
96
 
88
97
  files['.gitignore'] = `node_modules/
@@ -98,6 +107,8 @@ Boring scaffold: **app/frontend** (auth UI) + **backend** (Worker API) + **migra
98
107
 
99
108
  Provider template: \`${provider}\` (see \`agentsam identity plan --provider ${provider}\`).
100
109
 
110
+ **Account SSOT:** \`accounts\` (row of record). \`account_identities\` is IdP linkage only.
111
+
101
112
  ## Quick start
102
113
 
103
114
  \`\`\`bash
@@ -109,7 +120,15 @@ npm run dev
109
120
  # open http://localhost:8787/auth/login
110
121
  \`\`\`
111
122
 
112
- OAuth: minted \`IAM_CLIENT_ID\` + \`IAM_CLIENT_SECRET\` (default). Developer BYOK: \`GOOGLE_*\` / \`GITHUB_*\` when set.
123
+ ### OAuth options (pick what you need)
124
+
125
+ | Lane | Env | Routes |
126
+ |------|-----|--------|
127
+ | IAM platform (default) | \`IAM_CLIENT_ID\` + \`IAM_CLIENT_SECRET\` | \`/api/oauth/inneranimalmedia/*\` |
128
+ | Google web | \`GOOGLE_CLIENT_ID\` + \`GOOGLE_CLIENT_SECRET\` | \`/api/oauth/google/start\` |
129
+ | Google desktop/CLI | \`GOOGLE_DESKTOP_CLIENT_ID\` | \`POST /api/oauth/google/desktop-exchange\` |
130
+ | GitHub | \`GITHUB_CLIENT_*\` | \`/api/oauth/github/start\` |
131
+ | Cloudflare | \`CLOUDFLARE_OAUTH_CLIENT_ID\` (+ optional secret) | \`/api/oauth/cloudflare/start\` |
113
132
 
114
133
  ## Layout
115
134
 
@@ -185,9 +204,8 @@ export default {
185
204
  function applyBrandTokens(html, { brandName, logoUrl }) {
186
205
  return html
187
206
  .replace(/Inner Animal Media/g, brandName)
188
- .replace(/Sign in \| Inner Animal Media/g, `Sign in | ${brandName}`)
189
- .replace(/Sign up \| Inner Animal Media/g, `Sign up | ${brandName}`)
190
- .replace(/Reset password \| Inner Animal Media/g, `Reset password | ${brandName}`)
207
+ .replace(/AgentSam/g, brandName)
208
+ .replace(/src="\/shared\/agentsam-mark\.svg"/g, `src="${logoUrl}"`)
191
209
  .replace(/src="\/brand\/[^"]*"/g, `src="${logoUrl}"`)
192
210
  .replace(/href="\/brand\/[^"]*"/g, `href="${logoUrl}"`);
193
211
  }