@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,132 @@
1
+ /**
2
+ * Portable AgentSam credential / vault contracts.
3
+ * Secrets never live on CredentialRecord — only credential_ref.
4
+ */
5
+
6
+ /**
7
+ * @typedef {'user'|'account'|'app'} CredentialOwnerType
8
+ * @typedef {'provider_api_key'|'oauth_connection'|'agentsam_api_key'|'app_secret'} CredentialKind
9
+ * @typedef {'active'|'expired'|'revoked'|'invalid'} CredentialStatus
10
+ */
11
+
12
+ /**
13
+ * @typedef {object} CredentialRecord
14
+ * @property {string} id
15
+ * @property {CredentialOwnerType} owner_type
16
+ * @property {string} owner_id
17
+ * @property {CredentialKind} kind
18
+ * @property {string} [provider]
19
+ * @property {string} label
20
+ * @property {string} credential_ref
21
+ * @property {CredentialStatus} status
22
+ * @property {string[]} [capabilities]
23
+ * @property {string[]} [granted_scopes]
24
+ * @property {string|null} [expires_at]
25
+ * @property {string|null} [validated_at]
26
+ * @property {string|null} [last_used_at]
27
+ * @property {string|null} [rotated_at]
28
+ * @property {string} [last4]
29
+ * @property {string} created_at
30
+ * @property {string} updated_at
31
+ */
32
+
33
+ /**
34
+ * @typedef {object} CredentialProviderField
35
+ * @property {string} id
36
+ * @property {'secret'|'text'|'url'} type
37
+ * @property {boolean} [required]
38
+ * @property {string} [label]
39
+ */
40
+
41
+ /**
42
+ * @typedef {object} CredentialProviderDefinition
43
+ * @property {string} id
44
+ * @property {string} label
45
+ * @property {{ kind: CredentialKind, sensitive?: boolean }} credential
46
+ * @property {CredentialProviderField[]} fields
47
+ * @property {string[]} [capabilities]
48
+ * @property {{ test?: boolean, rotate?: boolean, revoke?: boolean }} [operations]
49
+ */
50
+
51
+ export const CREDENTIAL_KINDS = Object.freeze({
52
+ PROVIDER_API_KEY: 'provider_api_key',
53
+ OAUTH_CONNECTION: 'oauth_connection',
54
+ AGENTSAM_API_KEY: 'agentsam_api_key',
55
+ APP_SECRET: 'app_secret',
56
+ });
57
+
58
+ export const CREDENTIAL_STATUSES = Object.freeze({
59
+ ACTIVE: 'active',
60
+ EXPIRED: 'expired',
61
+ REVOKED: 'revoked',
62
+ INVALID: 'invalid',
63
+ });
64
+
65
+ /**
66
+ * Authority lanes — do not conflate.
67
+ *
68
+ * VAULT_MASTER_KEY encrypts BYOK / app secrets at rest (per Worker/app)
69
+ * AGENTSAM_API_KEY aak_* delegated account API credential (IAM verifies hash)
70
+ * AGENTSAM_BRIDGE_KEY machine↔Worker service auth (not a user credential)
71
+ * browser_oauth interactive session cookie (not reusable API key)
72
+ */
73
+ export const CREDENTIAL_AUTHORITY = Object.freeze({
74
+ vaultMasterKey: 'VAULT_MASTER_KEY',
75
+ agentsamApiKey: 'AGENTSAM_API_KEY',
76
+ agentsamApiKeyPrefix: 'aak_',
77
+ agentsamApiKeyStore: 'agentsam_api_credentials',
78
+ bridgeKey: 'AGENTSAM_BRIDGE_KEY',
79
+ });
80
+
81
+ /**
82
+ * @param {Partial<CredentialRecord> & Pick<CredentialRecord,'id'|'owner_type'|'owner_id'|'kind'|'label'|'credential_ref'|'status'|'created_at'|'updated_at'>} input
83
+ * @returns {CredentialRecord}
84
+ */
85
+ export function normalizeCredentialRecord(input) {
86
+ if (!input?.id || !input.credential_ref) {
87
+ throw new Error('credential_record_requires_id_and_ref');
88
+ }
89
+ if (typeof input.credential_ref === 'string' && /^(sk-|sk_live_|AIza|ghp_|cf_|aak_)/i.test(input.credential_ref)) {
90
+ throw new Error('credential_ref_must_not_be_plaintext_secret');
91
+ }
92
+ return Object.freeze({
93
+ id: String(input.id),
94
+ owner_type: input.owner_type,
95
+ owner_id: String(input.owner_id),
96
+ kind: input.kind,
97
+ provider: input.provider ? String(input.provider) : undefined,
98
+ label: String(input.label || input.provider || input.kind),
99
+ credential_ref: String(input.credential_ref),
100
+ status: input.status || CREDENTIAL_STATUSES.ACTIVE,
101
+ capabilities: Array.isArray(input.capabilities) ? [...input.capabilities] : undefined,
102
+ granted_scopes: Array.isArray(input.granted_scopes) ? [...input.granted_scopes] : undefined,
103
+ expires_at: input.expires_at ?? null,
104
+ validated_at: input.validated_at ?? null,
105
+ last_used_at: input.last_used_at ?? null,
106
+ rotated_at: input.rotated_at ?? null,
107
+ last4: input.last4 || undefined,
108
+ created_at: String(input.created_at),
109
+ updated_at: String(input.updated_at),
110
+ });
111
+ }
112
+
113
+ /**
114
+ * @param {CredentialProviderDefinition} def
115
+ */
116
+ export function defineCredentialProvider(def) {
117
+ if (!def?.id || !def?.label || !def?.credential?.kind) {
118
+ throw new Error('invalid_credential_provider');
119
+ }
120
+ return Object.freeze({
121
+ id: def.id,
122
+ label: def.label,
123
+ credential: Object.freeze({ ...def.credential }),
124
+ fields: Object.freeze((def.fields || []).map((f) => Object.freeze({ ...f }))),
125
+ capabilities: Object.freeze([...(def.capabilities || [])]),
126
+ operations: Object.freeze({
127
+ test: def.operations?.test !== false,
128
+ rotate: Boolean(def.operations?.rotate),
129
+ revoke: def.operations?.revoke !== false,
130
+ }),
131
+ });
132
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Type declarations for `@inneranimalmedia/agentsam-vault/crypto`.
3
+ * Runtime stays plain JS (Workers + Node); this file is for TS consumers only.
4
+ */
5
+
6
+ export function parseVaultMasterKeyBytes(rawMasterKey: string): Uint8Array;
7
+
8
+ export function importVaultMasterKey(rawMasterKey: string): Promise<CryptoKey>;
9
+
10
+ /** Mint `v1.<base64-32-bytes>` for wrangler secret put. */
11
+ export function mintVaultMasterKeyV1(): string;
12
+
13
+ export function encryptVaultSecret(
14
+ key: CryptoKey,
15
+ plaintext: string,
16
+ aad: string,
17
+ ): Promise<string>;
18
+
19
+ export function decryptVaultSecret(
20
+ key: CryptoKey,
21
+ packedB64: string,
22
+ aad: string,
23
+ ): Promise<string>;
24
+
25
+ export function last4(value: unknown): string;
26
+
27
+ export function makeCredentialRef(input: {
28
+ backend?: string;
29
+ id: string;
30
+ }): string;
@@ -0,0 +1,107 @@
1
+ /**
2
+ * AES-256-GCM vault crypto.
3
+ * VAULT_MASTER_KEY must be an explicit versioned 32-byte key:
4
+ * v1.<base64|base64url of exactly 32 bytes>
5
+ *
6
+ * No silent truncate / hash of arbitrary strings.
7
+ */
8
+
9
+ const enc = new TextEncoder();
10
+ const dec = new TextDecoder();
11
+
12
+ function b64ToBytes(b64) {
13
+ const normalized = String(b64).replace(/-/g, '+').replace(/_/g, '/');
14
+ const pad = normalized.length % 4 === 0 ? '' : '='.repeat(4 - (normalized.length % 4));
15
+ const bin = atob(normalized + pad);
16
+ const out = new Uint8Array(bin.length);
17
+ for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
18
+ return out;
19
+ }
20
+
21
+ function bytesToB64(bytes) {
22
+ let s = '';
23
+ for (const b of bytes) s += String.fromCharCode(b);
24
+ return btoa(s);
25
+ }
26
+
27
+ /**
28
+ * Parse VAULT_MASTER_KEY into raw 32 bytes.
29
+ * @param {string} rawMasterKey
30
+ * @returns {Uint8Array}
31
+ */
32
+ export function parseVaultMasterKeyBytes(rawMasterKey) {
33
+ const raw = String(rawMasterKey || '').trim();
34
+ if (!raw) throw new Error('VAULT_MASTER_KEY_MISSING');
35
+ if (!raw.startsWith('v1.')) {
36
+ throw new Error(
37
+ 'VAULT_MASTER_KEY_INVALID_FORMAT: expected v1.<base64-32-bytes> (generate: openssl rand -base64 32 | sed "s|^|v1.|")',
38
+ );
39
+ }
40
+ const payload = raw.slice(3);
41
+ let keyBytes;
42
+ try {
43
+ keyBytes = b64ToBytes(payload);
44
+ } catch {
45
+ throw new Error('VAULT_MASTER_KEY_INVALID_BASE64');
46
+ }
47
+ if (keyBytes.byteLength !== 32) {
48
+ throw new Error(
49
+ `VAULT_MASTER_KEY_INVALID_LENGTH: got ${keyBytes.byteLength} bytes, need exactly 32`,
50
+ );
51
+ }
52
+ return keyBytes;
53
+ }
54
+
55
+ /**
56
+ * @param {string} rawMasterKey
57
+ */
58
+ export async function importVaultMasterKey(rawMasterKey) {
59
+ const keyBytes = parseVaultMasterKeyBytes(rawMasterKey);
60
+ return crypto.subtle.importKey('raw', keyBytes, { name: 'AES-GCM' }, false, [
61
+ 'encrypt',
62
+ 'decrypt',
63
+ ]);
64
+ }
65
+
66
+ /**
67
+ * Mint a new versioned master key string for wrangler secret put.
68
+ */
69
+ export function mintVaultMasterKeyV1() {
70
+ const bytes = crypto.getRandomValues(new Uint8Array(32));
71
+ return `v1.${bytesToB64(bytes)}`;
72
+ }
73
+
74
+ export async function encryptVaultSecret(key, plaintext, aad) {
75
+ const iv = crypto.getRandomValues(new Uint8Array(12));
76
+ const cipher = await crypto.subtle.encrypt(
77
+ { name: 'AES-GCM', iv, additionalData: enc.encode(aad) },
78
+ key,
79
+ enc.encode(plaintext),
80
+ );
81
+ const packed = new Uint8Array(iv.byteLength + cipher.byteLength);
82
+ packed.set(iv, 0);
83
+ packed.set(new Uint8Array(cipher), iv.byteLength);
84
+ return bytesToB64(packed);
85
+ }
86
+
87
+ export async function decryptVaultSecret(key, packedB64, aad) {
88
+ const packed = b64ToBytes(packedB64);
89
+ const iv = packed.slice(0, 12);
90
+ const data = packed.slice(12);
91
+ const plain = await crypto.subtle.decrypt(
92
+ { name: 'AES-GCM', iv, additionalData: enc.encode(aad) },
93
+ key,
94
+ data,
95
+ );
96
+ return dec.decode(plain);
97
+ }
98
+
99
+ export function last4(value) {
100
+ const v = String(value ?? '');
101
+ if (!v) return '';
102
+ return v.length <= 4 ? '••••' : v.slice(-4);
103
+ }
104
+
105
+ export function makeCredentialRef({ backend = 'vault', id }) {
106
+ return `${backend}:${id}`;
107
+ }
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Portable OAuth-token envelope for user_oauth_tokens.
3
+ *
4
+ * Compatibility contract:
5
+ * - Key derivation exactly matches IAM backend/credentials/crypto-vault.js:
6
+ * HKDF-SHA256, 16 zero-byte salt, info "iam-vault-v1", AES-256-GCM.
7
+ * - New rows are v2:<kid>:<base64(iv12 || ciphertext)> and REQUIRE AAD.
8
+ * - Unprefixed rows are legacy IAM ciphertext (same KDF, no AAD).
9
+ *
10
+ * This is intentionally separate from the app-secret vault format. App-local
11
+ * secrets and PKCE state do not need to be readable by another runtime.
12
+ */
13
+
14
+ const enc = new TextEncoder();
15
+ const dec = new TextDecoder();
16
+ const HKDF_INFO = 'iam-vault-v1';
17
+ const V2_PREFIX = 'v2:';
18
+
19
+ function bytesToB64(bytes) {
20
+ let s = '';
21
+ for (const b of bytes) s += String.fromCharCode(b);
22
+ return btoa(s);
23
+ }
24
+
25
+ function b64ToBytes(value) {
26
+ try {
27
+ const normalized = String(value || '').replace(/-/g, '+').replace(/_/g, '/');
28
+ const pad = normalized.length % 4 === 0 ? '' : '='.repeat(4 - (normalized.length % 4));
29
+ const bin = atob(normalized + pad);
30
+ const out = new Uint8Array(bin.length);
31
+ for (let i = 0; i < bin.length; i += 1) out[i] = bin.charCodeAt(i);
32
+ return out;
33
+ } catch {
34
+ throw vaultError('vault_unseal_failed', 'Invalid OAuth vault base64 payload');
35
+ }
36
+ }
37
+
38
+ function vaultError(code, message, extra = {}) {
39
+ const error = new Error(message || code);
40
+ error.code = code;
41
+ Object.assign(error, extra);
42
+ return error;
43
+ }
44
+
45
+ async function deriveOauthKey(material, usage = ['encrypt', 'decrypt']) {
46
+ const raw = String(material || '').trim();
47
+ if (!raw) throw vaultError('vault_required', 'VAULT_MASTER_KEY is required');
48
+ const base = await crypto.subtle.importKey('raw', enc.encode(raw), 'HKDF', false, ['deriveKey']);
49
+ return crypto.subtle.deriveKey(
50
+ {
51
+ name: 'HKDF',
52
+ hash: 'SHA-256',
53
+ salt: new Uint8Array(16),
54
+ info: enc.encode(HKDF_INFO),
55
+ },
56
+ base,
57
+ { name: 'AES-GCM', length: 256 },
58
+ false,
59
+ usage,
60
+ );
61
+ }
62
+
63
+ async function decryptPacked(key, packedB64, aad) {
64
+ const packed = b64ToBytes(packedB64);
65
+ if (packed.byteLength < 13) throw vaultError('vault_unseal_failed', 'invalid encrypted payload');
66
+ const iv = packed.slice(0, 12);
67
+ const ciphertext = packed.slice(12);
68
+ const params = { name: 'AES-GCM', iv };
69
+ if (aad != null) params.additionalData = enc.encode(String(aad));
70
+ try {
71
+ const plain = await crypto.subtle.decrypt(params, key, ciphertext);
72
+ return dec.decode(plain);
73
+ } catch {
74
+ throw vaultError('vault_unseal_failed', 'OAuth vault authentication failed');
75
+ }
76
+ }
77
+
78
+ export async function oauthKeyId(material) {
79
+ const raw = String(material || '').trim();
80
+ if (!raw) throw vaultError('vault_required', 'VAULT_MASTER_KEY is required');
81
+ const digest = new Uint8Array(await crypto.subtle.digest('SHA-256', enc.encode(raw)));
82
+ const hex = Array.from(digest, (b) => b.toString(16).padStart(2, '0')).join('');
83
+ return `k1-${hex.slice(0, 16)}`;
84
+ }
85
+
86
+ export function oauthAad(provider, userId, accountIdentifier) {
87
+ const p = String(provider || '').trim().toLowerCase();
88
+ const uid = String(userId || '').trim();
89
+ const account = String(accountIdentifier || '').trim();
90
+ if (!p || !uid || !account) {
91
+ throw vaultError('vault_aad_required', 'provider, userId, and accountIdentifier are required');
92
+ }
93
+ return `${p}:${uid}:${account}`;
94
+ }
95
+
96
+ export async function sealOauthToken(material, plaintext, aad) {
97
+ if (!String(aad || '')) throw vaultError('vault_aad_required', 'OAuth AAD is required');
98
+ const key = await deriveOauthKey(material, ['encrypt']);
99
+ const iv = crypto.getRandomValues(new Uint8Array(12));
100
+ const ciphertext = await crypto.subtle.encrypt(
101
+ { name: 'AES-GCM', iv, additionalData: enc.encode(String(aad)) },
102
+ key,
103
+ enc.encode(String(plaintext ?? '')),
104
+ );
105
+ const packed = new Uint8Array(iv.byteLength + ciphertext.byteLength);
106
+ packed.set(iv, 0);
107
+ packed.set(new Uint8Array(ciphertext), iv.byteLength);
108
+ const kid = await oauthKeyId(material);
109
+ return `${V2_PREFIX}${kid}:${bytesToB64(packed)}`;
110
+ }
111
+
112
+ export async function unsealOauthToken(material, blob, aad) {
113
+ const value = String(blob || '').trim();
114
+ if (!value) throw vaultError('vault_unseal_failed', 'OAuth vault payload is empty');
115
+ const key = await deriveOauthKey(material, ['decrypt']);
116
+
117
+ if (!value.startsWith(V2_PREFIX)) {
118
+ // Legacy IAM format: HKDF-derived AES-GCM with no AAD.
119
+ return decryptPacked(key, value, null);
120
+ }
121
+
122
+ const first = value.indexOf(':', V2_PREFIX.length);
123
+ if (first < 0) throw vaultError('vault_unseal_failed', 'Malformed v2 OAuth vault envelope');
124
+ const storedKid = value.slice(V2_PREFIX.length, first);
125
+ const packed = value.slice(first + 1);
126
+ const currentKid = await oauthKeyId(material);
127
+ if (storedKid !== currentKid) {
128
+ throw vaultError('vault_kid_mismatch', 'OAuth vault key id mismatch', {
129
+ storedKeyId: storedKid,
130
+ currentKeyId: currentKid,
131
+ });
132
+ }
133
+ if (!String(aad || '')) throw vaultError('vault_aad_required', 'OAuth AAD is required');
134
+ return decryptPacked(key, packed, String(aad));
135
+ }
136
+
137
+ /** Test/migration helper: emit the legacy IAM no-AAD format. */
138
+ export async function sealLegacyIamOauthToken(material, plaintext) {
139
+ const key = await deriveOauthKey(material, ['encrypt']);
140
+ const iv = crypto.getRandomValues(new Uint8Array(12));
141
+ const ciphertext = await crypto.subtle.encrypt(
142
+ { name: 'AES-GCM', iv },
143
+ key,
144
+ enc.encode(String(plaintext ?? '')),
145
+ );
146
+ const packed = new Uint8Array(iv.byteLength + ciphertext.byteLength);
147
+ packed.set(iv, 0);
148
+ packed.set(new Uint8Array(ciphertext), iv.byteLength);
149
+ return bytesToB64(packed);
150
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Package entry types for `@inneranimalmedia/agentsam-vault`.
3
+ * Re-exports crypto + contracts used by Local Studio / Worker consumers.
4
+ */
5
+
6
+ export * from "./crypto/aes-gcm.js";
7
+ export * from "./contracts/credential.js";
8
+
9
+ export * from "./crypto/oauth-envelope.js";
@@ -0,0 +1,27 @@
1
+ export {
2
+ CREDENTIAL_KINDS,
3
+ CREDENTIAL_STATUSES,
4
+ CREDENTIAL_AUTHORITY,
5
+ normalizeCredentialRecord,
6
+ defineCredentialProvider,
7
+ } from './contracts/credential.js';
8
+ export { DEFAULT_CREDENTIAL_PROVIDERS, createProviderRegistry } from './providers/registry.js';
9
+ export {
10
+ importVaultMasterKey,
11
+ parseVaultMasterKeyBytes,
12
+ mintVaultMasterKeyV1,
13
+ encryptVaultSecret,
14
+ decryptVaultSecret,
15
+ last4,
16
+ makeCredentialRef,
17
+ } from './crypto/aes-gcm.js';
18
+ export { createCredentialResolver } from './runtime/resolver.js';
19
+
20
+
21
+ export {
22
+ oauthAad,
23
+ oauthKeyId,
24
+ sealOauthToken,
25
+ unsealOauthToken,
26
+ sealLegacyIamOauthToken,
27
+ } from './crypto/oauth-envelope.js';
@@ -0,0 +1,90 @@
1
+ import { defineCredentialProvider, CREDENTIAL_KINDS } from '../contracts/credential.js';
2
+
3
+ /** Provider registry — UI renders fields from this; no hardcoded dropdown lists. */
4
+ export const DEFAULT_CREDENTIAL_PROVIDERS = Object.freeze([
5
+ defineCredentialProvider({
6
+ id: 'openai',
7
+ label: 'OpenAI',
8
+ credential: { kind: CREDENTIAL_KINDS.PROVIDER_API_KEY, sensitive: true },
9
+ fields: [{ id: 'api_key', type: 'secret', required: true, label: 'API key' }],
10
+ capabilities: ['models', 'chat', 'embeddings', 'responses'],
11
+ operations: { test: true, rotate: false, revoke: true },
12
+ }),
13
+ defineCredentialProvider({
14
+ id: 'anthropic',
15
+ label: 'Anthropic',
16
+ credential: { kind: CREDENTIAL_KINDS.PROVIDER_API_KEY, sensitive: true },
17
+ fields: [{ id: 'api_key', type: 'secret', required: true, label: 'API key' }],
18
+ capabilities: ['models', 'chat'],
19
+ operations: { test: true, rotate: false, revoke: true },
20
+ }),
21
+ defineCredentialProvider({
22
+ id: 'gemini',
23
+ label: 'Google Gemini',
24
+ credential: { kind: CREDENTIAL_KINDS.PROVIDER_API_KEY, sensitive: true },
25
+ fields: [{ id: 'api_key', type: 'secret', required: true, label: 'API key' }],
26
+ capabilities: ['models', 'chat', 'embeddings'],
27
+ operations: { test: true, rotate: false, revoke: true },
28
+ }),
29
+ defineCredentialProvider({
30
+ id: 'cursor',
31
+ label: 'Cursor',
32
+ credential: { kind: CREDENTIAL_KINDS.PROVIDER_API_KEY, sensitive: true },
33
+ fields: [{ id: 'api_key', type: 'secret', required: true, label: 'API key' }],
34
+ capabilities: ['models', 'chat'],
35
+ operations: { test: true, rotate: false, revoke: true },
36
+ }),
37
+ defineCredentialProvider({
38
+ id: 'xai',
39
+ label: 'xAI',
40
+ credential: { kind: CREDENTIAL_KINDS.PROVIDER_API_KEY, sensitive: true },
41
+ fields: [{ id: 'api_key', type: 'secret', required: true, label: 'API key' }],
42
+ capabilities: ['models', 'chat'],
43
+ operations: { test: true, rotate: false, revoke: true },
44
+ }),
45
+ defineCredentialProvider({
46
+ id: 'cloudflare',
47
+ label: 'Cloudflare',
48
+ credential: { kind: CREDENTIAL_KINDS.OAUTH_CONNECTION, sensitive: true },
49
+ fields: [],
50
+ capabilities: ['workers', 'd1', 'r2', 'ai', 'dns'],
51
+ operations: { test: true, rotate: false, revoke: true },
52
+ }),
53
+ defineCredentialProvider({
54
+ id: 'github',
55
+ label: 'GitHub',
56
+ credential: { kind: CREDENTIAL_KINDS.OAUTH_CONNECTION, sensitive: true },
57
+ fields: [],
58
+ capabilities: ['repos', 'actions'],
59
+ operations: { test: true, rotate: false, revoke: true },
60
+ }),
61
+ defineCredentialProvider({
62
+ id: 'agentsam',
63
+ label: 'AgentSam API key',
64
+ credential: { kind: CREDENTIAL_KINDS.AGENTSAM_API_KEY, sensitive: true },
65
+ fields: [{ id: 'api_key', type: 'secret', required: true, label: 'AGENTSAM_API_KEY (aak_…)' }],
66
+ capabilities: ['sdk', 'control_plane'],
67
+ operations: { test: true, rotate: true, revoke: true },
68
+ }),
69
+ ]);
70
+
71
+ /**
72
+ * @param {import('../contracts/credential.js').CredentialProviderDefinition[]} [extra]
73
+ */
74
+ export function createProviderRegistry(extra = []) {
75
+ const map = new Map();
76
+ for (const p of [...DEFAULT_CREDENTIAL_PROVIDERS, ...extra]) {
77
+ map.set(p.id, p);
78
+ }
79
+ return Object.freeze({
80
+ get(id) {
81
+ return map.get(String(id || '')) || null;
82
+ },
83
+ list() {
84
+ return [...map.values()];
85
+ },
86
+ listByKind(kind) {
87
+ return [...map.values()].filter((p) => p.credential.kind === kind);
88
+ },
89
+ });
90
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Resolve a usable secret for a capability — env is last-resort compatibility,
3
+ * not the product UX.
4
+ *
5
+ * Precedence (hosted Web Worker path):
6
+ * 1. explicit override
7
+ * 2. account vault (user_secrets unwrap via credential_ref)
8
+ * 3. permitted environment variable (provider adapter)
9
+ * 4. null
10
+ */
11
+
12
+ /**
13
+ * @typedef {object} CredentialResolverOptions
14
+ * @property {(query: { provider: string, capability?: string }) => Promise<{ ref: string, last4?: string }|null>} [lookupVaultMeta]
15
+ * @property {(ref: string) => Promise<string|null>} [unwrap]
16
+ * @property {Record<string, string|undefined>} [env]
17
+ * @property {Record<string, string>} [envMap] provider → env var name
18
+ */
19
+
20
+ const DEFAULT_ENV_MAP = Object.freeze({
21
+ openai: 'OPENAI_API_KEY',
22
+ anthropic: 'ANTHROPIC_API_KEY',
23
+ gemini: 'GEMINI_API_KEY',
24
+ cursor: 'CURSOR_API_KEY',
25
+ xai: 'XAI_API_KEY',
26
+ cloudflare: 'CLOUDFLARE_API_TOKEN',
27
+ agentsam: 'AGENTSAM_API_KEY',
28
+ });
29
+
30
+ /**
31
+ * @param {CredentialResolverOptions} options
32
+ */
33
+ export function createCredentialResolver(options = {}) {
34
+ const envMap = { ...DEFAULT_ENV_MAP, ...(options.envMap || {}) };
35
+ const env = options.env || {};
36
+
37
+ return Object.freeze({
38
+ /**
39
+ * @param {{ provider: string, capability?: string, explicit?: string|null }} query
40
+ * @returns {Promise<{ source: 'explicit'|'vault'|'environment', value: string, last4?: string }|null>}
41
+ */
42
+ async resolve(query) {
43
+ const provider = String(query?.provider || '').trim().toLowerCase();
44
+ if (!provider) return null;
45
+
46
+ const explicit = String(query?.explicit || '').trim();
47
+ if (explicit) {
48
+ return { source: 'explicit', value: explicit, last4: explicit.slice(-4) };
49
+ }
50
+
51
+ if (typeof options.lookupVaultMeta === 'function' && typeof options.unwrap === 'function') {
52
+ const meta = await options.lookupVaultMeta({
53
+ provider,
54
+ capability: query.capability,
55
+ });
56
+ if (meta?.ref) {
57
+ const value = await options.unwrap(meta.ref);
58
+ if (value) {
59
+ return {
60
+ source: 'vault',
61
+ value,
62
+ last4: meta.last4 || value.slice(-4),
63
+ };
64
+ }
65
+ }
66
+ }
67
+
68
+ const envName = envMap[provider];
69
+ const fromEnv = envName ? String(env[envName] || '').trim() : '';
70
+ if (fromEnv) {
71
+ return { source: 'environment', value: fromEnv, last4: fromEnv.slice(-4) };
72
+ }
73
+
74
+ return null;
75
+ },
76
+ });
77
+ }
@@ -0,0 +1,24 @@
1
+ # @inneranimalmedia/agentsam-workbench
2
+
3
+ Reusable React workbench primitives built on `@inneranimalmedia/agentsam-contracts`.
4
+
5
+ This is the shared AgentSam UI layer for Local Studio, CAD Studio, and CMS Studio. It provides controlled/headless primitives for agent threads and composition, model selection, tool/artifact receipts, browser frames, terminal surfaces, and resizable shell panels. Product apps inject their own state, routing, auth, tools, runtime adapters, and visual treatment.
6
+
7
+ Current proof consumer: `apps/local-studio/`. Local Studio now delegates its composer, thread scroll behavior, and split-handle behavior to this package while retaining product-specific styling and state.
8
+
9
+ `packages/agentsam-shell-kit` remains only as a compatibility facade for older imports.
10
+ # Floating annotation helper
11
+
12
+ `MiniAgentSam` is exported from `@inneranimalmedia/agentsam-workbench/agent`.
13
+ Import `@inneranimalmedia/agentsam-workbench/agent/mini-agentsam.css` once in the host.
14
+ The host controls `selecting`, `onSelectingChange`, `onSubmit(prompt, selection)`,
15
+ and an optional `renderComposer` slot. Use `scope()` to restrict selection to a
16
+ particular root. No network, storage, plugin registry, or application dependency
17
+ is built into the helper. It inherits `--nav-*` tokens; other hosts can supply
18
+ `--mini-surface`, `--mini-text`, `--mini-muted`, `--mini-border`, and `--mini-accent`.
19
+
20
+ Selections are bounded descriptive DOM context and never authorize edits. Input
21
+ values are withheld. Cross-origin and sandboxed iframe contents are not inspected;
22
+ their host frame may be selected as a contextual resource. Mark semantic ancestors
23
+ with `data-agentsam-resource` and excluded controls with `data-annotation-control`.
24
+ Local Studio stages the annotation in its active conversation draft for review.