@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
@@ -3,60 +3,131 @@ import { resolveAccountAuthority } from '../lib/auth.js';
3
3
  import {
4
4
  describeAccountSession,
5
5
  resolveAccountApiKey,
6
+ readAccountSession,
7
+ saveAccountSession,
6
8
  } from '../lib/account-session.js';
7
9
  import { listProviderCredentialStatus } from '../lib/provider-credentials.js';
10
+ import { projectWhoamiCapabilities } from '../lib/whoami-capabilities.js';
11
+ import { collectLocalTerminalContext, mergeTerminalContexts } from '../lib/terminal-local.js';
12
+ import {
13
+ resolveCurrentAppContext,
14
+ resolvePlatformAccountIssuer,
15
+ } from '../lib/app-authority.js';
8
16
 
9
17
  function writeLine(write, value = '') { write(`${value}\n`); }
10
18
 
19
+ function epochToIso(value) {
20
+ const n = Number(value);
21
+ if (!Number.isFinite(n) || n <= 0) return null;
22
+ const ms = n > 1e12 ? n : n * 1000;
23
+ try {
24
+ return new Date(ms).toISOString();
25
+ } catch {
26
+ return null;
27
+ }
28
+ }
29
+
11
30
  function safeTerminalContext(value = {}) {
12
31
  return {
13
32
  available: value?.available === true,
14
- instances: (value?.instances || []).map((row) => ({
15
- id: row?.id || null,
16
- name: row?.name || null,
17
- kind: row?.kind || null,
18
- provider: row?.provider || null,
19
- status: row?.status || null,
20
- platform: row?.platform || null,
21
- arch: row?.arch || null,
22
- active_connection_count: Number(row?.active_connection_count || 0),
23
- default_connection_id: row?.default_connection_id || null,
24
- last_seen_at: row?.last_seen_at || null,
25
- })),
26
- connections: (value?.connections || []).map((row) => ({
27
- id: row?.id || null,
28
- instance_id: row?.instance_id || null,
29
- name: row?.name || null,
30
- kind: row?.kind || null,
31
- provider: row?.provider || null,
32
- transport: row?.transport || null,
33
- transport_provider: row?.transport_provider || null,
34
- is_active: row?.is_active === true,
35
- is_default: row?.is_default === true,
36
- health_status: row?.health_status || 'unknown',
37
- last_seen_at: row?.last_seen_at || null,
38
- })),
33
+ instances: (value?.instances || []).map((row) => {
34
+ const lastSeen = row?.last_seen_at ?? null;
35
+ const id = row?.id || row?.instance_id || null;
36
+ const compute = row?.compute_provider || row?.provider || null;
37
+ return {
38
+ id,
39
+ instance_id: id,
40
+ name: row?.name || null,
41
+ kind: row?.kind || null,
42
+ provider: compute,
43
+ compute_provider: compute,
44
+ status: row?.status || null,
45
+ hostname: row?.hostname || null,
46
+ platform: row?.platform || null,
47
+ arch: row?.arch || null,
48
+ hw_model: row?.hw_model || null,
49
+ active_connection_count: Number(row?.active_connection_count || 0),
50
+ default_connection_id: row?.default_connection_id || null,
51
+ last_seen_at: lastSeen,
52
+ last_seen_at_iso: row?.last_seen_at_iso || epochToIso(lastSeen),
53
+ };
54
+ }),
55
+ connections: (value?.connections || []).map((row) => {
56
+ const lastSeen = row?.last_seen_at ?? null;
57
+ const id = row?.id || row?.connection_id || null;
58
+ const compute = row?.compute_provider || row?.provider || null;
59
+ return {
60
+ id,
61
+ connection_id: id,
62
+ instance_id: row?.instance_id || null,
63
+ name: row?.name || null,
64
+ kind: row?.kind || null,
65
+ provider: compute,
66
+ compute_provider: compute,
67
+ transport: row?.transport || null,
68
+ transport_provider: row?.transport_provider || null,
69
+ endpoint_url: row?.endpoint_url || null,
70
+ route_hostname: row?.route_hostname || null,
71
+ public_url: row?.public_url || row?.endpoint_url || null,
72
+ is_active: row?.is_active === true,
73
+ is_default: row?.is_default === true,
74
+ health_status: row?.health_status || 'unknown',
75
+ last_seen_at: lastSeen,
76
+ last_seen_at_iso: row?.last_seen_at_iso || epochToIso(lastSeen),
77
+ };
78
+ }),
39
79
  };
40
80
  }
41
81
 
42
- function capabilityProbe(credentials = []) {
43
- const has = (provider) => credentials.some((row) => row.provider === provider && row.configured);
44
- return {
45
- repository: { available: true },
46
- database: { available: true, drivers: ['sqlite'] },
47
- vectors: { available: true, drivers: ['local_exact'] },
48
- models: {
49
- available: has('openai') || has('anthropic') || has('gemini') || has('xai') || has('cursor') || has('cloudflare'),
50
- configuredProviders: ['openai', 'anthropic', 'gemini', 'xai', 'cursor', 'cloudflare'].filter((p) => has(p)).length,
51
- },
52
- deploy: { available: has('cloudflare') },
53
- };
82
+ function attachOwnerAccountId(credentials = [], ownerAccountId) {
83
+ const owner = ownerAccountId == null ? '' : String(ownerAccountId).trim();
84
+ if (!owner) return credentials;
85
+ return (credentials || []).map((row) => {
86
+ const next = {
87
+ ...row,
88
+ owner_account_id: owner,
89
+ };
90
+ if (row.provider === 'cloudflare' && row.account_id && row.account_id !== owner) {
91
+ next.cloudflare_account_id = row.account_id;
92
+ }
93
+ // Platform + all providers: account_id means AgentSam au_* for this user
94
+ next.account_id = owner;
95
+ return next;
96
+ });
97
+ }
98
+
99
+ function normalizeAuthKind(kind) {
100
+ const raw = String(kind || '').trim();
101
+ if (raw === 'api_key') return 'agentsam_api_key';
102
+ if (raw === 'browser_oauth' || raw === 'oauth_session') return 'agentsam_browser_oauth';
103
+ return raw || null;
104
+ }
105
+
106
+ function authLabelFor(kind, authType) {
107
+ const k = normalizeAuthKind(kind) || normalizeAuthKind(authType);
108
+ if (k === 'agentsam_api_key') return 'AgentSam API Key';
109
+ if (k === 'agentsam_browser_oauth') return 'AgentSam Browser OAuth';
110
+ if (k === 'agentsam_cf_browser_oauth') return 'Cloudflare Browser OAuth';
111
+ return k || String(authType || 'unknown');
112
+ }
113
+
114
+ function patchBrowserSessionEmail(email, options = {}) {
115
+ const cleanEmail = email == null ? '' : String(email).trim();
116
+ if (!cleanEmail) return;
117
+ try {
118
+ const session = readAccountSession(options);
119
+ if (!session?.access_token) return;
120
+ if (session.email === cleanEmail) return;
121
+ saveAccountSession({ ...session, email: cleanEmail }, options);
122
+ } catch {
123
+ /* best effort — do not fail whoami */
124
+ }
54
125
  }
55
126
 
56
127
  export async function collectWhoami(options = {}) {
57
128
  const env = options.env || process.env;
58
129
  const apiKey = resolveAccountApiKey({ env, explicit: options.token || '', home: options.home });
59
- const browserSession = describeAccountSession({ env, home: options.home });
130
+ let browserSession = describeAccountSession({ env, home: options.home });
60
131
  const authorityLoader = options.authorityLoader || resolveAccountAuthority;
61
132
  const active = await authorityLoader({
62
133
  env,
@@ -69,9 +140,19 @@ export async function collectWhoami(options = {}) {
69
140
  signal: options.signal,
70
141
  });
71
142
  const credentials = listProviderCredentialStatus({ env, home: options.home });
143
+ const localTerminal = options.localTerminal
144
+ || await collectLocalTerminalContext({ env, home: options.home });
145
+ const platformIssuer = resolvePlatformAccountIssuer(env);
146
+ const appContext = resolveCurrentAppContext({
147
+ root: options.root,
148
+ cwd: options.cwd || process.cwd(),
149
+ });
72
150
 
151
+ const activeKind = normalizeAuthKind(active.kind);
152
+ // Project capabilities after we know tokenPermissions (below) when possible.
153
+ let capabilities = options.capabilities || null;
73
154
  const base = {
74
- schema_version: 3,
155
+ schema_version: 4,
75
156
  ok: false,
76
157
  command_id: 'whoami',
77
158
  risk: 'read',
@@ -82,29 +163,67 @@ export async function collectWhoami(options = {}) {
82
163
  authType: null,
83
164
  authLabel: null,
84
165
  authority: 'inneranimalmedia',
166
+ namespaces: {
167
+ platform_issuer: platformIssuer,
168
+ app_id: appContext.app_id,
169
+ host_origin: appContext.host_origin,
170
+ app_context_source: appContext.source,
171
+ note: 'PLATFORM issuer ≠ APP HOST — do not alias',
172
+ },
85
173
  identity: null,
86
174
  account: null,
87
175
  credential: null,
88
176
  tokenPermissions: [],
89
- capabilities: capabilityProbe(credentials),
177
+ capabilities,
90
178
  active_auth: {
91
179
  configured: Boolean(active.value || active.error),
92
- kind: active.kind || null,
180
+ kind: activeKind,
93
181
  source: active.source || null,
94
182
  valid: null,
95
183
  error: active.error || null,
96
184
  },
97
185
  api_key: {
98
186
  configured: Boolean(apiKey.value || apiKey.error),
187
+ kind: 'agentsam_api_key',
99
188
  source: apiKey.source || null,
100
189
  valid: apiKey.error ? false : null,
101
190
  error: apiKey.error || null,
102
191
  },
103
- browser_session: browserSession,
192
+ browser_session: {
193
+ ...browserSession,
194
+ kind: browserSession.kind || (browserSession.configured ? 'agentsam_browser_oauth' : null),
195
+ },
196
+ cf_browser_oauth: {
197
+ kind: 'agentsam_cf_browser_oauth',
198
+ configured: false,
199
+ source: null,
200
+ next: 'agentsam cloudflare login --pack agentsam',
201
+ },
104
202
  provider_credentials: credentials,
203
+ // Local ExecOS profiles stay visible even when remote context fails.
204
+ terminal: safeTerminalContext(localTerminal),
105
205
  };
106
206
 
107
- if (!active.value) return base;
207
+ if (!active.value) {
208
+ if (!capabilities) {
209
+ capabilities = await projectWhoamiCapabilities({
210
+ env,
211
+ home: options.home,
212
+ cwd: options.cwd,
213
+ discoverRemote: options.discoverRemote !== false,
214
+ tokenPermissions: [],
215
+ });
216
+ base.capabilities = capabilities;
217
+ }
218
+ if (/IAM_OAUTH_ISSUER/i.test(String(active.error || ''))) {
219
+ base.active_auth.next =
220
+ 'source ~/.agentsam/load-agent-env.sh # loads AGENTSAM_API_KEY + IAM_OAUTH_ISSUER';
221
+ } else if (!apiKey.value) {
222
+ base.active_auth.next =
223
+ 'agentsam api-key create --store keychain --activate && eval "$(agentsam env shell --profile default)"';
224
+ }
225
+ return base;
226
+ }
108
227
 
109
228
  try {
110
229
  const loader = options.contextLoader || ((token) => getJson('/api/sdk/context', {
@@ -118,18 +237,36 @@ export async function collectWhoami(options = {}) {
118
237
  signal: options.signal,
119
238
  }));
120
239
  const context = await loader(active.value);
121
- const authType = context?.auth_type || (active.kind === 'api_key' ? 'api_key' : 'oauth_session');
240
+ const authType = String(context?.auth_type || '').trim()
241
+ || (activeKind === 'agentsam_api_key' ? 'api_key' : 'browser_oauth');
122
242
  const tokenPermissions = Array.isArray(context?.tokenPermissions)
123
243
  ? context.tokenPermissions
124
244
  : Array.isArray(context?.credential?.scopes)
125
245
  ? context.credential.scopes
126
246
  : [];
127
- const authLabel =
128
- authType === 'api_key'
129
- ? 'AgentSam API Key'
130
- : authType === 'oauth_session'
131
- ? 'OAuth Session'
132
- : String(authType);
247
+ if (!capabilities) {
248
+ capabilities = await projectWhoamiCapabilities({
249
+ env,
250
+ home: options.home,
251
+ cwd: options.cwd,
252
+ discoverRemote: options.discoverRemote !== false,
253
+ tokenPermissions,
254
+ });
255
+ } else if (capabilities.terminal == null) {
256
+ const { projectTerminalCapability } = await import('../lib/terminal-scopes.js');
257
+ capabilities = { ...capabilities, terminal: projectTerminalCapability(tokenPermissions) };
258
+ }
259
+ const ownerAccountId = context?.owner_account_id || context?.account_id || context?.user_id || null;
260
+ const email = context?.email || context?.user?.email || active.session?.email || browserSession.email || null;
261
+
262
+ if (email) {
263
+ patchBrowserSessionEmail(email, { env, home: options.home });
264
+ browserSession = describeAccountSession({ env, home: options.home });
265
+ }
266
+
267
+ const cfConnected = context?.cloudflare?.ok === true
268
+ || context?.cloudflare?.status === 'connected'
269
+ || Boolean(context?.cloudflare?.connection);
133
270
 
134
271
  return {
135
272
  ...base,
@@ -138,15 +275,17 @@ export async function collectWhoami(options = {}) {
138
275
  loggedIn: true,
139
276
  authenticated: true,
140
277
  authType,
141
- authLabel,
278
+ authLabel: authLabelFor(activeKind, authType),
142
279
  identity: {
143
- user_id: context?.user_id || null,
144
- account_id: context?.account_id || null,
145
- email: context?.email || context?.user?.email || null,
280
+ user_id: context?.user_id || ownerAccountId || null,
281
+ account_id: ownerAccountId,
282
+ owner_account_id: ownerAccountId,
283
+ email,
146
284
  },
147
285
  account: {
148
- id: context?.account_id || context?.user_id || null,
149
- display_name: context?.email || context?.user?.email || context?.account_id || null,
286
+ id: ownerAccountId,
287
+ display_name: email || ownerAccountId || null,
288
+ email,
150
289
  },
151
290
  credential: context?.credential
152
291
  ? {
@@ -159,18 +298,36 @@ export async function collectWhoami(options = {}) {
159
298
  expires_at: context.credential.expires_at || null,
160
299
  last_used_at: context.credential.last_used_at || null,
161
300
  }
162
- : active.kind === 'api_key'
301
+ : activeKind === 'agentsam_api_key'
163
302
  ? { id: null, name: null, prefix: null, status: 'active' }
164
303
  : null,
165
304
  tokenPermissions,
166
- capabilities: capabilityProbe(credentials),
167
- active_auth: { ...base.active_auth, valid: true, error: null },
168
- api_key: active.kind === 'api_key' ? { ...base.api_key, valid: true, error: null } : base.api_key,
169
- cloudflare_connected: context?.cloudflare?.ok === true,
305
+ capabilities,
306
+ active_auth: { ...base.active_auth, kind: activeKind, valid: true, error: null },
307
+ api_key: activeKind === 'agentsam_api_key'
308
+ ? { ...base.api_key, valid: true, error: null }
309
+ : base.api_key,
310
+ browser_session: {
311
+ ...browserSession,
312
+ kind: 'agentsam_browser_oauth',
313
+ email: email || browserSession.email || null,
314
+ user_id: browserSession.user_id || ownerAccountId || null,
315
+ account_id: browserSession.account_id || ownerAccountId || null,
316
+ },
317
+ cf_browser_oauth: {
318
+ kind: 'agentsam_cf_browser_oauth',
319
+ configured: cfConnected,
320
+ source: cfConnected ? 'user_oauth_tokens' : null,
321
+ next: cfConnected
322
+ ? 'agentsam cloudflare permissions --json'
323
+ : 'agentsam cloudflare login --pack agentsam',
324
+ },
325
+ provider_credentials: attachOwnerAccountId(credentials, ownerAccountId),
326
+ cloudflare_connected: cfConnected,
170
327
  byok: context?.byok && typeof context.byok === 'object'
171
328
  ? Object.fromEntries(Object.entries(context.byok).map(([key, value]) => [key, { configured: value?.configured === true }]))
172
329
  : {},
173
- terminal: safeTerminalContext(context?.terminal),
330
+ terminal: safeTerminalContext(mergeTerminalContexts(context?.terminal, localTerminal)),
174
331
  };
175
332
  } catch (error) {
176
333
  const rawMessage = error?.message || String(error);
@@ -179,8 +336,16 @@ export async function collectWhoami(options = {}) {
179
336
  : rawMessage;
180
337
  return {
181
338
  ...base,
182
- active_auth: { ...base.active_auth, valid: false, error: message },
183
- api_key: active.kind === 'api_key' ? { ...base.api_key, valid: false, error: message } : base.api_key,
339
+ active_auth: {
340
+ ...base.active_auth,
341
+ valid: false,
342
+ error: message,
343
+ next: /IAM_OAUTH_ISSUER/i.test(message)
344
+ ? 'source ~/.agentsam/load-agent-env.sh'
345
+ : 'agentsam login # or agentsam whoami --json for detail',
346
+ },
347
+ api_key: activeKind === 'agentsam_api_key' ? { ...base.api_key, valid: false, error: message } : base.api_key,
348
+ terminal: safeTerminalContext(localTerminal),
184
349
  };
185
350
  }
186
351
  }
@@ -208,6 +373,7 @@ export function renderWhoami(status) {
208
373
  lines.push(` API key ${status.api_key?.configured ? status.api_key?.valid === false ? 'invalid' : 'configured' : 'not configured'}`);
209
374
  lines.push(` browser login ${status.browser_session?.configured ? 'stored' : 'not configured'}`);
210
375
  if (status.active_auth?.error) lines.push(` error ${status.active_auth.error}`);
376
+ if (status.active_auth?.next) lines.push(` next ${status.active_auth.next}`);
211
377
  lines.push('');
212
378
  if (status.browser_session?.configured && status.active_auth?.error) {
213
379
  lines.push(' tip A login session is saved locally, but the server rejected it on this');
@@ -215,16 +381,47 @@ export function renderWhoami(status) {
215
381
  lines.push(' `agentsam whoami --json` for the full response.');
216
382
  } else if (!status.api_key?.configured) {
217
383
  lines.push(' tip Run `agentsam login` then `agentsam api-key create --store keychain --activate`.');
384
+ lines.push(' Then: source ~/.agentsam/load-agent-env.sh');
385
+ } else if (status.active_auth?.next) {
386
+ lines.push(` tip ${status.active_auth.next}`);
218
387
  }
219
388
  }
389
+
390
+ const shadow = describeAuthShadow(status);
391
+ if (shadow) {
392
+ lines.push('');
393
+ lines.push(...shadow);
394
+ }
395
+
220
396
  lines.push('');
221
397
  lines.push(' Capabilities');
222
398
  const caps = status.capabilities || {};
223
399
  for (const [key, value] of Object.entries(caps)) {
400
+ if (key === 'edit' || key === 'tools' || key === 'cloudflare') continue;
224
401
  const available = value?.available === true ? 'yes' : 'no';
225
- const extra = value?.configuredProviders != null ? ` · providers ${value.configuredProviders}` : '';
402
+ let extra = '';
403
+ if (key === 'terminal' && value?.lanes) {
404
+ const lanes = Object.entries(value.lanes)
405
+ .filter(([, on]) => on)
406
+ .map(([lane]) => lane);
407
+ extra = lanes.length ? ` · ${lanes.join(', ')}` : ' · (no terminal:* on this key)';
408
+ } else if (Array.isArray(value?.configuredProviders)) {
409
+ extra = ` · providers ${value.configuredProviders.join(',') || 0}`;
410
+ } else if (value?.configuredProviders != null) {
411
+ extra = ` · providers ${value.configuredProviders}`;
412
+ } else if (Array.isArray(value?.drivers)) {
413
+ const ids = value.drivers.map((d) => (typeof d === 'string' ? d : d.id)).filter(Boolean);
414
+ if (ids.length) extra = ` · ${ids.join(', ')}`;
415
+ }
226
416
  lines.push(` ${key.padEnd(14)} ${available}${extra}`);
227
417
  }
418
+ if (status.capabilities?.edit) {
419
+ lines.push('');
420
+ lines.push(' Edit capabilities');
421
+ for (const [key, cmd] of Object.entries(status.capabilities.edit)) {
422
+ lines.push(` ${key.padEnd(18)} ${cmd}`);
423
+ }
424
+ }
228
425
  lines.push('');
229
426
  lines.push(' Provider credentials');
230
427
  for (const row of status.provider_credentials || []) {
@@ -239,6 +436,73 @@ export function renderWhoami(status) {
239
436
  return lines.join('\n');
240
437
  }
241
438
 
439
+ /**
440
+ * When browser OAuth exists but API key won authority — explain, don't imply login failed.
441
+ */
442
+ export function describeAuthShadow(status = {}) {
443
+ const browser = status.browser_session || {};
444
+ const active = status.active_auth || {};
445
+ const apiKey = status.api_key || {};
446
+ if (!browser.configured) return null;
447
+ if (active.kind === 'agentsam_browser_oauth' || active.kind === 'browser_oauth') return null;
448
+ if (!(active.kind === 'agentsam_api_key' || active.kind === 'api_key' || apiKey.configured)) return null;
449
+
450
+ const lines = [
451
+ ' Authority lanes',
452
+ ` Current authoritative credential`,
453
+ ` agentsam_api_key · ${apiKey.source || active.source || 'environment'}`,
454
+ '',
455
+ ' agentsam_browser_oauth',
456
+ ` available${browser.expired ? ' · expired' : ''}${browser.refreshable ? ' · refreshable' : ''} but not currently authoritative`,
457
+ browser.email ? ` email ${browser.email}` : ' email (resolve via agentsam whoami after login)',
458
+ '',
459
+ ' Why?',
460
+ ' AGENTSAM_API_KEY (or an explicit aak_* token) has higher precedence than browser OAuth.',
461
+ '',
462
+ ' Options',
463
+ ' keep API key (default — no action)',
464
+ ' prefer session unset AGENTSAM_API_KEY && agentsam whoami',
465
+ ' details agentsam whoami --json',
466
+ ];
467
+ return lines;
468
+ }
469
+
470
+ /**
471
+ * Post-login human summary — never claim OAuth is authoritative when API key still wins.
472
+ */
473
+ export function renderLoginResult(status = {}) {
474
+ const lines = ['', ' ✓ Browser OAuth login saved', ''];
475
+ const shadow = describeAuthShadow(status);
476
+ if (shadow) {
477
+ lines.push(' Current authoritative credential');
478
+ lines.push(` agentsam_api_key · ${status.api_key?.source || status.active_auth?.source || 'environment'}`);
479
+ lines.push('');
480
+ lines.push(' agentsam_browser_oauth');
481
+ lines.push(' available but not currently authoritative');
482
+ lines.push('');
483
+ lines.push(' Why?');
484
+ lines.push(' AGENTSAM_API_KEY has higher precedence.');
485
+ lines.push('');
486
+ lines.push(' [enter] keep API key');
487
+ lines.push(' [s] use OAuth session → unset AGENTSAM_API_KEY && agentsam whoami');
488
+ lines.push(' [d] details → agentsam whoami --json');
489
+ lines.push('');
490
+ } else if (status.active_auth?.kind === 'agentsam_browser_oauth' || status.active_auth?.kind === 'browser_oauth') {
491
+ lines.push(' Current authoritative credential');
492
+ lines.push(' agentsam_browser_oauth');
493
+ lines.push('');
494
+ lines.push(' Next');
495
+ lines.push(' agentsam api-key create --store keychain --activate');
496
+ lines.push(' agentsam whoami');
497
+ lines.push('');
498
+ } else {
499
+ lines.push(' Current authoritative credential');
500
+ lines.push(` ${status.authLabel || status.active_auth?.kind || 'unknown'} · ${status.active_auth?.source || 'runtime'}`);
501
+ lines.push('');
502
+ }
503
+ return lines.join('\n');
504
+ }
505
+
242
506
  export async function runWhoami(argv = [], options = {}) {
243
507
  const allowed = new Set(['--json']);
244
508
  const unknown = argv.filter((arg) => !allowed.has(arg));
@@ -38,6 +38,7 @@ export function normalizeProviderTemplateId(id) {
38
38
  const key = String(id || '').trim().toLowerCase();
39
39
  if (!key) return '';
40
40
  if (key === 'iam') return 'inneranimalmedia';
41
+ if (key === 'google-desktop') return 'google_desktop';
41
42
  return key;
42
43
  }
43
44
 
package/src/index.js CHANGED
@@ -242,6 +242,10 @@ export {
242
242
  pingMcpServer,
243
243
  listMcpTools,
244
244
  callMcpTool,
245
+ withMcpClient,
246
+ listCloudflareMcpBundles,
247
+ getCloudflareMcpBundle,
248
+ scopesForCloudflareMcpBundle,
245
249
  recordToolReceipt,
246
250
  getSessionToolReceipts,
247
251
  clearSessionToolReceipts,