@inneranimalmedia/agentsam-sdk 2.6.1 → 2.6.3

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 (507) hide show
  1. package/AGENTSAM.md +45 -1
  2. package/README.md +80 -0
  3. package/apps/README.md +34 -0
  4. package/apps/cad-creator/README.md +728 -0
  5. package/apps/cad-creator/shared/cad/package.json +19 -0
  6. package/apps/cad-creator/shared/cad/src/domain/operations.ts +7 -0
  7. package/apps/cad-creator/shared/cad/src/domain/project-contract.d.ts +3 -0
  8. package/apps/cad-creator/shared/cad/src/domain/project-contract.js +75 -0
  9. package/apps/cad-creator/shared/cad/src/domain/project-tools.d.ts +1 -0
  10. package/apps/cad-creator/shared/cad/src/domain/project-tools.js +24 -0
  11. package/apps/cad-creator/shared/cad/src/domain/validation.ts +191 -0
  12. package/apps/cad-creator/shared/cad/src/index.ts +4 -0
  13. package/apps/cad-creator/shared/cad/src/robotics/types.ts +232 -0
  14. package/apps/cad-creator/shared/cad/src/types.ts +507 -0
  15. package/apps/cad-creator/shared/cad/tsconfig.json +14 -0
  16. package/docs/AUTH_IDENTITY_CONTRACT.md +25 -27
  17. package/docs/AUTORAG.md +58 -0
  18. package/docs/BRAND_INTELLIGENCE.md +30 -0
  19. package/docs/CLI_SHELL.md +4 -2
  20. package/docs/CMS_CONTEXTUAL_COMPOSER.md +38 -0
  21. package/docs/MERKLE.md +4 -0
  22. package/docs/PROJECT_CONFIG.md +3 -0
  23. package/docs/REPOSITORY_KNOWLEDGE.md +2 -0
  24. package/docs/SDK_WORKER.md +4 -3
  25. package/docs/THEME_REFINERY.md +120 -0
  26. package/docs/architecture/PROVIDER-TOOLS-AND-COMPACTION.md +60 -0
  27. package/docs/architecture/STORAGE.md +87 -0
  28. package/docs/cad-project-tools.md +69 -0
  29. package/docs/cms-scaffolding-pattern-reference.md +73 -0
  30. package/docs/plans/AGENTSAM-INTERACTIVE-UI-REQUIREMENTS-codex-tui-20260919.md +113 -0
  31. package/docs/plans/AGENTSAM-INTERACTIVE-UI-REQUIREMENTS.md +85 -0
  32. package/docs/plans/AGENTSAM-MCP-CLIENT-2026-09-19.md +181 -0
  33. package/docs/plans/ASBD-PORTABLE-WORKGRAPH-UI-DEFERRED.md +34 -0
  34. package/docs/plans/ASTRA-BRIEF-2026-09-18.md +258 -0
  35. package/docs/plans/MULTI-AGENT-SPRINTS-2026-09-19.md +373 -0
  36. package/docs/plans/NEXT-AGENT-HANDOFF.md +167 -0
  37. package/docs/plans/RECONCILIATION-2026-09-19.md +178 -0
  38. package/docs/plugins.md +43 -0
  39. package/docs/tools/README.md +57 -0
  40. package/docs/tools/agent-and-orchestration.md +49 -0
  41. package/docs/tools/browser-and-research.md +46 -0
  42. package/docs/tools/cloudflare-platform.md +32 -0
  43. package/docs/tools/cms.md +25 -0
  44. package/docs/tools/communications.md +41 -0
  45. package/docs/tools/database-and-storage.md +62 -0
  46. package/docs/tools/design-and-media.md +64 -0
  47. package/docs/tools/filesystem-and-code.md +55 -0
  48. package/docs/tools/github.md +56 -0
  49. package/docs/tools/integrations-and-misc.md +16 -0
  50. package/docs/tools/memory.md +21 -0
  51. package/docs/tools/terminal-and-execution.md +29 -0
  52. package/docs/tools/tickets-and-platform.md +30 -0
  53. package/migrations/d1/0001_agentsam_plugin_runtime.sql +177 -0
  54. package/migrations/d1/0002_agentsam_ticket_ownership.sql +8 -0
  55. package/migrations/d1/0002_dynamic_model_policies.sql +23 -0
  56. package/migrations/d1/0003_expand_tool_handler_families.sql +18 -0
  57. package/migrations/d1/0004_project_aware_retrieval_lanes.sql +24 -0
  58. package/migrations/d1/0005_portable_knowledge_identity.sql +104 -0
  59. package/migrations/d1/0006_repair_ops_trail_account_scope.sql +14 -0
  60. package/migrations/d1/0007_repair_ops_trail_agent_run_account.sql +13 -0
  61. package/migrations/d1/0008_backfill_knowledge_run_legacy_tenant.sql +14 -0
  62. package/migrations/d1/0009_normalize_cloudflare_plugin_installations.sql +137 -0
  63. package/migrations/runtime/0001_cli_runtime.sql +67 -0
  64. package/migrations/runtime/0002_project_sessions.sql +15 -0
  65. package/migrations/runtime/0003_provider_continuations.sql +8 -0
  66. package/package.json +92 -12
  67. package/packages/agentsam-brand/README.md +21 -0
  68. package/packages/agentsam-brand/package.json +22 -0
  69. package/packages/agentsam-brand/src/contract.js +59 -0
  70. package/packages/agentsam-brand/src/extract.js +126 -0
  71. package/packages/agentsam-brand/src/goap-actions.js +73 -0
  72. package/packages/agentsam-brand/src/index.js +48 -0
  73. package/packages/agentsam-brand/src/plan.js +115 -0
  74. package/packages/agentsam-brand/src/resolve.js +139 -0
  75. package/packages/agentsam-brand/src/scan.js +250 -0
  76. package/packages/agentsam-brand/test/brand-scan.test.mjs +106 -0
  77. package/packages/agentsam-contracts/README.md +23 -0
  78. package/packages/agentsam-contracts/package.json +32 -0
  79. package/packages/agentsam-contracts/src/adapter.ts +25 -0
  80. package/packages/agentsam-contracts/src/agent.ts +35 -0
  81. package/packages/agentsam-contracts/src/artifacts.ts +33 -0
  82. package/packages/agentsam-contracts/src/authority.ts +29 -0
  83. package/packages/agentsam-contracts/src/context.ts +16 -0
  84. package/packages/agentsam-contracts/src/errors.ts +46 -0
  85. package/packages/agentsam-contracts/src/events.ts +47 -0
  86. package/packages/agentsam-contracts/src/execution.ts +50 -0
  87. package/packages/agentsam-contracts/src/hooks.ts +40 -0
  88. package/packages/agentsam-contracts/src/identity.ts +16 -0
  89. package/packages/agentsam-contracts/src/index.ts +14 -0
  90. package/packages/agentsam-contracts/src/models.ts +9 -0
  91. package/packages/agentsam-contracts/src/providers.ts +33 -0
  92. package/packages/agentsam-contracts/src/repository.ts +64 -0
  93. package/packages/agentsam-contracts/src/tools.ts +98 -0
  94. package/packages/agentsam-contracts/test/contracts.test.mjs +16 -0
  95. package/packages/agentsam-contracts/test/errors-catalog.test.mjs +25 -0
  96. package/packages/agentsam-contracts/test/repository.test.mjs +18 -0
  97. package/packages/agentsam-contracts/tsconfig.json +12 -0
  98. package/packages/agentsam-errors/package.json +17 -0
  99. package/packages/agentsam-errors/src/adapters/anthropic.js +15 -0
  100. package/packages/agentsam-errors/src/adapters/cad.js +109 -0
  101. package/packages/agentsam-errors/src/adapters/cloudflare.js +21 -0
  102. package/packages/agentsam-errors/src/adapters/cursor.js +4 -0
  103. package/packages/agentsam-errors/src/adapters/device.js +38 -0
  104. package/packages/agentsam-errors/src/adapters/docker.js +28 -0
  105. package/packages/agentsam-errors/src/adapters/gcp.js +14 -0
  106. package/packages/agentsam-errors/src/adapters/github.js +22 -0
  107. package/packages/agentsam-errors/src/adapters/google.js +17 -0
  108. package/packages/agentsam-errors/src/adapters/index.js +55 -0
  109. package/packages/agentsam-errors/src/adapters/internal.js +40 -0
  110. package/packages/agentsam-errors/src/adapters/oauth.js +24 -0
  111. package/packages/agentsam-errors/src/adapters/openai.js +17 -0
  112. package/packages/agentsam-errors/src/adapters/process.js +35 -0
  113. package/packages/agentsam-errors/src/adapters/provider.js +114 -0
  114. package/packages/agentsam-errors/src/envelope.js +186 -0
  115. package/packages/agentsam-errors/src/error.js +24 -0
  116. package/packages/agentsam-errors/src/fingerprint.js +35 -0
  117. package/packages/agentsam-errors/src/index.js +10 -0
  118. package/packages/agentsam-errors/src/normalize.js +30 -0
  119. package/packages/agentsam-errors/src/redaction.js +52 -0
  120. package/packages/agentsam-errors/src/render.js +16 -0
  121. package/packages/agentsam-errors/src/retry.js +10 -0
  122. package/packages/agentsam-errors/src/transport.js +52 -0
  123. package/packages/agentsam-errors/src/vocabulary.js +320 -0
  124. package/packages/agentsam-errors/test/envelope.test.mjs +70 -0
  125. package/packages/agentsam-errors/test/providers.test.mjs +99 -0
  126. package/packages/agentsam-errors/test/redaction.test.mjs +21 -0
  127. package/packages/agentsam-errors/test/runtime-cad-device.test.mjs +76 -0
  128. package/packages/agentsam-errors/test/transport.test.mjs +46 -0
  129. package/packages/agentsam-knowledge/package.json +15 -0
  130. package/packages/agentsam-knowledge/src/autorag/index.js +64 -0
  131. package/packages/agentsam-knowledge/src/backends/index.js +26 -0
  132. package/packages/agentsam-knowledge/src/index.js +3 -0
  133. package/packages/agentsam-knowledge/src/providers/index.js +95 -0
  134. package/packages/agentsam-knowledge/test/autorag.test.mjs +42 -0
  135. package/packages/agentsam-nav/README.md +40 -0
  136. package/packages/agentsam-nav/dist/Nav.d.ts +43 -0
  137. package/packages/agentsam-nav/dist/NavCollapsible.d.ts +10 -0
  138. package/packages/agentsam-nav/dist/NavContent.d.ts +2 -0
  139. package/packages/agentsam-nav/dist/NavFooter.d.ts +2 -0
  140. package/packages/agentsam-nav/dist/NavGroup.d.ts +3 -0
  141. package/packages/agentsam-nav/dist/NavHeader.d.ts +2 -0
  142. package/packages/agentsam-nav/dist/NavMenu.d.ts +22 -0
  143. package/packages/agentsam-nav/dist/NavProvider.d.ts +35 -0
  144. package/packages/agentsam-nav/dist/NavTrigger.d.ts +2 -0
  145. package/packages/agentsam-nav/dist/Surfaces.d.ts +41 -0
  146. package/packages/agentsam-nav/dist/browser.d.ts +11 -0
  147. package/packages/agentsam-nav/dist/browser.global.js +132 -0
  148. package/packages/agentsam-nav/dist/browser.js +613 -0
  149. package/packages/agentsam-nav/dist/contracts.d.ts +76 -0
  150. package/packages/agentsam-nav/dist/index.d.ts +11 -0
  151. package/packages/agentsam-nav/dist/index.js +614 -0
  152. package/packages/agentsam-nav/dist/legacy.css +83 -0
  153. package/packages/agentsam-nav/dist/shell.css +113 -0
  154. package/packages/agentsam-nav/dist/theme.css +113 -0
  155. package/packages/agentsam-nav/dist/utils.d.ts +1 -0
  156. package/packages/agentsam-nav/package.json +43 -0
  157. package/packages/agentsam-queue-control/README.md +107 -0
  158. package/packages/agentsam-queue-control/package.json +31 -0
  159. package/packages/agentsam-queue-control/schemas/job-envelope.schema.json +56 -0
  160. package/packages/agentsam-queue-control/src/adapters/cloudflare.js +152 -0
  161. package/packages/agentsam-queue-control/src/adapters/memory.js +38 -0
  162. package/packages/agentsam-queue-control/src/contracts.js +130 -0
  163. package/packages/agentsam-queue-control/src/control-plane.js +141 -0
  164. package/packages/agentsam-queue-control/src/dispatch.js +43 -0
  165. package/packages/agentsam-queue-control/src/index.js +7 -0
  166. package/packages/agentsam-queue-control/src/policy.js +88 -0
  167. package/packages/agentsam-queue-control/src/topology.js +66 -0
  168. package/packages/agentsam-queue-control/test/queue-control.test.mjs +100 -0
  169. package/packages/agentsam-repository/src/goap.js +718 -0
  170. package/packages/agentsam-repository/src/goap.js.bak-20260922011251 +670 -0
  171. package/packages/agentsam-repository/src/index.js +5 -0
  172. package/packages/agentsam-repository/src/merkle/cloudflare-persistence.js +2 -2
  173. package/packages/agentsam-repository/src/tickets.js +184 -0
  174. package/packages/agentsam-repository/src/work-tracking.js +199 -0
  175. package/packages/agentsam-repository/src/workspace-state.js +176 -0
  176. package/packages/agentsam-repository/test/goap-tickets-workspace-state.test.mjs +152 -0
  177. package/packages/connectors/cloudflare/src/index.js +297 -15
  178. package/packages/connectors/cloudflare/src/owner.js +43 -40
  179. package/packages/connectors/cloudflare/src/routes.js +167 -26
  180. package/packages/connectors/cloudflare/tests/connector.test.mjs +112 -2
  181. package/packages/heuristic-theme/README.md +11 -0
  182. package/packages/heuristic-theme/package.json +25 -0
  183. package/packages/heuristic-theme/src/index.js +2 -0
  184. package/packages/heuristic-theme/src/registry.js +36 -0
  185. package/packages/heuristic-theme/src/theme.js +41 -0
  186. package/packages/heuristic-theme/test/theme.test.mjs +26 -0
  187. package/packages/identity/.agentsam/features/oauth-login-portal/agentsam.feature.json +64 -0
  188. package/packages/identity/.agentsam/features/oauth-login-portal/providers.json +96 -0
  189. package/packages/identity/.agentsam/features/oauth-login-portal/resources.json +47 -0
  190. package/packages/identity/.agentsam/features/oauth-login-portal/routes.json +74 -0
  191. package/packages/identity/.agentsam/features/oauth-login-portal/ui.json +35 -0
  192. package/packages/identity/package.json +4 -3
  193. package/packages/identity/src/adapters/cloudflare-d1/ids.js +4 -0
  194. package/packages/identity/src/adapters/cloudflare-d1/index.js +39 -1
  195. package/packages/identity/src/contracts/auth-config.js +23 -40
  196. package/packages/identity/src/contracts/provider.js +3 -2
  197. package/packages/identity/src/frontend/auth-portal/pages/login.html +7 -0
  198. package/packages/identity/src/index.js +2 -0
  199. package/packages/identity/src/oauth/credentials.js +13 -0
  200. package/packages/identity/src/oauth/iam-platform.js +5 -5
  201. package/packages/identity/src/providers/cloudflare/index.js +19 -0
  202. package/packages/identity/src/providers/cloudflare/mapper.js +21 -0
  203. package/packages/identity/src/providers/cloudflare/oauth.js +48 -0
  204. package/packages/identity/src/providers/cloudflare/profile.js +28 -0
  205. package/packages/identity/src/providers/index.js +18 -2
  206. package/packages/identity/src/server/identity-service.js +13 -3
  207. package/packages/identity/src/server/worker-router.js +63 -8
  208. package/packages/identity/tests/auth-config.test.mjs +14 -23
  209. package/packages/identity/tests/identity-service.test.mjs +15 -0
  210. package/packages/providers/completeful/README.md +38 -0
  211. package/packages/providers/completeful/package.json +29 -0
  212. package/packages/providers/completeful/src/client.js +162 -0
  213. package/packages/providers/completeful/src/events.js +49 -0
  214. package/packages/providers/completeful/src/index.js +22 -0
  215. package/packages/providers/completeful/src/tools.js +579 -0
  216. package/packages/providers/completeful/src/webhooks.js +55 -0
  217. package/packages/providers/completeful/test/provider.test.mjs +196 -0
  218. package/packages/theme-church-site/README.md +10 -0
  219. package/packages/theme-church-site/package.json +30 -0
  220. package/packages/theme-church-site/src/harvest.json +14 -0
  221. package/packages/theme-church-site/src/index.js +84 -0
  222. package/packages/theme-church-site/test/theme.test.mjs +19 -0
  223. package/packages/theme-companions-site/README.md +10 -0
  224. package/packages/theme-companions-site/package.json +30 -0
  225. package/packages/theme-companions-site/src/harvest.json +12 -0
  226. package/packages/theme-companions-site/src/index.js +82 -0
  227. package/packages/theme-companions-site/test/theme.test.mjs +19 -0
  228. package/packages/theme-floors-site/README.md +10 -0
  229. package/packages/theme-floors-site/package.json +30 -0
  230. package/packages/theme-floors-site/src/harvest.json +14 -0
  231. package/packages/theme-floors-site/src/index.js +82 -0
  232. package/packages/theme-floors-site/test/theme.test.mjs +19 -0
  233. package/packages/theme-fuelnfree-site/README.md +10 -0
  234. package/packages/theme-fuelnfree-site/package.json +30 -0
  235. package/packages/theme-fuelnfree-site/src/harvest.json +13 -0
  236. package/packages/theme-fuelnfree-site/src/index.js +81 -0
  237. package/packages/theme-fuelnfree-site/test/theme.test.mjs +19 -0
  238. package/packages/theme-handyman-site/README.md +10 -0
  239. package/packages/theme-handyman-site/package.json +30 -0
  240. package/packages/theme-handyman-site/src/harvest.json +10 -0
  241. package/packages/theme-handyman-site/src/index.js +83 -0
  242. package/packages/theme-handyman-site/test/theme.test.mjs +19 -0
  243. package/packages/theme-insurance-site/README.md +10 -0
  244. package/packages/theme-insurance-site/package.json +30 -0
  245. package/packages/theme-insurance-site/src/harvest.json +10 -0
  246. package/packages/theme-insurance-site/src/index.js +83 -0
  247. package/packages/theme-insurance-site/test/theme.test.mjs +19 -0
  248. package/packages/theme-shinshu-site/README.md +10 -0
  249. package/packages/theme-shinshu-site/package.json +30 -0
  250. package/packages/theme-shinshu-site/src/harvest.json +12 -0
  251. package/packages/theme-shinshu-site/src/index.js +83 -0
  252. package/packages/theme-shinshu-site/test/theme.test.mjs +19 -0
  253. package/packages/work-graph/README.md +49 -0
  254. package/packages/work-graph/package.json +19 -0
  255. package/packages/work-graph/prototype/README.md +32 -0
  256. package/packages/work-graph/prototype/data/demo-workgraph.js +47 -0
  257. package/packages/work-graph/prototype/renderers/timeline-model.js +21 -0
  258. package/packages/work-graph/prototype/renderers/workgraph-runtime.js +38 -0
  259. package/packages/work-graph/prototype-gnantt.html +655 -0
  260. package/packages/work-graph/src/adapters/business/projects.js +23 -0
  261. package/packages/work-graph/src/adapters/engineering/git.js +22 -0
  262. package/packages/work-graph/src/adapters/engineering/mcp.js +22 -0
  263. package/packages/work-graph/src/index.js +76 -0
  264. package/packages/work-graph/src/renderers/gantt-model.js +11 -0
  265. package/packages/work-graph/src/renderers/timeline.js +16 -0
  266. package/packages/work-graph/test/work-graph.test.mjs +37 -0
  267. package/protocol/README.md +12 -0
  268. package/protocol/capabilities/cloudflare-cpu-audit-input.schema.json +30 -6
  269. package/protocol/capabilities/cloudflare-cpu-profile-input.schema.json +18 -4
  270. package/protocol/capabilities/cloudflare-wrangler-native-input.schema.json +59 -10
  271. package/protocol/capabilities/knowledge-search-input.schema.json +35 -0
  272. package/protocol/capabilities/manifest.json +163 -1
  273. package/protocol/capabilities/repository-audit-input.schema.json +39 -6
  274. package/protocol/capabilities/repository-snapshot-input.schema.json +15 -3
  275. package/protocol/capabilities/terminal-exec-input.schema.json +55 -0
  276. package/protocol/commerce/catalog.v1.json +50 -0
  277. package/protocol/errors/error-catalog.json +164 -0
  278. package/protocol/errors/error-envelope.schema.json +544 -0
  279. package/protocol/features/README.md +57 -0
  280. package/protocol/features/agentsam.feature.v1.schema.json +290 -0
  281. package/protocol/features/catalog.json +65 -0
  282. package/protocol/features/examples/provider-resend.feature.json +17 -0
  283. package/protocol/go/agentsam-go-runtime.v1.json +17 -0
  284. package/protocol/knowledge/LIFECYCLE.md +140 -0
  285. package/protocol/knowledge/README.md +4 -0
  286. package/protocol/presets/catalog.json +128 -19
  287. package/protocol/rpc/v1/errors.proto +24 -0
  288. package/protocol/theme-refinery/d1-reconciliation.md +48 -0
  289. package/protocol/theme-refinery/product-metadata.schema.json +27 -0
  290. package/protocol/theme-refinery/receipts/products-registry-batch-20260924.json +318 -0
  291. package/protocol/theme-refinery/receipts/theme-harvest-20260924.json +472 -0
  292. package/protocol/theme-refinery/reconciliation-receipt.schema.json +83 -0
  293. package/services/cad/server.py +249 -2
  294. package/src/agent/capability-adapter.js +15 -5
  295. package/src/agent/index.js +2 -1
  296. package/src/agent/model-turn.js +51 -0
  297. package/src/agent/responses-runner.js +304 -38
  298. package/src/capabilities/index.js +1 -0
  299. package/src/capabilities/terminal-exec.js +78 -0
  300. package/src/cli.js +129 -31
  301. package/src/cloudflare/index.js +6 -0
  302. package/src/cloudflare/runtime-status.js +393 -0
  303. package/src/cloudflare/wrangler.js +17 -1
  304. package/src/commands/account-auth.js +1 -1
  305. package/src/commands/app.js +106 -0
  306. package/src/commands/autorag.js +77 -0
  307. package/src/commands/brand.js +293 -0
  308. package/src/commands/cad.js +1 -0
  309. package/src/commands/connections.js +126 -29
  310. package/src/commands/context-economics.js +8 -0
  311. package/src/commands/db.js +7 -0
  312. package/src/commands/deploy.js +2 -2
  313. package/src/commands/env.js +5 -4
  314. package/src/commands/eval.js +209 -14
  315. package/src/commands/go.js +365 -0
  316. package/src/commands/goap.js +176 -0
  317. package/src/commands/identity-init.js +27 -3
  318. package/src/commands/identity-protocol.js +195 -0
  319. package/src/commands/knowledge.js +64 -5
  320. package/src/commands/mcp.js +341 -0
  321. package/src/commands/merkle-persist.js +3 -1
  322. package/src/commands/merkle.js +18 -3
  323. package/src/commands/models.js +109 -23
  324. package/src/commands/plugins.js +175 -0
  325. package/src/commands/preferences.js +28 -8
  326. package/src/commands/product.js +53 -10
  327. package/src/commands/providers.js +389 -0
  328. package/src/commands/resume.js +9 -5
  329. package/src/commands/runtime-status.js +154 -0
  330. package/src/commands/shell.js +469 -54
  331. package/src/commands/status.js +82 -7
  332. package/src/commands/tunnel.js +228 -195
  333. package/src/commands/whoami.js +115 -22
  334. package/src/context/budget.js +6 -0
  335. package/src/context/index.js +2 -1
  336. package/src/context/project-card.js +75 -0
  337. package/src/errors/contract.js +34 -211
  338. package/src/errors/diagnostic.js +95 -50
  339. package/src/errors/index.js +6 -13
  340. package/src/eval/index.js +6 -0
  341. package/src/eval/live.js +439 -0
  342. package/src/features/resolve.js +242 -0
  343. package/src/go/build.js +108 -0
  344. package/src/go/cloudflare.js +207 -0
  345. package/src/go/contract.js +139 -0
  346. package/src/go/discover.js +96 -0
  347. package/src/go/index.js +13 -0
  348. package/src/go/receipts.js +77 -0
  349. package/src/go/registry.js +223 -0
  350. package/src/go/verify.js +31 -0
  351. package/src/index.js +100 -1
  352. package/src/knowledge/config.js +13 -5
  353. package/src/knowledge/engine.js +23 -8
  354. package/src/knowledge/index.js +1 -0
  355. package/src/knowledge/lane-registry.js +46 -0
  356. package/src/knowledge/providers/gemini.js +48 -8
  357. package/src/knowledge/service/client.js +13 -1
  358. package/src/knowledge/service/grpc-codec.js +156 -53
  359. package/src/knowledge/service/job-engine.js +133 -11
  360. package/src/knowledge/service/job-worker.js +34 -5
  361. package/src/knowledge/service/server.js +10 -1
  362. package/src/knowledge/store-discovery.js +77 -0
  363. package/src/lib/account-session.js +100 -25
  364. package/src/lib/agent-instructions.js +3 -0
  365. package/src/lib/auth.js +318 -51
  366. package/src/lib/cad/blender.js +42 -3
  367. package/src/lib/cad/d1-project-store.js +43 -0
  368. package/src/lib/cad/discovery.js +616 -0
  369. package/src/lib/cad/docker-executor.js +352 -0
  370. package/src/lib/cad/freecad.js +253 -0
  371. package/src/lib/cad/index.js +40 -0
  372. package/src/lib/cad/openscad.js +198 -0
  373. package/src/lib/cad/project-cli.d.ts +2 -0
  374. package/src/lib/cad/project-cli.js +21 -0
  375. package/src/lib/cad/project-contract.d.ts +3 -0
  376. package/src/lib/cad/project-contract.js +1 -0
  377. package/src/lib/cad/project-recipe.js +30 -0
  378. package/src/lib/cad/project-runtime.d.ts +2 -0
  379. package/src/lib/cad/project-runtime.js +53 -0
  380. package/src/lib/cad/project-store.js +25 -0
  381. package/src/lib/cad/project-workflows.js +31 -0
  382. package/src/lib/cad-docker.js +21 -2
  383. package/src/lib/cli-preferences.js +17 -2
  384. package/src/lib/core-client.js +97 -33
  385. package/src/lib/deploy/local-studio.js +6 -5
  386. package/src/lib/detect-context.js +14 -16
  387. package/src/lib/dockerize.js +3 -0
  388. package/src/lib/execution-approvals.js +1 -0
  389. package/src/lib/identity-scaffold.js +4 -1
  390. package/src/lib/knowledge-docker.js +9 -1
  391. package/src/lib/local-sessions.js +124 -34
  392. package/src/lib/local-status.js +35 -14
  393. package/src/lib/project-config.js +9 -0
  394. package/src/lib/provider-credentials.js +233 -55
  395. package/src/lib/scaffold/resolve-cloudflare-account.js +37 -0
  396. package/src/lib/scaffold/wizards/cms.js +2 -8
  397. package/src/lib/scaffold/wizards/worker-api.js +2 -8
  398. package/src/lib/slash-commands.js +10 -2
  399. package/src/local/migrations.js +109 -1
  400. package/src/local/runtime-store.js +31 -5
  401. package/src/local/sqlite.js +36 -1
  402. package/src/mcp/authority.js +348 -0
  403. package/src/mcp/client-adapters.js +431 -0
  404. package/src/mcp/client.js +172 -0
  405. package/src/mcp/index.js +47 -0
  406. package/src/mcp/telemetry.js +103 -0
  407. package/src/models/catalog.js +329 -51
  408. package/src/models/discovery.js +59 -4
  409. package/src/models/index.js +2 -0
  410. package/src/models/inventory-core.js +182 -0
  411. package/src/models/policy.js +20 -0
  412. package/src/plugins/cloudflare.js +103 -0
  413. package/src/plugins/completeful.js +69 -0
  414. package/src/plugins/contracts.js +86 -0
  415. package/src/plugins/index.js +11 -0
  416. package/src/plugins/registry.js +207 -0
  417. package/src/plugins/resource-scope.js +45 -0
  418. package/src/plugins/runtime.js +118 -0
  419. package/src/plugins/vectorize.js +31 -0
  420. package/src/progression/engine.js +171 -0
  421. package/src/progression/index.js +1 -0
  422. package/src/providers/cloudflare-chat.js +1 -1
  423. package/src/providers/gemini-generate-content.js +2 -1
  424. package/src/providers/openai-responses.js +45 -16
  425. package/src/providers/tool-schema.js +85 -0
  426. package/src/repository/index.js +29 -0
  427. package/src/rpc/generated/errors_pb.js +961 -1
  428. package/src/security/local-vault.js +415 -0
  429. package/src/security/process.js +20 -4
  430. package/src/status/actions.js +192 -0
  431. package/src/tools/hydrate.js +5 -1
  432. package/src/tools/index.js +7 -0
  433. package/src/tools/redact.js +64 -0
  434. package/src/tools/registry.js +83 -0
  435. package/src/tools/runtime.js +257 -0
  436. package/src/tools/search.js +21 -8
  437. package/src/ui/ansi.js +117 -3
  438. package/src/ui/cli/activity.js +76 -7
  439. package/src/ui/cli/footer.js +110 -9
  440. package/src/ui/cli/help.js +14 -5
  441. package/src/ui/wireframes.js +166 -0
  442. package/test/account-session.test.mjs +76 -11
  443. package/test/apps-scaffold-contract.test.mjs +58 -0
  444. package/test/capabilities.test.mjs +1 -1
  445. package/test/cli/eval-live.test.mjs +219 -0
  446. package/test/cli/go.test.mjs +71 -0
  447. package/test/cli/local-vault-and-provider-setup.test.mjs +268 -0
  448. package/test/cli/mcp-client.test.mjs +245 -0
  449. package/test/cli/runtime-ui.test.mjs +69 -2
  450. package/test/cli/status-actions.test.mjs +88 -0
  451. package/test/cli/wireframes-go-registry.test.mjs +54 -0
  452. package/test/cloudflare-connector.test.mjs +3 -6
  453. package/test/cloudflare-runtime.test.mjs +8 -1
  454. package/test/context.test.mjs +15 -0
  455. package/test/error-diagnostics.test.mjs +9 -0
  456. package/test/fixtures/cad/courtyard-house.json +208 -0
  457. package/test/go/cloudflare-probe.test.mjs +53 -0
  458. package/test/integration/app-command.test.mjs +55 -0
  459. package/test/integration/cad-discovery.test.mjs +158 -0
  460. package/test/integration/cad-docker-executor.test.mjs +249 -0
  461. package/test/integration/cad-execution.test.mjs +184 -0
  462. package/test/integration/cad-project-app.test.mjs +31 -0
  463. package/test/integration/cad-project-d1.test.mjs +25 -0
  464. package/test/integration/cad-project-native.test.mjs +24 -0
  465. package/test/integration/cad-project-workflow.test.mjs +9 -0
  466. package/test/integration/cad-project.test.mjs +82 -0
  467. package/test/integration/cli-help.test.mjs +4 -0
  468. package/test/integration/cms-site-tenancy-contract.test.mjs +256 -0
  469. package/test/integration/core-client.integration.test.mjs +55 -0
  470. package/test/integration/error-runtime-rpc.test.mjs +71 -0
  471. package/test/integration/features-resolve.test.mjs +128 -0
  472. package/test/integration/install-script.test.mjs +107 -0
  473. package/test/integration/inventory-core.test.mjs +53 -0
  474. package/test/integration/plugins-cloudflare.integration.test.mjs +28 -0
  475. package/test/integration/provider-env-cli.test.mjs +1 -1
  476. package/test/integration/runtime-migrations.test.mjs +6 -1
  477. package/test/integration/runtime-status.integration.test.mjs +211 -0
  478. package/test/integration/scaffold-cloudflare.test.mjs +46 -0
  479. package/test/integration/storage-architecture.test.mjs +154 -0
  480. package/test/integration/store-discovery.test.mjs +44 -0
  481. package/test/integration/terminal-exec.integration.test.mjs +86 -0
  482. package/test/integration/tool-runtime.test.mjs +124 -0
  483. package/test/integration/tool-schema.test.mjs +59 -0
  484. package/test/knowledge-service.test.mjs +4 -0
  485. package/test/local-sessions.test.mjs +11 -2
  486. package/test/local-studio-deploy.test.mjs +1 -1
  487. package/test/model-catalog.test.mjs +28 -1
  488. package/test/models.test.mjs +159 -5
  489. package/test/openai-responses.test.mjs +60 -0
  490. package/test/provider-credentials.test.mjs +15 -5
  491. package/test/responses-runner.test.mjs +321 -6
  492. package/test/sdk-worker-contract.test.mjs +5 -1
  493. package/test/shell.test.mjs +149 -4
  494. package/test/smoke.mjs +4 -3
  495. package/test/tools-search.test.mjs +33 -0
  496. package/test/unit/website-assets-bindings.test.mjs +60 -0
  497. package/test/whoami-resume.test.mjs +87 -7
  498. package/examples/gorilla-shell/README.md +0 -15
  499. package/src/lib/gorilla-template.js +0 -54
  500. package/src/lib/prompt-byok.js +0 -57
  501. package/src/lib/save-sdk-token.js +0 -19
  502. package/templates/gorilla-shell/App.tsx +0 -639
  503. package/templates/gorilla-shell/README.md +0 -34
  504. package/templates/gorilla-shell/index.html +0 -15
  505. package/templates/gorilla-shell/main.jsx +0 -9
  506. package/templates/gorilla-shell/package.json +0 -19
  507. package/templates/gorilla-shell/vite.config.js +0 -21
@@ -9,7 +9,7 @@ import {
9
9
  assertConnectionOwner,
10
10
  } from './index.js';
11
11
  import { resolveAuthenticatedOwner } from './owner.js';
12
- import { sealToken, vaultConfigured } from './vault.js';
12
+ import { decryptSecret, sealToken, vaultConfigured } from './vault.js';
13
13
 
14
14
  function json(data, status = 200) {
15
15
  return new Response(JSON.stringify(data), {
@@ -22,6 +22,35 @@ function redirect(location) {
22
22
  return new Response(null, { status: 302, headers: { location } });
23
23
  }
24
24
 
25
+ function settingsRedirect(url, result, error = '', returnTo = '') {
26
+ const destination = returnTo ? new URL(returnTo) : new URL('/settings/integrations', url.origin);
27
+ destination.searchParams.set('connection', 'cloudflare');
28
+ destination.searchParams.set('result', result);
29
+ if (error) destination.searchParams.set('error', error);
30
+ return redirect(destination.toString());
31
+ }
32
+
33
+ function resolveReturnTo(url) {
34
+ const raw = url.searchParams.get('return_to') || '';
35
+ if (!raw) return '';
36
+ try {
37
+ const destination = new URL(raw, url.origin);
38
+ return destination.origin === url.origin ? destination.toString() : '';
39
+ } catch {
40
+ return '';
41
+ }
42
+ }
43
+
44
+ async function deleteOAuthState(env, state) {
45
+ if (env.DB) {
46
+ await env.DB.prepare(
47
+ `DELETE FROM agentsam_cloudflare_oauth_state WHERE state = ?`,
48
+ ).bind(state).run();
49
+ } else if (env.oauthState instanceof Map) {
50
+ env.oauthState.delete(state);
51
+ }
52
+ }
53
+
25
54
  export function isCloudflareConnectionPath(pathname) {
26
55
  return pathname === '/api/connections/cloudflare'
27
56
  || pathname === '/api/connections/cloudflare/start'
@@ -47,10 +76,58 @@ async function ensureTables(env) {
47
76
  state TEXT PRIMARY KEY,
48
77
  owner_id TEXT NOT NULL,
49
78
  code_verifier TEXT NOT NULL,
50
- created_at INTEGER
79
+ created_at INTEGER,
80
+ return_to TEXT
81
+ )`).run();
82
+ await env.DB.prepare(`CREATE TABLE IF NOT EXISTS integration_resources (
83
+ id TEXT PRIMARY KEY,
84
+ tenant_id TEXT NOT NULL,
85
+ connection_id TEXT NOT NULL,
86
+ provider TEXT NOT NULL,
87
+ resource_type TEXT NOT NULL,
88
+ provider_resource_id TEXT,
89
+ name TEXT,
90
+ url TEXT,
91
+ metadata_json TEXT DEFAULT '{}',
92
+ synced_at TEXT,
93
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
94
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
51
95
  )`).run();
52
96
  }
53
97
 
98
+ async function seedKnownCloudflareResources(env, ownerId, connectionId, cloudflareAccountId) {
99
+ if (!env?.DB?.prepare || !cloudflareAccountId) return;
100
+ let configuredScopes = {};
101
+ try { configuredScopes = JSON.parse(env.AGENTSAM_RESOURCE_SCOPE_JSON || '{}'); } catch { configuredScopes = {}; }
102
+ const resources = [
103
+ { key: 'agentsam-sdk', type: 'worker', id: 'agentsam-sdk', name: 'AgentSam SDK / Local Studio' },
104
+ { key: 'agentsam-cad-creator', type: 'worker', id: 'agentsam-cad-creator', name: 'AgentSam CAD Creator' },
105
+ { key: 'agentsam-client-cms-editor', type: 'worker', id: 'agentsam-client-cms-editor', name: 'AgentSam Client CMS Editor' },
106
+ { key: 'fuelnfreetime', type: 'worker', id: 'fuelnfreetime', name: 'Fuel & Free Time', metadata: {
107
+ zone_id: '816a5d2284103e4481987ceeb16c2ca9',
108
+ d1_database_id: '9fd6ff92-e407-4b51-8b01-3c93f3845bb2',
109
+ r2_bucket: 'fuelnfreetime',
110
+ ...(configuredScopes.fuelnfreetime || {}),
111
+ } },
112
+ ];
113
+ const statements = resources.map((resource) => env.DB.prepare(`
114
+ INSERT OR REPLACE INTO integration_resources (
115
+ id, tenant_id, connection_id, provider, resource_type, provider_resource_id,
116
+ name, metadata_json, synced_at, updated_at
117
+ ) VALUES (?, ?, ?, 'cloudflare', ?, ?, ?, ?, datetime('now'), datetime('now'))
118
+ `).bind(
119
+ `ires_cf_${cloudflareAccountId}_${resource.key}`,
120
+ ownerId,
121
+ connectionId,
122
+ resource.type,
123
+ resource.id,
124
+ resource.name,
125
+ JSON.stringify({ cloudflare_account_id: cloudflareAccountId, ...(resource.metadata || {}) }),
126
+ ));
127
+ if (typeof env.DB.batch === 'function') await env.DB.batch(statements);
128
+ else for (const statement of statements) await statement.run();
129
+ }
130
+
54
131
  export async function handleCloudflareConnectionRequest(request, env) {
55
132
  const url = new URL(request.url);
56
133
  const client = resolveCloudflareOAuthClient(env);
@@ -98,7 +175,9 @@ export async function handleCloudflareConnectionRequest(request, env) {
98
175
  if (env.DB) {
99
176
  const row = await env.DB.prepare(
100
177
  `SELECT connection_id, owner_id, cloudflare_account_id, scopes, status, created_at, updated_at, expires_at
101
- FROM agentsam_cloudflare_connections WHERE owner_id = ? LIMIT 1`,
178
+ FROM agentsam_cloudflare_connections
179
+ WHERE owner_id = ? AND status = 'connected'
180
+ ORDER BY updated_at DESC LIMIT 1`,
102
181
  ).bind(ownerId).first();
103
182
  if (row) {
104
183
  connection = {
@@ -122,12 +201,17 @@ export async function handleCloudflareConnectionRequest(request, env) {
122
201
  const verifier = btoa(String.fromCharCode(...verifierBytes)).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
123
202
  const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier));
124
203
  const challenge = btoa(String.fromCharCode(...new Uint8Array(digest))).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
204
+ const returnTo = resolveReturnTo(url);
125
205
  if (env.DB) {
126
206
  await env.DB.prepare(
127
- `INSERT INTO agentsam_cloudflare_oauth_state (state, owner_id, code_verifier, created_at) VALUES (?, ?, ?, unixepoch())`,
128
- ).bind(state, ownerId, verifier).run();
207
+ `DELETE FROM agentsam_cloudflare_oauth_state WHERE created_at < unixepoch() - 600`,
208
+ ).run();
209
+ await env.DB.prepare(
210
+ `INSERT INTO agentsam_cloudflare_oauth_state (state, owner_id, code_verifier, created_at, return_to)
211
+ VALUES (?, ?, ?, unixepoch(), ?)`,
212
+ ).bind(state, ownerId, verifier, returnTo || null).run();
129
213
  } else if (env.oauthState instanceof Map) {
130
- env.oauthState.set(state, { ownerId, verifier });
214
+ env.oauthState.set(state, { ownerId, verifier, returnTo });
131
215
  }
132
216
  const redirectUri = `${url.origin}${CLOUDFLARE_CALLBACK_PATH}`;
133
217
  const authorize = buildAuthorizeUrl({
@@ -142,41 +226,62 @@ export async function handleCloudflareConnectionRequest(request, env) {
142
226
  if (url.pathname === CLOUDFLARE_CALLBACK_PATH && request.method === 'GET') {
143
227
  const code = url.searchParams.get('code') || '';
144
228
  const state = url.searchParams.get('state') || '';
229
+ const providerError = url.searchParams.get('error') || '';
145
230
  let stored = null;
146
231
  if (env.DB) {
147
232
  stored = await env.DB.prepare(
148
- `SELECT owner_id, code_verifier FROM agentsam_cloudflare_oauth_state WHERE state = ?`,
233
+ `SELECT owner_id, code_verifier, created_at, return_to
234
+ FROM agentsam_cloudflare_oauth_state WHERE state = ?`,
149
235
  ).bind(state).first();
150
236
  } else if (env.oauthState instanceof Map) {
151
237
  stored = env.oauthState.get(state);
152
- if (stored) stored = { owner_id: stored.ownerId, code_verifier: stored.verifier };
238
+ if (stored) stored = { owner_id: stored.ownerId, code_verifier: stored.verifier, return_to: stored.returnTo || '' };
153
239
  }
154
240
  if (!stored) {
241
+ // A callback without a one-time PKCE state is forged or expired. Keep
242
+ // this as an explicit 403 instead of redirecting into a misleading UI.
155
243
  return json({ ok: false, error: 'cloudflare_connection_forbidden' }, 403);
156
244
  }
157
245
  if (!ownerId) ownerId = stored.owner_id;
158
246
  if (stored.owner_id !== ownerId) {
159
- return json({ ok: false, error: 'cloudflare_connection_forbidden' }, 403);
247
+ return settingsRedirect(url, 'error', 'cloudflare_connection_forbidden', stored.return_to || '');
248
+ }
249
+ const createdAt = Number(stored.created_at || 0);
250
+ const now = Math.floor(Date.now() / 1000);
251
+ if (createdAt && now - createdAt > 10 * 60) {
252
+ await deleteOAuthState(env, state);
253
+ return settingsRedirect(url, 'error', 'oauth_state_expired', stored.return_to || '');
160
254
  }
255
+ await deleteOAuthState(env, state);
256
+ if (providerError) {
257
+ return settingsRedirect(url, 'error', providerError, stored.return_to || '');
258
+ }
259
+ if (!code) {
260
+ return settingsRedirect(url, 'error', 'authorization_code_missing', stored.return_to || '');
261
+ }
262
+ // This is Cloudflare's public PKCE client (Token Authentication Method:
263
+ // None). Do not add client_secret, even if an obsolete Worker binding is
264
+ // present; a mixed-auth exchange is rejected by Cloudflare.
265
+ const tokenParams = {
266
+ grant_type: 'authorization_code',
267
+ code,
268
+ redirect_uri: `${url.origin}${CLOUDFLARE_CALLBACK_PATH}`,
269
+ client_id: String(env.CLOUDFLARE_OAUTH_CLIENT_ID),
270
+ code_verifier: stored.code_verifier,
271
+ };
161
272
  const tokenRes = await fetch(CLOUDFLARE_OAUTH_TOKEN_URL, {
162
273
  method: 'POST',
163
274
  headers: { 'content-type': 'application/x-www-form-urlencoded' },
164
- body: new URLSearchParams({
165
- grant_type: 'authorization_code',
166
- code,
167
- redirect_uri: `${url.origin}${CLOUDFLARE_CALLBACK_PATH}`,
168
- client_id: String(env.CLOUDFLARE_OAUTH_CLIENT_ID),
169
- client_secret: String(env.CLOUDFLARE_OAUTH_CLIENT_SECRET),
170
- code_verifier: stored.code_verifier,
171
- }),
275
+ body: new URLSearchParams(tokenParams),
172
276
  });
173
277
  if (!tokenRes.ok) {
174
- return json({ ok: false, error: 'token_exchange_failed' }, 502);
278
+ console.error('cloudflare_token_exchange_failed', tokenRes.status);
279
+ return settingsRedirect(url, 'error', 'token_exchange_failed', stored.return_to || '');
175
280
  }
176
281
  const tokens = await tokenRes.json();
177
282
  const connectionId = `cfconn_${crypto.randomUUID().replace(/-/g, '').slice(0, 16)}`;
178
283
  if (tokens.access_token && !vaultConfigured(env)) {
179
- return json({ ok: false, error: 'vault_unavailable' }, 503);
284
+ return settingsRedirect(url, 'error', 'vault_unavailable', stored.return_to || '');
180
285
  }
181
286
  const aad = `cloudflare-connection:${ownerId}`;
182
287
  let accessEnc = null;
@@ -185,10 +290,16 @@ export async function handleCloudflareConnectionRequest(request, env) {
185
290
  accessEnc = await sealToken(env, tokens.access_token, aad);
186
291
  refreshEnc = await sealToken(env, tokens.refresh_token, aad);
187
292
  } catch (err) {
188
- return json({ ok: false, error: err.code || 'vault_unavailable' }, 503);
293
+ return settingsRedirect(url, 'error', err.code || 'vault_unavailable', stored.return_to || '');
189
294
  }
190
295
  if (env.DB) {
191
- await env.DB.prepare(
296
+ const removePrevious = env.DB.prepare(
297
+ `UPDATE agentsam_cloudflare_connections
298
+ SET status = 'superseded', access_token_encrypted = NULL,
299
+ refresh_token_encrypted = NULL, updated_at = unixepoch()
300
+ WHERE owner_id = ? AND status = 'connected'`,
301
+ ).bind(ownerId);
302
+ const insertConnection = env.DB.prepare(
192
303
  `INSERT INTO agentsam_cloudflare_connections (
193
304
  connection_id, owner_id, cloudflare_account_id, scopes, status,
194
305
  access_token_encrypted, refresh_token_encrypted, created_at, updated_at, expires_at
@@ -201,22 +312,52 @@ export async function handleCloudflareConnectionRequest(request, env) {
201
312
  accessEnc,
202
313
  refreshEnc,
203
314
  tokens.expires_in ? Math.floor(Date.now() / 1000) + Number(tokens.expires_in) : null,
204
- ).run();
315
+ );
316
+ if (typeof env.DB.batch === 'function') {
317
+ await env.DB.batch([removePrevious, insertConnection]);
318
+ } else {
319
+ await removePrevious.run();
320
+ await insertConnection.run();
321
+ }
322
+ await seedKnownCloudflareResources(env, ownerId, connectionId, tokens.account_id || null);
205
323
  }
206
- return redirect(`/agentsam?connection=cloudflare`);
324
+ return settingsRedirect(url, 'connected', '', stored.return_to || '');
207
325
  }
208
326
 
209
327
  if (url.pathname === '/api/connections/cloudflare/disconnect' && request.method === 'POST') {
328
+ let providerRevoked = false;
210
329
  if (env.DB) {
211
330
  const row = await env.DB.prepare(
212
- `SELECT connection_id, owner_id FROM agentsam_cloudflare_connections WHERE owner_id = ?`,
331
+ `SELECT connection_id, owner_id, access_token_encrypted
332
+ FROM agentsam_cloudflare_connections
333
+ WHERE owner_id = ? AND status = 'connected'
334
+ ORDER BY updated_at DESC LIMIT 1`,
213
335
  ).bind(ownerId).first();
214
336
  if (row) {
215
337
  assertConnectionOwner({ ownerId: row.owner_id, connectionId: row.connection_id }, ownerId);
216
- await env.DB.prepare(`DELETE FROM agentsam_cloudflare_connections WHERE owner_id = ?`).bind(ownerId).run();
338
+ if (row.access_token_encrypted) {
339
+ try {
340
+ const token = await decryptSecret(env, row.access_token_encrypted, `cloudflare-connection:${ownerId}`);
341
+ const revokeParams = new URLSearchParams({ token, client_id: String(env.CLOUDFLARE_OAUTH_CLIENT_ID) });
342
+ const revokeResponse = await fetch(CLOUDFLARE_OAUTH_REVOKE_URL, {
343
+ method: 'POST',
344
+ headers: { 'content-type': 'application/x-www-form-urlencoded' },
345
+ body: revokeParams,
346
+ });
347
+ providerRevoked = revokeResponse.ok;
348
+ } catch (error) {
349
+ console.error('cloudflare_token_revoke_failed', String(error?.message || error));
350
+ }
351
+ }
352
+ await env.DB.prepare(`
353
+ UPDATE agentsam_cloudflare_connections
354
+ SET status = 'revoked', access_token_encrypted = NULL,
355
+ refresh_token_encrypted = NULL, expires_at = unixepoch(), updated_at = unixepoch()
356
+ WHERE connection_id = ? AND owner_id = ?
357
+ `).bind(row.connection_id, ownerId).run();
217
358
  }
218
359
  }
219
- return json({ ok: true, status: 'not_configured' });
360
+ return json({ ok: true, status: 'not_configured', provider_revoked: providerRevoked });
220
361
  }
221
362
 
222
363
  return json({ ok: false, error: 'not_found' }, 404);
@@ -5,6 +5,7 @@ import {
5
5
  cloudflareConnectionSafeStatus,
6
6
  resolveCloudflareOAuthClient,
7
7
  } from '../src/index.js';
8
+ import { handleCloudflareConnectionRequest } from '../src/routes.js';
8
9
 
9
10
  describe('cloudflare connector', () => {
10
11
  it('reports not_configured when credentials are absent', () => {
@@ -17,7 +18,6 @@ describe('cloudflare connector', () => {
17
18
  it('loads fake fixtures without treating them as production authority', () => {
18
19
  const client = resolveCloudflareOAuthClient({
19
20
  CLOUDFLARE_OAUTH_CLIENT_ID: 'sillynotreal',
20
- CLOUDFLARE_OAUTH_CLIENT_SECRET: 'sillynotreal-secret',
21
21
  });
22
22
  assert.equal(client.configured, true);
23
23
  assert.equal(client.fixture, true);
@@ -32,7 +32,7 @@ describe('cloudflare connector', () => {
32
32
  });
33
33
  const blob = JSON.stringify(status);
34
34
  assert.equal(blob.includes('sillynotreal-secret'), false);
35
- assert.equal(status.secret, 'configured');
35
+ assert.equal(status.token_auth_method, 'none_pkce');
36
36
  assert.equal(status.configured, false);
37
37
  });
38
38
 
@@ -41,4 +41,114 @@ describe('cloudflare connector', () => {
41
41
  assert.throws(() => assertConnectionOwner(record, 'connor'), /cloudflare_connection_forbidden/);
42
42
  assert.equal(assertConnectionOwner(record, 'sam').connectionId, 'c1');
43
43
  });
44
+
45
+ it('supports a production PKCE client with no client secret', () => {
46
+ const client = resolveCloudflareOAuthClient({
47
+ CLOUDFLARE_OAUTH_CLIENT_ID: 'real-client-id',
48
+ });
49
+ assert.equal(client.productionReady, true);
50
+ assert.equal(client.clientIdConfigured, true);
51
+ assert.equal(client.tokenAuthMethod, 'none_pkce');
52
+ });
53
+
54
+ it('keeps connector return paths same-origin', async () => {
55
+ const calls = [];
56
+ const DB = {
57
+ prepare(sql) {
58
+ return {
59
+ args: [],
60
+ bind(...args) { this.args = args; return this; },
61
+ async run() { calls.push({ sql, args: this.args }); return { success: true }; },
62
+ };
63
+ },
64
+ };
65
+ const response = await handleCloudflareConnectionRequest(
66
+ new Request('https://agentsam.example/api/connections/cloudflare/start?return_to=https://untrusted.example/after', {
67
+ headers: { authorization: 'Bearer fixture' },
68
+ }),
69
+ {
70
+ DB,
71
+ fixtureSessions: new Map([['fixture', 'user_123']]),
72
+ CLOUDFLARE_OAUTH_CLIENT_ID: 'real-client-id',
73
+ },
74
+ );
75
+ assert.equal(response.status, 200);
76
+ assert.equal(
77
+ calls.some((call) => call.sql.includes('DELETE FROM agentsam_cloudflare_oauth_state WHERE created_at < unixepoch() - 600')),
78
+ true,
79
+ );
80
+ const stateInsert = calls.find((call) => call.sql.includes('INSERT INTO agentsam_cloudflare_oauth_state'));
81
+ assert.ok(stateInsert);
82
+ assert.equal(stateInsert.args.at(-1), null);
83
+ });
84
+
85
+ it('consumes callback state and stores only encrypted OAuth tokens', async () => {
86
+ const now = Math.floor(Date.now() / 1000);
87
+ const calls = [];
88
+ const statements = [];
89
+ const DB = {
90
+ prepare(sql) {
91
+ const statement = {
92
+ sql,
93
+ args: [],
94
+ bind(...args) {
95
+ this.args = args;
96
+ return this;
97
+ },
98
+ async first() {
99
+ if (sql.includes('agentsam_cloudflare_oauth_state')) {
100
+ return { owner_id: 'user_123', code_verifier: 'verifier', created_at: now };
101
+ }
102
+ return null;
103
+ },
104
+ async run() {
105
+ calls.push({ sql, args: this.args });
106
+ return { success: true };
107
+ },
108
+ };
109
+ statements.push(statement);
110
+ return statement;
111
+ },
112
+ async batch(batchStatements) {
113
+ for (const statement of batchStatements) await statement.run();
114
+ return batchStatements.map(() => ({ success: true }));
115
+ },
116
+ };
117
+ const originalFetch = globalThis.fetch;
118
+ globalThis.fetch = async (_input, init) => {
119
+ const body = new URLSearchParams(init.body);
120
+ assert.equal(body.get('client_secret'), null);
121
+ return new Response(JSON.stringify({
122
+ access_token: 'access-plaintext',
123
+ refresh_token: 'refresh-plaintext',
124
+ account_id: 'account_123',
125
+ scope: 'd1.read workers-scripts.write',
126
+ expires_in: 3600,
127
+ }), { status: 200, headers: { 'content-type': 'application/json' } });
128
+ };
129
+
130
+ try {
131
+ const response = await handleCloudflareConnectionRequest(
132
+ new Request('https://agentsam.example/api/connections/cloudflare/callback?code=code_123&state=state_123'),
133
+ {
134
+ DB,
135
+ CLOUDFLARE_OAUTH_CLIENT_ID: 'real-client-id',
136
+ CLOUDFLARE_OAUTH_CLIENT_SECRET: 'obsolete-secret-must-not-be-sent',
137
+ VAULT_MASTER_KEY: '01234567890123456789012345678901',
138
+ },
139
+ );
140
+ assert.equal(response.status, 302);
141
+ assert.equal(
142
+ response.headers.get('location'),
143
+ 'https://agentsam.example/settings/integrations?connection=cloudflare&result=connected',
144
+ );
145
+ assert.equal(calls.some((call) => call.sql.includes('DELETE FROM agentsam_cloudflare_oauth_state')), true);
146
+ const insert = calls.find((call) => call.sql.includes('INSERT INTO agentsam_cloudflare_connections'));
147
+ assert.ok(insert);
148
+ assert.notEqual(insert.args[4], 'access-plaintext');
149
+ assert.notEqual(insert.args[5], 'refresh-plaintext');
150
+ } finally {
151
+ globalThis.fetch = originalFetch;
152
+ }
153
+ });
44
154
  });
@@ -0,0 +1,11 @@
1
+ # @inneranimalmedia/heuristic-theme
2
+
3
+ Stock AgentSam CMS storefront shell theme. Exports a deterministic theme contract consumed by CMS presets and `theme.storefront.shell`.
4
+
5
+ ```js
6
+ import { createStorefrontShellTheme } from "@inneranimalmedia/heuristic-theme";
7
+
8
+ const theme = createStorefrontShellTheme();
9
+ ```
10
+
11
+ Historical gallery demos live in `apps/theme-gallery-preview` — this package owns the reusable stock contract, not donor site archives.
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@inneranimalmedia/heuristic-theme",
3
+ "version": "0.1.0",
4
+ "description": "Stock AgentSam CMS storefront shell theme contract (heuristic-theme).",
5
+ "type": "module",
6
+ "main": "./src/index.js",
7
+ "exports": {
8
+ ".": "./src/index.js",
9
+ "./theme": "./src/theme.js"
10
+ },
11
+ "files": [
12
+ "src",
13
+ "README.md"
14
+ ],
15
+ "scripts": {
16
+ "test": "node --test test/*.test.mjs"
17
+ },
18
+ "engines": {
19
+ "node": ">=22 <25"
20
+ },
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "license": "MIT"
25
+ }
@@ -0,0 +1,2 @@
1
+ export { createStorefrontShellTheme } from "./theme.js";
2
+ export { createHeuristicThemeProductRow } from "./registry.js";
@@ -0,0 +1,36 @@
1
+ import { createStorefrontShellTheme } from "./theme.js";
2
+
3
+ /**
4
+ * Durable agentsam_products payload for the stock heuristic theme.
5
+ * Caller resolves repository_id against live code_repositories before UPSERT.
6
+ */
7
+ export function createHeuristicThemeProductRow({ accountId, repositoryId = null } = {}) {
8
+ const theme = createStorefrontShellTheme();
9
+ return {
10
+ account_id: accountId || null,
11
+ slug: theme.slug,
12
+ name: theme.displayName,
13
+ kind: "theme",
14
+ status: "wired",
15
+ repository_id: repositoryId,
16
+ canonical_path: "packages/heuristic-theme",
17
+ package_name: "@inneranimalmedia/heuristic-theme",
18
+ metadata: {
19
+ origin: "gallery_mount",
20
+ normalization_state: "wired",
21
+ package: "@inneranimalmedia/heuristic-theme",
22
+ preview_kind: "live",
23
+ capabilities: ["theme.storefront.shell"],
24
+ app_manifest: null,
25
+ help_root: "docs/",
26
+ },
27
+ capability: "theme.storefront.shell",
28
+ relationships: [
29
+ {
30
+ relationship_type: "packaged_as",
31
+ target_type: "sdk-package",
32
+ target_slug: "heuristic-theme",
33
+ },
34
+ ],
35
+ };
36
+ }
@@ -0,0 +1,41 @@
1
+ /** @typedef {{ id: string, slug: string, displayName: string, version: string, kind: string, surfaces: string[], slots: Record<string, string[]>, tokens: Record<string, string>, sections: Array<{ type: string, label: string }>, metadata: Record<string, unknown> }} StorefrontShellTheme */
2
+
3
+ /**
4
+ * Deterministic stock CMS storefront shell theme contract.
5
+ * @returns {StorefrontShellTheme}
6
+ */
7
+ export function createStorefrontShellTheme() {
8
+ return {
9
+ id: "theme.storefront.shell",
10
+ slug: "heuristic-theme",
11
+ displayName: "Heuristic Theme",
12
+ version: "0.1.0",
13
+ kind: "storefront-shell",
14
+ surfaces: ["cms.editor", "cms.preview", "theme.gallery"],
15
+ slots: {
16
+ shell: ["header", "main", "footer"],
17
+ page: ["hero", "products", "content", "footer"],
18
+ navigation: ["brand", "links", "cta"],
19
+ },
20
+ tokens: {
21
+ "--color-bg": "#F9F7F2",
22
+ "--color-ink": "#101014",
23
+ "--color-accent": "#1e6a6f",
24
+ "--color-muted": "#8a8a95",
25
+ "--font-display": "\"Iowan Old Style\", \"Palatino Linotype\", Palatino, serif",
26
+ "--font-body": "ui-sans-serif, system-ui, -apple-system, sans-serif",
27
+ "--radius-control": "8px",
28
+ },
29
+ sections: [
30
+ { type: "hero", label: "Editorial hero" },
31
+ { type: "products", label: "Product grid" },
32
+ { type: "footer", label: "Footer" },
33
+ ],
34
+ metadata: {
35
+ package: "@inneranimalmedia/heuristic-theme",
36
+ capability: "theme.storefront.shell",
37
+ deterministic: true,
38
+ demoSite: "demo",
39
+ },
40
+ };
41
+ }
@@ -0,0 +1,26 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+ import { createStorefrontShellTheme } from "../src/index.js";
4
+
5
+ test("createStorefrontShellTheme returns stable stock contract", () => {
6
+ const theme = createStorefrontShellTheme();
7
+ assert.equal(theme.id, "theme.storefront.shell");
8
+ assert.equal(theme.slug, "heuristic-theme");
9
+ assert.equal(theme.kind, "storefront-shell");
10
+ assert.ok(theme.surfaces.includes("cms.editor"));
11
+ assert.ok(theme.slots.shell.includes("header"));
12
+ assert.equal(theme.tokens["--color-accent"], "#1e6a6f");
13
+ assert.equal(theme.metadata.package, "@inneranimalmedia/heuristic-theme");
14
+ assert.deepEqual(createStorefrontShellTheme(), theme);
15
+ });
16
+
17
+ import { createHeuristicThemeProductRow } from "../src/index.js";
18
+
19
+ test("createHeuristicThemeProductRow emits D1-ready product identity", () => {
20
+ const row = createHeuristicThemeProductRow({ accountId: "acct_demo", repositoryId: "repo_sdk" });
21
+ assert.equal(row.slug, "heuristic-theme");
22
+ assert.equal(row.kind, "theme");
23
+ assert.equal(row.status, "wired");
24
+ assert.equal(row.metadata.capabilities[0], "theme.storefront.shell");
25
+ assert.equal(row.canonical_path, "packages/heuristic-theme");
26
+ });
@@ -0,0 +1,64 @@
1
+ {
2
+ "schema": "agentsam.feature.v1",
3
+ "id": "identity.oauth-login-portal",
4
+ "name": "OAuth Login Portal",
5
+ "kind": "integration",
6
+ "status": "extracted",
7
+ "package": {
8
+ "name": "@inneranimalmedia/agentsam-sdk-identity",
9
+ "version": "2.6.2",
10
+ "directory": "packages/identity"
11
+ },
12
+ "provides": [
13
+ "identity.init",
14
+ "identity.login",
15
+ "identity.session",
16
+ "identity.oauth",
17
+ "identity.password-reset",
18
+ "identity.portal-ui"
19
+ ],
20
+ "runtime": [
21
+ "worker",
22
+ "browser"
23
+ ],
24
+ "contributes": {
25
+ "ui": [
26
+ "auth-portal"
27
+ ],
28
+ "migrations": [
29
+ "src/migrations/0001_identity_core.sql",
30
+ "src/migrations/0002_company.sql"
31
+ ]
32
+ },
33
+ "artifacts": [
34
+ {
35
+ "kind": "provider-catalog",
36
+ "path": "./providers.json"
37
+ },
38
+ {
39
+ "kind": "resources",
40
+ "path": "./resources.json"
41
+ },
42
+ {
43
+ "kind": "routes",
44
+ "path": "./routes.json"
45
+ },
46
+ {
47
+ "kind": "ui",
48
+ "path": "./ui.json"
49
+ }
50
+ ],
51
+ "activation": {
52
+ "steps": [
53
+ "validate_manifest",
54
+ "check_runtime",
55
+ "resolve_requires",
56
+ "plan_migrations",
57
+ "plan_routes",
58
+ "operator_approval",
59
+ "activate",
60
+ "verify",
61
+ "write_install_receipt"
62
+ ]
63
+ }
64
+ }