@inneranimalmedia/agentsam-sdk 2.6.4 → 2.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (418) hide show
  1. package/AGENTSAM.md +11 -0
  2. package/README.md +15 -9
  3. package/apps/client-cms-editor/AGENTS.md +12 -0
  4. package/apps/client-cms-editor/IMPORT_PROVENANCE.json +8 -0
  5. package/apps/client-cms-editor/README.md +72 -0
  6. package/apps/client-cms-editor/agentsam.app.json +57 -0
  7. package/apps/client-cms-editor/backend/README.md +5 -0
  8. package/apps/client-cms-editor/backend/package.json +22 -0
  9. package/apps/client-cms-editor/backend/src/api/client.ts +200 -0
  10. package/apps/client-cms-editor/backend/src/demo-bootstrap.ts +145 -0
  11. package/apps/client-cms-editor/backend/src/index.ts +6 -0
  12. package/apps/client-cms-editor/backend/src/model.ts +115 -0
  13. package/apps/client-cms-editor/backend/src/preview/bridge.ts +79 -0
  14. package/apps/client-cms-editor/backend/src/preview/urls.ts +55 -0
  15. package/apps/client-cms-editor/backend/src/routing/cms-route.js +293 -0
  16. package/apps/client-cms-editor/backend/src/routing/index.js +10 -0
  17. package/apps/client-cms-editor/backend/src/storefront.ts +52 -0
  18. package/apps/client-cms-editor/backend/tsconfig.json +15 -0
  19. package/apps/client-cms-editor/backend/worker/index.js +34 -0
  20. package/apps/client-cms-editor/backend/wrangler.jsonc +11 -0
  21. package/apps/client-cms-editor/bin/agentsam-cms.mjs +229 -0
  22. package/apps/client-cms-editor/frontend/index.html +12 -0
  23. package/apps/client-cms-editor/frontend/package.json +33 -0
  24. package/apps/client-cms-editor/frontend/src/AgentSamDrawer.tsx +188 -0
  25. package/apps/client-cms-editor/frontend/src/CmsAgentSurface.tsx +191 -0
  26. package/apps/client-cms-editor/frontend/src/CmsEditor.tsx +1345 -0
  27. package/apps/client-cms-editor/frontend/src/env.d.ts +14 -0
  28. package/apps/client-cms-editor/frontend/src/index.ts +8 -0
  29. package/apps/client-cms-editor/frontend/src/lib/content-safety.ts +63 -0
  30. package/apps/client-cms-editor/frontend/src/main.tsx +17 -0
  31. package/apps/client-cms-editor/frontend/src/mount.tsx +51 -0
  32. package/apps/client-cms-editor/frontend/src/styles/agentsam-drawer.css +214 -0
  33. package/apps/client-cms-editor/frontend/src/styles/cmsShell.css +1739 -0
  34. package/apps/client-cms-editor/frontend/src/styles/studio.css +106 -0
  35. package/apps/client-cms-editor/frontend/src/surfaces/CmsDashboard.tsx +313 -0
  36. package/apps/client-cms-editor/frontend/src/surfaces/CmsGuidedChatHero.tsx +121 -0
  37. package/apps/client-cms-editor/frontend/src/surfaces/CmsHubPage.tsx +132 -0
  38. package/apps/client-cms-editor/frontend/src/surfaces/CmsSiteSwitcher.tsx +176 -0
  39. package/apps/client-cms-editor/frontend/src/surfaces/index.ts +5 -0
  40. package/apps/client-cms-editor/frontend/src/surfaces/types.ts +48 -0
  41. package/apps/client-cms-editor/frontend/tsconfig.json +25 -0
  42. package/apps/client-cms-editor/frontend/vite.config.ts +13 -0
  43. package/apps/client-cms-editor/package-lock.json +3832 -0
  44. package/apps/client-cms-editor/package.json +23 -0
  45. package/apps/client-cms-editor/reference/DONOR_README.md +52 -0
  46. package/apps/client-cms-editor/reference/DONOR_package-lock.json +1253 -0
  47. package/apps/client-cms-editor/reference/DONOR_tsconfig.json +15 -0
  48. package/apps/client-cms-editor/shared/cms/package.json +21 -0
  49. package/apps/client-cms-editor/shared/cms/src/agent-context.ts +35 -0
  50. package/apps/client-cms-editor/shared/cms/src/cloudflare-bindings.ts +51 -0
  51. package/apps/client-cms-editor/shared/cms/src/editor-types.ts +58 -0
  52. package/apps/client-cms-editor/shared/cms/src/index.ts +5 -0
  53. package/apps/client-cms-editor/shared/cms/src/publication.ts +24 -0
  54. package/apps/client-cms-editor/shared/cms/src/routes.ts +11 -0
  55. package/apps/client-cms-editor/shared/cms/tsconfig.json +12 -0
  56. package/bin/agentsam-rapid-rust +36 -0
  57. package/docs/AUTH_IDENTITY_CONTRACT.md +2 -0
  58. package/docs/MACHINE_INTELLIGENCE.md +120 -0
  59. package/docs/WINDOWS_RUNTIME_INSTALL.md +30 -0
  60. package/docs/architecture/AGENTSAM_APPLICATION_CONTRACT.md +188 -0
  61. package/docs/architecture/AGENTSAM_RUNTIME_PROTOCOL.md +151 -0
  62. package/docs/architecture/LOCAL_STUDIO_CLOUDFLARE_OAUTH.md +12 -4
  63. package/docs/architecture/R2_SLUG_NAMESPACE.md +20 -0
  64. package/docs/architecture/WORK_PRODUCT_EXTRACTION.md +97 -0
  65. package/docs/brand/AGENT_SAM_ICON_GRAMMAR.md +70 -0
  66. package/docs/content-studio/HOST_MOUNT_CHECKLIST.md +71 -0
  67. package/docs/content-studio/REVISION_GATE_2026-09-27.md +501 -0
  68. package/docs/contracts/capability-install-planner.md +67 -0
  69. package/docs/contracts/environment-vocabulary.md +195 -0
  70. package/docs/contracts/google-cloud-oauth-setup.md +199 -0
  71. package/docs/local-studio/WORKMODE_DONOR_NOTES.md +1 -1
  72. package/docs/plans/LOCAL-STUDIO-GRADUATION-2026-09-26.md +290 -0
  73. package/docs/plans/LOCAL-STUDIO-REAL-APP-CONTRACT-ADDENDUM-2026-09-27.md +394 -0
  74. package/docs/plans/MACHINE-FIRST-APPS-TUI-2026-09-24.md +227 -0
  75. package/docs/plans/TOMORROW-EXTENSIVE-TODO-2026-09-26.md +221 -0
  76. package/docs/plans/TOMORROW-MACHINE-FIRST-BRIEFING.md +145 -0
  77. package/docs/plans/UNIVERSAL-INGEST-MACHINE-FIRST-2026-09-24.md +215 -0
  78. package/docs/plugins.md +2 -2
  79. package/docs/product/AGENTSAM_PRODUCT_EXPERIENCE_STANDARD.md +280 -0
  80. package/docs/product/LOCAL_STUDIO_DESKTOP_EXPERIENCE.md +139 -0
  81. package/docs/product/README.md +8 -0
  82. package/docs/rapid-rust-wasm.md +35 -0
  83. package/migrations/d1/0016_cloudflare_oauth_user_oauth_tokens_ssot.sql +14 -0
  84. package/package.json +73 -14
  85. package/packages/agentsam-brand/README.md +106 -11
  86. package/packages/agentsam-brand/bin/agentsam-brand.mjs +9 -0
  87. package/packages/agentsam-brand/package.json +39 -7
  88. package/packages/agentsam-brand/src/adapters/cloudflare-images.js +453 -0
  89. package/packages/agentsam-brand/src/adapters/cloudflare-r2.js +74 -0
  90. package/packages/agentsam-brand/src/adapters/d1-registry.js +26 -0
  91. package/packages/agentsam-brand/src/adapters/filesystem.js +59 -0
  92. package/packages/agentsam-brand/src/adapters/memory.js +31 -0
  93. package/packages/agentsam-brand/src/cli/controller.js +503 -0
  94. package/packages/agentsam-brand/src/cli/wizard.js +526 -0
  95. package/packages/agentsam-brand/src/core/capabilities.js +201 -0
  96. package/packages/agentsam-brand/src/core/derivatives.js +211 -0
  97. package/packages/agentsam-brand/src/core/errors.js +12 -0
  98. package/packages/agentsam-brand/src/core/ingest.js +195 -0
  99. package/packages/agentsam-brand/src/core/inspect.js +109 -0
  100. package/packages/agentsam-brand/src/core/keys.js +83 -0
  101. package/packages/agentsam-brand/src/core/naming.js +142 -0
  102. package/packages/agentsam-brand/src/core/optimize.js +316 -0
  103. package/packages/agentsam-brand/src/core/pack.js +305 -0
  104. package/packages/agentsam-brand/src/core/plan.js +276 -0
  105. package/packages/agentsam-brand/src/core/preview.js +159 -0
  106. package/packages/agentsam-brand/src/core/processors/cloudflare.js +68 -0
  107. package/packages/agentsam-brand/src/core/processors/contract.js +203 -0
  108. package/packages/agentsam-brand/src/core/processors/index.js +148 -0
  109. package/packages/agentsam-brand/src/core/processors/native.js +82 -0
  110. package/packages/agentsam-brand/src/core/processors/sharp.js +113 -0
  111. package/packages/agentsam-brand/src/core/processors/squoosh-binary.js +195 -0
  112. package/packages/agentsam-brand/src/core/promote.js +288 -0
  113. package/packages/agentsam-brand/src/core/receipts.js +155 -0
  114. package/packages/agentsam-brand/src/core/v2/compile.js +280 -0
  115. package/packages/agentsam-brand/src/core/v2/derivatives-semantic.js +207 -0
  116. package/packages/agentsam-brand/src/core/v2/ingest-graph.js +387 -0
  117. package/packages/agentsam-brand/src/core/v2/roles.js +180 -0
  118. package/packages/agentsam-brand/src/core/v2/schema.js +209 -0
  119. package/packages/agentsam-brand/src/core/v2/templates.js +114 -0
  120. package/packages/agentsam-brand/src/index.js +193 -36
  121. package/packages/agentsam-brand/src/presets/app-icon.json +16 -0
  122. package/packages/agentsam-brand/src/presets/favicon.json +17 -0
  123. package/packages/agentsam-brand/src/presets/hero.json +12 -0
  124. package/packages/agentsam-brand/src/presets/index.js +40 -0
  125. package/packages/agentsam-brand/src/presets/logo.json +12 -0
  126. package/packages/agentsam-brand/src/presets/model.json +8 -0
  127. package/packages/agentsam-brand/src/presets/og-image.json +10 -0
  128. package/packages/agentsam-brand/src/presets/product-shot.json +11 -0
  129. package/packages/agentsam-brand/src/presets/social-image.json +10 -0
  130. package/packages/agentsam-brand/src/presets/web-image.json +10 -0
  131. package/packages/agentsam-contracts/src/artifacts.ts +41 -0
  132. package/packages/agentsam-knowledge/src/autorag/index.js +1 -1
  133. package/packages/agentsam-knowledge/src/providers/index.js +6 -4
  134. package/packages/agentsam-knowledge/src/providers/ollama-endpoint.js +31 -0
  135. package/packages/agentsam-knowledge/test/autorag.test.mjs +22 -1
  136. package/packages/agentsam-nav/package.json +2 -2
  137. package/packages/agentsam-rapid-rust/Cargo.lock +344 -0
  138. package/packages/agentsam-rapid-rust/Cargo.toml +18 -0
  139. package/packages/agentsam-rapid-rust/README.md +5 -0
  140. package/packages/agentsam-rapid-rust/src/main.rs +718 -0
  141. package/packages/agentsam-rapid-rust/templates/api/Cargo.toml.tmpl +18 -0
  142. package/packages/agentsam-rapid-rust/templates/api/src/lib.rs.tmpl +17 -0
  143. package/packages/agentsam-rapid-rust/templates/common/README.md.tmpl +22 -0
  144. package/packages/agentsam-rapid-rust/templates/common/package.json.tmpl +12 -0
  145. package/packages/agentsam-rapid-rust/templates/common/wrangler.toml.tmpl +6 -0
  146. package/packages/agentsam-rapid-rust/templates/crypto-auth/Cargo.toml.tmpl +21 -0
  147. package/packages/agentsam-rapid-rust/templates/crypto-auth/src/lib.rs.tmpl +32 -0
  148. package/packages/agentsam-rapid-rust/templates/data-processor/Cargo.toml.tmpl +18 -0
  149. package/packages/agentsam-rapid-rust/templates/data-processor/src/lib.rs.tmpl +41 -0
  150. package/packages/agentsam-rapid-rust/templates/shared-core/Cargo.toml.tmpl +9 -0
  151. package/packages/agentsam-rapid-rust/templates/shared-core/core/Cargo.toml.tmpl +7 -0
  152. package/packages/agentsam-rapid-rust/templates/shared-core/core/src/lib.rs.tmpl +23 -0
  153. package/packages/agentsam-rapid-rust/templates/shared-core/worker/Cargo.toml.tmpl +12 -0
  154. package/packages/agentsam-rapid-rust/templates/shared-core/worker/src/lib.rs.tmpl +16 -0
  155. package/packages/agentsam-rapid-rust/templates/shared-core/wrangler.toml.tmpl +6 -0
  156. package/packages/agentsam-repository/src/index.js +1 -0
  157. package/packages/agentsam-repository/src/merkle/semantic.js +3 -10
  158. package/packages/agentsam-repository/src/source-types.js +85 -0
  159. package/packages/agentsam-vault/README.md +96 -0
  160. package/packages/agentsam-vault/package.json +32 -0
  161. package/packages/agentsam-vault/src/contracts/credential.d.ts +78 -0
  162. package/packages/agentsam-vault/src/contracts/credential.js +132 -0
  163. package/packages/agentsam-vault/src/crypto/aes-gcm.d.ts +30 -0
  164. package/packages/agentsam-vault/src/crypto/aes-gcm.js +107 -0
  165. package/packages/agentsam-vault/src/crypto/oauth-envelope.js +150 -0
  166. package/packages/agentsam-vault/src/index.d.ts +9 -0
  167. package/packages/agentsam-vault/src/index.js +27 -0
  168. package/packages/agentsam-vault/src/providers/registry.js +90 -0
  169. package/packages/agentsam-vault/src/runtime/resolver.js +77 -0
  170. package/packages/agentsam-workbench/README.md +24 -0
  171. package/packages/agentsam-workbench/package.json +38 -0
  172. package/packages/agentsam-workbench/src/agent/AgentPanel.tsx +41 -0
  173. package/packages/agentsam-workbench/src/agent/ArtifactCard.tsx +9 -0
  174. package/packages/agentsam-workbench/src/agent/Composer.tsx +102 -0
  175. package/packages/agentsam-workbench/src/agent/ConnectedAgentPanel.tsx +194 -0
  176. package/packages/agentsam-workbench/src/agent/ContextualComposer.tsx +788 -0
  177. package/packages/agentsam-workbench/src/agent/GoalStatusStrip.tsx +38 -0
  178. package/packages/agentsam-workbench/src/agent/MiniAgentSam.tsx +86 -0
  179. package/packages/agentsam-workbench/src/agent/ModelSelect.tsx +19 -0
  180. package/packages/agentsam-workbench/src/agent/Thread.tsx +56 -0
  181. package/packages/agentsam-workbench/src/agent/ToolReceipt.tsx +11 -0
  182. package/packages/agentsam-workbench/src/agent/contextual-composer.css +611 -0
  183. package/packages/agentsam-workbench/src/agent/index.ts +10 -0
  184. package/packages/agentsam-workbench/src/agent/mini-agentsam.css +12 -0
  185. package/packages/agentsam-workbench/src/browser/BrowserFrame.tsx +37 -0
  186. package/packages/agentsam-workbench/src/browser/index.ts +1 -0
  187. package/packages/agentsam-workbench/src/index.ts +6 -0
  188. package/packages/agentsam-workbench/src/project-control.css +160 -0
  189. package/packages/agentsam-workbench/src/projects/ProjectsSurface.tsx +131 -0
  190. package/packages/agentsam-workbench/src/projects/index.ts +1 -0
  191. package/packages/agentsam-workbench/src/shell/Breadcrumb.tsx +35 -0
  192. package/packages/agentsam-workbench/src/shell/ResizableStage.tsx +99 -0
  193. package/packages/agentsam-workbench/src/shell/SidePanel.tsx +5 -0
  194. package/packages/agentsam-workbench/src/shell/index.ts +4 -0
  195. package/packages/agentsam-workbench/src/shell/surfaceRegistry.ts +29 -0
  196. package/packages/agentsam-workbench/src/terminal/TerminalSurface.tsx +5 -0
  197. package/packages/agentsam-workbench/src/terminal/index.ts +1 -0
  198. package/packages/agentsam-workbench/src/timeline/GanttBoard.tsx +258 -0
  199. package/packages/agentsam-workbench/src/timeline/index.ts +1 -0
  200. package/packages/agentsam-workbench/tsconfig.json +13 -0
  201. package/packages/connectors/cloudflare/OAUTH_STORAGE_AUDIT.md +53 -0
  202. package/packages/connectors/cloudflare/package.json +3 -1
  203. package/packages/connectors/cloudflare/src/api-client.js +279 -0
  204. package/packages/connectors/cloudflare/src/capabilities.js +585 -0
  205. package/packages/connectors/cloudflare/src/credential.js +318 -0
  206. package/packages/connectors/cloudflare/src/families/brand-protection.js +123 -0
  207. package/packages/connectors/cloudflare/src/families/keyless.js +114 -0
  208. package/packages/connectors/cloudflare/src/families/pages.js +151 -0
  209. package/packages/connectors/cloudflare/src/families/scanner.js +123 -0
  210. package/packages/connectors/cloudflare/src/families/snippets.js +207 -0
  211. package/packages/connectors/cloudflare/src/families/tag-gateway.js +46 -0
  212. package/packages/connectors/cloudflare/src/families/tags.js +124 -0
  213. package/packages/connectors/cloudflare/src/families/token-validation.js +95 -0
  214. package/packages/connectors/cloudflare/src/families/workflows.js +156 -0
  215. package/packages/connectors/cloudflare/src/index.js +102 -265
  216. package/packages/connectors/cloudflare/src/oauth-persist.js +336 -0
  217. package/packages/connectors/cloudflare/src/owner.js +42 -12
  218. package/packages/connectors/cloudflare/src/permission-options.js +1064 -0
  219. package/packages/connectors/cloudflare/src/routes.js +309 -144
  220. package/packages/connectors/cloudflare/src/scope-catalog.js +345 -0
  221. package/packages/connectors/cloudflare/src/vault.js +2 -2
  222. package/packages/connectors/cloudflare/tests/capabilities.test.mjs +276 -0
  223. package/packages/connectors/cloudflare/tests/connector.test.mjs +26 -30
  224. package/packages/connectors/cloudflare/tests/oauth-persist.test.mjs +125 -0
  225. package/packages/identity/.agentsam/features/oauth-login-portal/providers.json +22 -2
  226. package/packages/identity/.agentsam/features/oauth-login-portal/resources.json +10 -4
  227. package/packages/identity/.agentsam/features/oauth-login-portal/routes.json +20 -0
  228. package/packages/identity/README.md +1 -1
  229. package/packages/identity/backend/README.md +1 -1
  230. package/packages/identity/migrations/D1_SCHEMA_MAPPING.md +3 -2
  231. package/packages/identity/migrations/sqlite/004_identity_oauth_consent_catalog.sql +48 -0
  232. package/packages/identity/package.json +4 -3
  233. package/packages/identity/scripts/local-identity-bridge.mjs +184 -0
  234. package/packages/identity/scripts/preview-auth-portal.mjs +7 -7
  235. package/packages/identity/src/adapters/cloudflare-d1/index.js +31 -2
  236. package/packages/identity/src/adapters/sqlite/index.js +4 -1
  237. package/packages/identity/src/contracts/auth-config.js +28 -8
  238. package/packages/identity/src/contracts/external-identity.js +1 -1
  239. package/packages/identity/src/contracts/provider.js +1 -0
  240. package/packages/identity/src/frontend/auth-portal/README.md +2 -1
  241. package/packages/identity/src/frontend/auth-portal/pages/login.html +6 -5
  242. package/packages/identity/src/frontend/auth-portal/pages/reset.html +6 -5
  243. package/packages/identity/src/frontend/auth-portal/pages/signup.html +6 -5
  244. package/packages/identity/src/frontend/auth-portal/shared/company-branding.js +1 -1
  245. package/packages/identity/src/frontend/auth-portal/shared/desktop-identity-bridge.js +207 -0
  246. package/packages/identity/src/index.js +16 -0
  247. package/packages/identity/src/migrations/0001_identity_core.sql +19 -2
  248. package/packages/identity/src/migrations/0003_accounts_ssot.sql +20 -0
  249. package/packages/identity/src/migrations/README.md +5 -2
  250. package/packages/identity/src/oauth/README.md +10 -5
  251. package/packages/identity/src/oauth/consent-view.js +388 -0
  252. package/packages/identity/src/oauth/credentials.js +31 -11
  253. package/packages/identity/src/oauth/google-desktop-exchange.js +173 -0
  254. package/packages/identity/src/providers/cloudflare/oauth.js +3 -4
  255. package/packages/identity/src/providers/cloudflare/profile.js +49 -14
  256. package/packages/identity/src/providers/iam/index.js +27 -5
  257. package/packages/identity/src/server/identity-service.js +31 -2
  258. package/packages/identity/src/server/worker-router.js +111 -81
  259. package/packages/identity/tests/auth-config.test.mjs +3 -2
  260. package/packages/identity/tests/identity-init-scaffold.test.mjs +3 -0
  261. package/packages/identity/tests/identity-service.test.mjs +16 -0
  262. package/packages/identity/tests/native-session-worker.test.mjs +64 -0
  263. package/packages/identity/tests/oauth-consent-view.test.mjs +106 -0
  264. package/packages/identity/tests/oauth-credentials.test.mjs +17 -4
  265. package/packages/identity/tests/oauth-presets-accounts-ssot.test.mjs +58 -0
  266. package/packages/identity/tests/preview-auth-portal.test.mjs +3 -3
  267. package/packages/runtime-protocol/src/index.js +154 -0
  268. package/packages/theme-scenes/README.md +164 -0
  269. package/packages/theme-scenes/package.json +53 -0
  270. package/packages/theme-scenes/src/blocks/index.js +30 -0
  271. package/packages/theme-scenes/src/contracts/index.js +286 -0
  272. package/packages/theme-scenes/src/demos/index.js +65 -0
  273. package/packages/theme-scenes/src/index.js +75 -0
  274. package/packages/theme-scenes/src/presets/index.js +263 -0
  275. package/packages/theme-scenes/src/runtime/compile.js +119 -0
  276. package/packages/theme-scenes/src/scenes/index.js +146 -0
  277. package/packages/theme-scenes/src/shell/index.js +47 -0
  278. package/packages/theme-scenes/src/themes/index.js +129 -0
  279. package/packages/theme-scenes/src/visuals/index.js +41 -0
  280. package/packages/theme-scenes/test/theme-scenes.test.mjs +179 -0
  281. package/packages/work-graph/src/index.js +34 -1
  282. package/packages/work-graph/src/renderers/gantt-model.js +24 -0
  283. package/packages/work-graph/test/work-graph.test.mjs +27 -7
  284. package/protocol/README.md +15 -7
  285. package/protocol/apps/agentsam.app.v1.schema.json +89 -7
  286. package/protocol/apps/agentsam.host-install.v1.schema.json +36 -0
  287. package/protocol/assets/README.md +9 -0
  288. package/protocol/assets/asset-record.v1.schema.json +64 -0
  289. package/protocol/runtime/agentsam.runtime.v1.schema.json +75 -0
  290. package/protocol/scoring/README.md +10 -0
  291. package/protocol/scoring/scorecard.v1.schema.json +65 -0
  292. package/protocol/ui/icon-registry.mjs +1 -0
  293. package/registry/cms-rust-machine-20260928/installable-products.json +31 -0
  294. package/registry/cms-rust-machine-20260928/manifest.json +22 -0
  295. package/registry/cms-rust-machine-20260928/migration.sql +237 -0
  296. package/registry/cms-rust-machine-20260928/receipt.json +21 -0
  297. package/registry/cms-rust-machine-20260928/receipt.sql +27 -0
  298. package/scripts/build_rapid_rust_cli.py +83 -0
  299. package/src/attachments/index.js +6 -0
  300. package/src/attachments/intake.js +235 -0
  301. package/src/capabilities/repository-snapshot.js +19 -2
  302. package/src/cli/command-catalog.js +8 -0
  303. package/src/cli.js +182 -26
  304. package/src/commands/account-auth.js +94 -8
  305. package/src/commands/app.js +307 -3
  306. package/src/commands/billing.js +127 -0
  307. package/src/commands/brand.js +74 -60
  308. package/src/commands/cheat-sheet.js +154 -0
  309. package/src/commands/cloudflare-login.js +222 -0
  310. package/src/commands/cloudflare.js +453 -23
  311. package/src/commands/codebaseindex.js +6 -1
  312. package/src/commands/compute.js +4 -0
  313. package/src/commands/connections.js +11 -5
  314. package/src/commands/credentials.js +116 -0
  315. package/src/commands/gcloud-auth.js +427 -0
  316. package/src/commands/google-cloud.js +375 -0
  317. package/src/commands/identity-init.js +2 -2
  318. package/src/commands/mcp.js +226 -33
  319. package/src/commands/ollama.js +3 -2
  320. package/src/commands/plugins.js +7 -2
  321. package/src/commands/product.js +36 -0
  322. package/src/commands/runtime-status.js +28 -9
  323. package/src/commands/runtime.js +313 -0
  324. package/src/commands/rust.js +24 -0
  325. package/src/commands/setup.js +279 -0
  326. package/src/commands/shell.js +16 -3
  327. package/src/commands/start-local.js +2 -2
  328. package/src/commands/terminal.js +171 -0
  329. package/src/commands/update.js +140 -0
  330. package/src/commands/whoami.js +329 -65
  331. package/src/features/resolve.js +1 -0
  332. package/src/index.js +4 -0
  333. package/src/indexing/ingest/inventory.js +254 -19
  334. package/src/indexing/ingest/materials.js +3 -9
  335. package/src/indexing/ingest/style-evidence.js +181 -0
  336. package/src/knowledge/source.js +3 -3
  337. package/src/lib/account-session.js +11 -4
  338. package/src/lib/app-authority.js +172 -0
  339. package/src/lib/auth.js +94 -21
  340. package/src/lib/core-client.js +5 -6
  341. package/src/lib/credentials-audit.js +451 -0
  342. package/src/lib/deploy/health.js +24 -6
  343. package/src/lib/detect-context.js +7 -1
  344. package/src/lib/google-cloud-connection.js +270 -0
  345. package/src/lib/google-cloud-inventory.js +385 -0
  346. package/src/lib/google-desktop-oauth.js +372 -0
  347. package/src/lib/google-studio-brokered-oauth.js +158 -0
  348. package/src/lib/identity-scaffold.js +24 -6
  349. package/src/lib/init-options.js +192 -0
  350. package/src/lib/local-scaffold.js +48 -16
  351. package/src/lib/provider-command-remediation.js +308 -0
  352. package/src/lib/provider-credentials.js +8 -0
  353. package/src/lib/scaffold/index.js +8 -2
  354. package/src/lib/scaffold/mcp-server.js +43 -0
  355. package/src/lib/scaffold/templates/mcp-server/index.js +397 -0
  356. package/src/lib/scaffold/templates/mcp-server/presets.js +39 -0
  357. package/src/lib/scaffold/wizards/cms.js +93 -0
  358. package/src/lib/scaffold/wizards/mcp-server.js +61 -0
  359. package/src/lib/setup/contract.js +26 -0
  360. package/src/lib/setup/discover.js +116 -0
  361. package/src/lib/setup/execute.js +205 -0
  362. package/src/lib/setup/planner.js +134 -0
  363. package/src/lib/setup/recipes.js +235 -0
  364. package/src/lib/setup/runtime-persist.js +197 -0
  365. package/src/lib/setup/runtime.js +394 -0
  366. package/src/lib/slash-commands.js +2 -0
  367. package/src/lib/terminal/machine-identity.js +95 -0
  368. package/src/lib/terminal-local.js +164 -0
  369. package/src/lib/terminal-scopes.js +52 -0
  370. package/src/lib/whoami-capabilities.js +184 -0
  371. package/src/local-pty/server.js +34 -5
  372. package/src/mcp/authority.js +58 -108
  373. package/src/mcp/client-adapters.js +68 -144
  374. package/src/mcp/client.js +142 -122
  375. package/src/mcp/cloudflare-bundles.js +225 -0
  376. package/src/mcp/index.js +12 -0
  377. package/src/plugins/cloudflare.js +1 -1
  378. package/src/providers/ollama-chat.js +2 -1
  379. package/src/sam/types.js +27 -2
  380. package/src/security/inventory.js +12 -2
  381. package/src/security/local-vault.js +2 -0
  382. package/src/security/scan.js +1 -1
  383. package/test/account-session.test.mjs +3 -3
  384. package/test/app-authority-context.test.mjs +32 -0
  385. package/test/cli/codebaseindex-plan-ux.test.mjs +1 -1
  386. package/test/cli/mcp-client.test.mjs +21 -10
  387. package/test/cli/runtime-persist.test.mjs +56 -0
  388. package/test/cli/rust-command.test.mjs +21 -0
  389. package/test/credentials-audit.test.mjs +113 -0
  390. package/test/deploy-health-scan.test.mjs +29 -1
  391. package/test/gcloud-auth.test.mjs +111 -0
  392. package/test/google-cloud-connection.test.mjs +83 -0
  393. package/test/google-cloud-inventory.test.mjs +64 -0
  394. package/test/init-options.test.mjs +35 -0
  395. package/test/integration/app-command.test.mjs +30 -0
  396. package/test/integration/cad-project.test.mjs +4 -1
  397. package/test/integration/cms-app-scaffold.test.mjs +71 -0
  398. package/test/integration/cms-site-tenancy-contract.test.mjs +3 -2
  399. package/test/integration/codebaseindex-ingest.test.mjs +48 -0
  400. package/test/integration/features-resolve.test.mjs +30 -11
  401. package/test/integration/inspect-path-cli.test.mjs +46 -0
  402. package/test/integration/inventory-evidence.test.mjs +125 -0
  403. package/test/integration/runtime-status.integration.test.mjs +2 -1
  404. package/test/knowledge.test.mjs +35 -1
  405. package/test/loopback-oauth.test.mjs +53 -0
  406. package/test/ollama.test.mjs +22 -0
  407. package/test/security.test.mjs +23 -0
  408. package/test/setup-planner.test.mjs +74 -0
  409. package/test/setup-runtime.test.mjs +51 -0
  410. package/test/terminal/local-pty.mock.test.mjs +3 -1
  411. package/test/terminal-machine-identity.test.mjs +88 -0
  412. package/test/whoami-resume.test.mjs +27 -6
  413. package/packages/agentsam-brand/test/brand-scan.test.mjs +0 -106
  414. package/packages/work-graph/prototype/README.md +0 -32
  415. package/packages/work-graph/prototype/data/demo-workgraph.js +0 -47
  416. package/packages/work-graph/prototype/renderers/timeline-model.js +0 -21
  417. package/packages/work-graph/prototype/renderers/workgraph-runtime.js +0 -38
  418. package/packages/work-graph/prototype-gnantt.html +0 -655
@@ -0,0 +1,151 @@
1
+ /** Cloudflare Pages — /accounts/{id}/pages/projects/... */
2
+ import { receipt } from '../api-client.js';
3
+
4
+ const CAP = 'cloudflare.pages';
5
+
6
+ export async function pagesStatus(client) {
7
+ client.requireAccount('pages.status');
8
+ try {
9
+ const res = await client.request('GET', client.accountPath('/pages/projects'), {
10
+ capabilityId: CAP,
11
+ operation: 'pages.list',
12
+ query: { per_page: 1 },
13
+ });
14
+ return receipt(CAP, 'status', {
15
+ ok: true,
16
+ availability: 'available',
17
+ authorized: true,
18
+ account_id: client.accountId,
19
+ auth: client.authMeta(),
20
+ project_sample: Array.isArray(res.result) ? res.result.length : null,
21
+ });
22
+ } catch (err) {
23
+ if (err.code === 'cloudflare_permission_denied') {
24
+ return receipt(CAP, 'status', { ok: false, authorized: false, ...err.toJSON() });
25
+ }
26
+ throw err;
27
+ }
28
+ }
29
+
30
+ export async function pagesList(client, query = {}) {
31
+ client.requireAccount('pages.list');
32
+ const res = await client.request('GET', client.accountPath('/pages/projects'), {
33
+ capabilityId: CAP,
34
+ operation: 'pages.list',
35
+ query,
36
+ });
37
+ return receipt(CAP, 'list', {
38
+ ok: true,
39
+ projects: res.result || [],
40
+ result_info: res.result_info,
41
+ auth: client.authMeta(),
42
+ });
43
+ }
44
+
45
+ export async function pagesInspect(client, projectName) {
46
+ client.requireAccount('pages.inspect');
47
+ const res = await client.request('GET', client.accountPath(`/pages/projects/${encodeURIComponent(projectName)}`), {
48
+ capabilityId: CAP,
49
+ operation: 'pages.inspect',
50
+ });
51
+ return receipt(CAP, 'inspect', { ok: true, project: res.result, auth: client.authMeta() });
52
+ }
53
+
54
+ export async function pagesDeployments(client, projectName, query = {}) {
55
+ client.requireAccount('pages.deployments');
56
+ const res = await client.request(
57
+ 'GET',
58
+ client.accountPath(`/pages/projects/${encodeURIComponent(projectName)}/deployments`),
59
+ { capabilityId: CAP, operation: 'pages.deployments', query },
60
+ );
61
+ return receipt(CAP, 'deployments', {
62
+ ok: true,
63
+ project: projectName,
64
+ deployments: res.result || [],
65
+ result_info: res.result_info,
66
+ });
67
+ }
68
+
69
+ export async function pagesDeployment(client, projectName, deploymentId) {
70
+ client.requireAccount('pages.deployment');
71
+ const res = await client.request(
72
+ 'GET',
73
+ client.accountPath(
74
+ `/pages/projects/${encodeURIComponent(projectName)}/deployments/${encodeURIComponent(deploymentId)}`,
75
+ ),
76
+ { capabilityId: CAP, operation: 'pages.deployment' },
77
+ );
78
+ return receipt(CAP, 'deployment', { ok: true, project: projectName, deployment: res.result });
79
+ }
80
+
81
+ export async function pagesDeploymentLogs(client, projectName, deploymentId) {
82
+ client.requireAccount('pages.logs');
83
+ const res = await client.request(
84
+ 'GET',
85
+ client.accountPath(
86
+ `/pages/projects/${encodeURIComponent(projectName)}/deployments/${encodeURIComponent(deploymentId)}/history/logs`,
87
+ ),
88
+ { capabilityId: CAP, operation: 'pages.logs' },
89
+ );
90
+ return receipt(CAP, 'logs', { ok: true, project: projectName, deployment_id: deploymentId, logs: res.result });
91
+ }
92
+
93
+ export async function pagesDomains(client, projectName) {
94
+ client.requireAccount('pages.domains');
95
+ const res = await client.request(
96
+ 'GET',
97
+ client.accountPath(`/pages/projects/${encodeURIComponent(projectName)}/domains`),
98
+ { capabilityId: CAP, operation: 'pages.domains' },
99
+ );
100
+ return receipt(CAP, 'domains', { ok: true, project: projectName, domains: res.result || [] });
101
+ }
102
+
103
+ export async function pagesUploadToken(client, projectName) {
104
+ client.requireAccount('pages.upload_token');
105
+ const res = await client.request(
106
+ 'GET',
107
+ client.accountPath(`/pages/projects/${encodeURIComponent(projectName)}/upload-token`),
108
+ { capabilityId: CAP, operation: 'pages.upload_token' },
109
+ );
110
+ // JWT is short-lived operational secret — do not echo in human receipts by default
111
+ return receipt(CAP, 'upload_token', {
112
+ ok: true,
113
+ project: projectName,
114
+ has_jwt: Boolean(res.result?.jwt),
115
+ // Only include jwt when caller opts in via client flag later; omit by default
116
+ });
117
+ }
118
+
119
+ export async function pagesPurgeBuildCache(client, projectName) {
120
+ client.requireAccount('pages.purge');
121
+ const res = await client.request(
122
+ 'POST',
123
+ client.accountPath(`/pages/projects/${encodeURIComponent(projectName)}/purge_build_cache`),
124
+ { capabilityId: CAP, operation: 'pages.purge_build_cache' },
125
+ );
126
+ return receipt(CAP, 'purge_build_cache', { ok: true, project: projectName, result: res.result });
127
+ }
128
+
129
+ export async function pagesRetryDeployment(client, projectName, deploymentId) {
130
+ client.requireAccount('pages.retry');
131
+ const res = await client.request(
132
+ 'POST',
133
+ client.accountPath(
134
+ `/pages/projects/${encodeURIComponent(projectName)}/deployments/${encodeURIComponent(deploymentId)}/retry`,
135
+ ),
136
+ { capabilityId: CAP, operation: 'pages.retry' },
137
+ );
138
+ return receipt(CAP, 'retry', { ok: true, project: projectName, deployment: res.result });
139
+ }
140
+
141
+ export async function pagesRollbackDeployment(client, projectName, deploymentId) {
142
+ client.requireAccount('pages.rollback');
143
+ const res = await client.request(
144
+ 'POST',
145
+ client.accountPath(
146
+ `/pages/projects/${encodeURIComponent(projectName)}/deployments/${encodeURIComponent(deploymentId)}/rollback`,
147
+ ),
148
+ { capabilityId: CAP, operation: 'pages.rollback' },
149
+ );
150
+ return receipt(CAP, 'rollback', { ok: true, project: projectName, deployment: res.result });
151
+ }
@@ -0,0 +1,123 @@
1
+ /** Cloudflare URL Scanner v2 — real API. */
2
+ import { receipt } from '../api-client.js';
3
+
4
+ const CAP = 'cloudflare.url_scanner';
5
+
6
+ export async function scannerStatus(client) {
7
+ client.requireAccount('scanner.status');
8
+ try {
9
+ // Lightweight authorized probe: empty search
10
+ await client.request('GET', client.accountPath('/urlscanner/v2/search'), {
11
+ capabilityId: CAP,
12
+ operation: 'scanner.search',
13
+ query: { q: 'page.domain:example.com', size: 1 },
14
+ });
15
+ return receipt(CAP, 'status', {
16
+ ok: true,
17
+ availability: 'available',
18
+ authorized: true,
19
+ account_id: client.accountId,
20
+ permission: 'Account → URL Scanner → Edit',
21
+ });
22
+ } catch (err) {
23
+ if (err.code === 'cloudflare_permission_denied') {
24
+ return receipt(CAP, 'status', {
25
+ ok: false,
26
+ availability: 'available',
27
+ authorized: false,
28
+ ...err.toJSON(),
29
+ });
30
+ }
31
+ // Search may 400 on query — still proves auth if not 401/403
32
+ if (err.httpStatus && err.httpStatus !== 401 && err.httpStatus !== 403) {
33
+ return receipt(CAP, 'status', {
34
+ ok: true,
35
+ availability: 'available',
36
+ authorized: true,
37
+ account_id: client.accountId,
38
+ note: 'probe_non_auth_error',
39
+ });
40
+ }
41
+ throw err;
42
+ }
43
+ }
44
+
45
+ export async function scannerScan(client, url, options = {}) {
46
+ client.requireAccount('scanner.scan');
47
+ const body = { url, ...options };
48
+ const res = await client.request('POST', client.accountPath('/urlscanner/v2/scan'), {
49
+ capabilityId: CAP,
50
+ operation: 'scanner.scan',
51
+ body,
52
+ });
53
+ return receipt(CAP, 'scan', { ok: true, scan: res.result });
54
+ }
55
+
56
+ export async function scannerBulk(client, urls = []) {
57
+ client.requireAccount('scanner.bulk');
58
+ const body = (urls || []).map((u) => (typeof u === 'string' ? { url: u } : u));
59
+ const res = await client.request('POST', client.accountPath('/urlscanner/v2/bulk'), {
60
+ capabilityId: CAP,
61
+ operation: 'scanner.bulk',
62
+ body,
63
+ });
64
+ return receipt(CAP, 'bulk', { ok: true, scans: res.result });
65
+ }
66
+
67
+ export async function scannerResult(client, scanId) {
68
+ client.requireAccount('scanner.result');
69
+ const res = await client.request('GET', client.accountPath(`/urlscanner/v2/result/${encodeURIComponent(scanId)}`), {
70
+ capabilityId: CAP,
71
+ operation: 'scanner.result',
72
+ });
73
+ return receipt(CAP, 'result', { ok: true, scan_id: scanId, result: res.result });
74
+ }
75
+
76
+ export async function scannerSearch(client, query = {}) {
77
+ client.requireAccount('scanner.search');
78
+ const res = await client.request('GET', client.accountPath('/urlscanner/v2/search'), {
79
+ capabilityId: CAP,
80
+ operation: 'scanner.search',
81
+ query,
82
+ });
83
+ return receipt(CAP, 'search', { ok: true, results: res.result, result_info: res.result_info });
84
+ }
85
+
86
+ export async function scannerHar(client, scanId) {
87
+ client.requireAccount('scanner.har');
88
+ const res = await client.request('GET', client.accountPath(`/urlscanner/v2/har/${encodeURIComponent(scanId)}`), {
89
+ capabilityId: CAP,
90
+ operation: 'scanner.har',
91
+ });
92
+ return receipt(CAP, 'har', { ok: true, scan_id: scanId, har: res.result });
93
+ }
94
+
95
+ export async function scannerDom(client, scanId) {
96
+ client.requireAccount('scanner.dom');
97
+ const res = await client.request('GET', client.accountPath(`/urlscanner/v2/dom/${encodeURIComponent(scanId)}`), {
98
+ capabilityId: CAP,
99
+ operation: 'scanner.dom',
100
+ raw: true,
101
+ });
102
+ return receipt(CAP, 'dom', {
103
+ ok: true,
104
+ scan_id: scanId,
105
+ dom: Buffer.isBuffer(res.body) ? res.body.toString('utf8') : res.body,
106
+ });
107
+ }
108
+
109
+ export async function scannerScreenshot(client, scanId) {
110
+ client.requireAccount('scanner.screenshot');
111
+ const res = await client.request(
112
+ 'GET',
113
+ client.accountPath(`/urlscanner/v2/screenshots/${encodeURIComponent(scanId)}.png`),
114
+ { capabilityId: CAP, operation: 'scanner.screenshot', raw: true },
115
+ );
116
+ return receipt(CAP, 'screenshot', {
117
+ ok: true,
118
+ scan_id: scanId,
119
+ content_type: 'image/png',
120
+ bytes: res.body?.length || 0,
121
+ png_base64: Buffer.isBuffer(res.body) ? res.body.toString('base64') : null,
122
+ });
123
+ }
@@ -0,0 +1,207 @@
1
+ /**
2
+ * Cloudflare Snippets — zone-scoped tiny edge logic.
3
+ *
4
+ * CRITICAL: PUT /snippets/snippet_rules replaces the zone's entire rules collection.
5
+ * Always: read → reconcile (preserve foreign rules) → plan → approve → PUT → verify.
6
+ *
7
+ * OAuth scope: Cloudflare documents Snippets Read/Write as API permissions.
8
+ * Scope string is NOT invented here — if oauthScopes is empty, capability is token_required
9
+ * until the OAuth app catalog exposes a verified identifier.
10
+ */
11
+ import { receipt } from '../api-client.js';
12
+ import crypto from 'node:crypto';
13
+
14
+ const CAP = 'cloudflare.snippets';
15
+ const AGENTSAM_RULE_PREFIX = '[AgentSam]';
16
+
17
+ function hashText(value) {
18
+ return crypto.createHash('sha256').update(String(value || '')).digest('hex').slice(0, 16);
19
+ }
20
+
21
+ export async function snippetsStatus(client, zoneId) {
22
+ try {
23
+ const res = await client.request('GET', client.zonePath(zoneId, '/snippets'), {
24
+ capabilityId: CAP,
25
+ operation: 'snippets.list',
26
+ });
27
+ return receipt(CAP, 'status', {
28
+ ok: true,
29
+ availability: 'available',
30
+ authorized: true,
31
+ zone_id: zoneId,
32
+ snippet_count: Array.isArray(res.result) ? res.result.length : null,
33
+ auth: client.authMeta(),
34
+ limits_note: 'Snippets: ~5ms CPU, 2MB memory, 32KB package; Pro+; proxied DNS required.',
35
+ });
36
+ } catch (err) {
37
+ if (err.code === 'cloudflare_permission_denied') {
38
+ return receipt(CAP, 'status', {
39
+ ok: false,
40
+ zone_id: zoneId,
41
+ authorized: false,
42
+ status: 'token_required_or_unauthorized',
43
+ permission: 'Snippets Read / Snippets Write',
44
+ note: 'OAuth scope string not assumed — use CLOUDFLARE_API_TOKEN with Snippets Write if OAuth catalog lacks it.',
45
+ ...err.toJSON(),
46
+ });
47
+ }
48
+ if (err.httpStatus === 404 || /plan|not.?entitled|pro/i.test(err.message)) {
49
+ return receipt(CAP, 'status', {
50
+ ok: false,
51
+ availability: 'unavailable_on_plan',
52
+ zone_id: zoneId,
53
+ message: err.message,
54
+ learn: 'Cloudflare → Rules → Snippets (Pro / Business / Enterprise)',
55
+ });
56
+ }
57
+ throw err;
58
+ }
59
+ }
60
+
61
+ export async function snippetsList(client, zoneId) {
62
+ const res = await client.request('GET', client.zonePath(zoneId, '/snippets'), {
63
+ capabilityId: CAP,
64
+ operation: 'snippets.list',
65
+ });
66
+ return receipt(CAP, 'list', { ok: true, zone_id: zoneId, snippets: res.result || [] });
67
+ }
68
+
69
+ export async function snippetsInspect(client, zoneId, name) {
70
+ const res = await client.request('GET', client.zonePath(zoneId, `/snippets/${encodeURIComponent(name)}`), {
71
+ capabilityId: CAP,
72
+ operation: 'snippets.inspect',
73
+ });
74
+ return receipt(CAP, 'inspect', { ok: true, zone_id: zoneId, snippet: res.result });
75
+ }
76
+
77
+ export async function snippetsContent(client, zoneId, name) {
78
+ const res = await client.request(
79
+ 'GET',
80
+ client.zonePath(zoneId, `/snippets/${encodeURIComponent(name)}/content`),
81
+ { capabilityId: CAP, operation: 'snippets.content', raw: true },
82
+ );
83
+ const text = Buffer.isBuffer(res.body) ? res.body.toString('utf8') : String(res.body || '');
84
+ return receipt(CAP, 'content', {
85
+ ok: true,
86
+ zone_id: zoneId,
87
+ snippet_name: name,
88
+ content_sha256_16: hashText(text),
89
+ bytes: text.length,
90
+ // Include content only in structured result for tooling — still redacted from default human format
91
+ content: text,
92
+ });
93
+ }
94
+
95
+ export async function snippetsPut(client, zoneId, name, body, { yes = false } = {}) {
96
+ if (!yes) {
97
+ return receipt(CAP, 'plan', {
98
+ ok: true,
99
+ planned: true,
100
+ zone_id: zoneId,
101
+ snippet_name: name,
102
+ operation: 'PUT /snippets/{name}',
103
+ note: 'Pass --yes to apply. Re-fetch after apply for verification.',
104
+ body_preview: typeof body === 'string' ? { content_sha256_16: hashText(body) } : body,
105
+ });
106
+ }
107
+ const res = await client.request('PUT', client.zonePath(zoneId, `/snippets/${encodeURIComponent(name)}`), {
108
+ capabilityId: CAP,
109
+ operation: 'snippets.put',
110
+ body,
111
+ });
112
+ const verify = await snippetsInspect(client, zoneId, name);
113
+ return receipt(CAP, 'apply', {
114
+ ok: true,
115
+ zone_id: zoneId,
116
+ snippet_name: name,
117
+ result: res.result,
118
+ verification: verify.snippet || null,
119
+ auth: client.authMeta(),
120
+ });
121
+ }
122
+
123
+ export async function snippetsDelete(client, zoneId, name, { yes = false } = {}) {
124
+ if (!yes) {
125
+ return receipt(CAP, 'plan', {
126
+ ok: true,
127
+ planned: true,
128
+ zone_id: zoneId,
129
+ snippet_name: name,
130
+ operation: 'DELETE',
131
+ });
132
+ }
133
+ const res = await client.request('DELETE', client.zonePath(zoneId, `/snippets/${encodeURIComponent(name)}`), {
134
+ capabilityId: CAP,
135
+ operation: 'snippets.delete',
136
+ });
137
+ return receipt(CAP, 'delete', { ok: true, zone_id: zoneId, snippet_name: name, result: res.result });
138
+ }
139
+
140
+ export async function snippetsRulesList(client, zoneId) {
141
+ const res = await client.request('GET', client.zonePath(zoneId, '/snippets/snippet_rules'), {
142
+ capabilityId: CAP,
143
+ operation: 'snippets.rules.list',
144
+ });
145
+ return receipt(CAP, 'rules.list', { ok: true, zone_id: zoneId, rules: res.result || [] });
146
+ }
147
+
148
+ /**
149
+ * Plan a rules collection write that PRESERVES non-AgentSam rules.
150
+ * desiredRules: AgentSam-owned rules to upsert (matched by description prefix + snippet name).
151
+ */
152
+ export function reconcileSnippetRules(existingRules = [], desiredAgentSamRules = []) {
153
+ const foreign = (existingRules || []).filter((r) => {
154
+ const desc = String(r.description || r.rule?.description || '');
155
+ return !desc.startsWith(AGENTSAM_RULE_PREFIX);
156
+ });
157
+ const owned = (desiredAgentSamRules || []).map((r) => ({
158
+ ...r,
159
+ description: String(r.description || '').startsWith(AGENTSAM_RULE_PREFIX)
160
+ ? r.description
161
+ : `${AGENTSAM_RULE_PREFIX} ${r.description || r.snippet || 'edge'}`.trim(),
162
+ }));
163
+ const next = [...foreign, ...owned];
164
+ return {
165
+ existing_count: (existingRules || []).length,
166
+ foreign_preserved: foreign.length,
167
+ agentsam_rules: owned.length,
168
+ next_count: next.length,
169
+ rules: next,
170
+ dropped_agentsam_replaced: (existingRules || []).length - foreign.length,
171
+ };
172
+ }
173
+
174
+ export async function snippetsRulesPlan(client, zoneId, desiredAgentSamRules = []) {
175
+ const current = await snippetsRulesList(client, zoneId);
176
+ const plan = reconcileSnippetRules(current.rules, desiredAgentSamRules);
177
+ return receipt(CAP, 'rules.plan', {
178
+ ok: true,
179
+ zone_id: zoneId,
180
+ planned: true,
181
+ ...plan,
182
+ warning: 'PUT replaces the entire snippet_rules collection — foreign rules are preserved by reconcile.',
183
+ });
184
+ }
185
+
186
+ export async function snippetsRulesApply(client, zoneId, desiredAgentSamRules = [], { yes = false } = {}) {
187
+ const plan = await snippetsRulesPlan(client, zoneId, desiredAgentSamRules);
188
+ if (!yes) return plan;
189
+ const res = await client.request('PUT', client.zonePath(zoneId, '/snippets/snippet_rules'), {
190
+ capabilityId: CAP,
191
+ operation: 'snippets.rules.apply',
192
+ body: { rules: plan.rules },
193
+ });
194
+ const after = await snippetsRulesList(client, zoneId);
195
+ return receipt(CAP, 'rules.apply', {
196
+ ok: true,
197
+ zone_id: zoneId,
198
+ result: res.result,
199
+ before_count: plan.existing_count,
200
+ after_count: (after.rules || []).length,
201
+ foreign_preserved: plan.foreign_preserved,
202
+ verification: after.rules,
203
+ auth: client.authMeta(),
204
+ });
205
+ }
206
+
207
+ export { AGENTSAM_RULE_PREFIX };
@@ -0,0 +1,46 @@
1
+ /** Google Tag Gateway — zone setting API. */
2
+ import { receipt } from '../api-client.js';
3
+
4
+ const CAP = 'cloudflare.tag_gateway';
5
+
6
+ export async function tagGatewayStatus(client, zoneId) {
7
+ const res = await client.request('GET', client.zonePath(zoneId, '/settings/google-tag-gateway/config'), {
8
+ capabilityId: CAP,
9
+ operation: 'tag_gateway.status',
10
+ });
11
+ return receipt(CAP, 'status', {
12
+ ok: true,
13
+ zone_id: zoneId,
14
+ config: res.result,
15
+ availability: 'available',
16
+ });
17
+ }
18
+
19
+ export async function tagGatewayConfigure(client, zoneId, config = {}) {
20
+ const body = {
21
+ enabled: config.enabled !== false,
22
+ measurementId: config.measurementId || config.measurement_id,
23
+ endpoint: config.endpoint || '/metrics',
24
+ hideOriginalIp: config.hideOriginalIp ?? config.hide_original_ip ?? true,
25
+ setUpTag: config.setUpTag ?? config.set_up_tag ?? true,
26
+ };
27
+ const res = await client.request('PUT', client.zonePath(zoneId, '/settings/google-tag-gateway/config'), {
28
+ capabilityId: CAP,
29
+ operation: 'tag_gateway.configure',
30
+ body,
31
+ });
32
+ return receipt(CAP, 'configure', { ok: true, zone_id: zoneId, config: res.result });
33
+ }
34
+
35
+ export async function tagGatewayDisable(client, zoneId) {
36
+ const current = await tagGatewayStatus(client, zoneId);
37
+ const prev = current.config || {};
38
+ return tagGatewayConfigure(client, zoneId, {
39
+ ...prev,
40
+ enabled: false,
41
+ measurementId: prev.measurementId,
42
+ endpoint: prev.endpoint || '/metrics',
43
+ hideOriginalIp: prev.hideOriginalIp,
44
+ setUpTag: prev.setUpTag,
45
+ });
46
+ }
@@ -0,0 +1,124 @@
1
+ /** Cloudflare account resource tags — Enterprise tagging API. */
2
+ import { receipt } from '../api-client.js';
3
+
4
+ const CAP = 'cloudflare.resource_tags';
5
+
6
+ export async function tagsStatus(client) {
7
+ client.requireAccount('tags.status');
8
+ try {
9
+ await client.request('GET', client.accountPath('/tags/keys'), {
10
+ capabilityId: CAP,
11
+ operation: 'tags.keys',
12
+ });
13
+ return receipt(CAP, 'status', {
14
+ ok: true,
15
+ availability: 'available',
16
+ authorized: true,
17
+ plan_note: 'Account resource tagging is Enterprise (beta) per Cloudflare OpenAPI.',
18
+ account_id: client.accountId,
19
+ });
20
+ } catch (err) {
21
+ if (err.code === 'cloudflare_permission_denied' || err.httpStatus === 403) {
22
+ return receipt(CAP, 'status', {
23
+ ok: false,
24
+ availability: 'enterprise',
25
+ authorized: false,
26
+ ...err.toJSON(),
27
+ });
28
+ }
29
+ // 404 / plan errors
30
+ if (err.httpStatus === 404 || /enterprise|not.?entitled|not.?found/i.test(err.message)) {
31
+ return receipt(CAP, 'status', {
32
+ ok: false,
33
+ availability: 'unavailable',
34
+ authorized: false,
35
+ plan: 'enterprise_required',
36
+ message: err.message,
37
+ learn: 'Cloudflare → Account → Resource Tagging (Enterprise)',
38
+ });
39
+ }
40
+ throw err;
41
+ }
42
+ }
43
+
44
+ export async function tagsKeys(client) {
45
+ client.requireAccount('tags.keys');
46
+ const res = await client.request('GET', client.accountPath('/tags/keys'), {
47
+ capabilityId: CAP,
48
+ operation: 'tags.keys',
49
+ });
50
+ return receipt(CAP, 'keys', { ok: true, keys: res.result });
51
+ }
52
+
53
+ export async function tagsValues(client, tagKey) {
54
+ client.requireAccount('tags.values');
55
+ const res = await client.request('GET', client.accountPath(`/tags/values/${encodeURIComponent(tagKey)}`), {
56
+ capabilityId: CAP,
57
+ operation: 'tags.values',
58
+ });
59
+ return receipt(CAP, 'values', { ok: true, key: tagKey, values: res.result });
60
+ }
61
+
62
+ export async function tagsSummary(client) {
63
+ client.requireAccount('tags.summary');
64
+ const res = await client.request('GET', client.accountPath('/tags/summary'), {
65
+ capabilityId: CAP,
66
+ operation: 'tags.summary',
67
+ });
68
+ return receipt(CAP, 'summary', { ok: true, summary: res.result });
69
+ }
70
+
71
+ export async function tagsResources(client, query = {}) {
72
+ client.requireAccount('tags.resources');
73
+ const res = await client.request('GET', client.accountPath('/tags/resources'), {
74
+ capabilityId: CAP,
75
+ operation: 'tags.resources',
76
+ query,
77
+ });
78
+ return receipt(CAP, 'resources', { ok: true, resources: res.result, result_info: res.result_info });
79
+ }
80
+
81
+ export async function tagsGet(client, resource) {
82
+ client.requireAccount('tags.get');
83
+ const res = await client.request('GET', client.accountPath('/tags'), {
84
+ capabilityId: CAP,
85
+ operation: 'tags.get',
86
+ query: { resource },
87
+ });
88
+ return receipt(CAP, 'list', { ok: true, resource, tags: res.result });
89
+ }
90
+
91
+ export async function tagsPut(client, body, { ifMatch } = {}) {
92
+ client.requireAccount('tags.put');
93
+ const headersQuery = {};
94
+ // If-Match is a header — pass via custom request
95
+ const res = await client.request('PUT', client.accountPath('/tags'), {
96
+ capabilityId: CAP,
97
+ operation: 'tags.set',
98
+ body,
99
+ });
100
+ void ifMatch;
101
+ void headersQuery;
102
+ return receipt(CAP, 'set', { ok: true, result: res.result });
103
+ }
104
+
105
+ export async function tagsDelete(client, body) {
106
+ client.requireAccount('tags.delete');
107
+ const res = await client.request('DELETE', client.accountPath('/tags'), {
108
+ capabilityId: CAP,
109
+ operation: 'tags.delete',
110
+ body,
111
+ });
112
+ return receipt(CAP, 'delete', { ok: true, result: res.result ?? null, http_status: res.http_status });
113
+ }
114
+
115
+ /** AgentSam-owned tag vocabulary (provider-native keys). */
116
+ export const AGENTSAM_TAG_VOCABULARY = Object.freeze([
117
+ 'agentsam.product',
118
+ 'agentsam.system',
119
+ 'agentsam.environment',
120
+ 'agentsam.lifecycle',
121
+ 'agentsam.repository',
122
+ 'agentsam.runtime',
123
+ 'customer',
124
+ ]);