@inneranimalmedia/agentsam-sdk 2.6.2 → 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 (497) 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/AUTORAG.md +58 -0
  17. package/docs/BRAND_INTELLIGENCE.md +30 -0
  18. package/docs/CLI_SHELL.md +4 -2
  19. package/docs/CMS_CONTEXTUAL_COMPOSER.md +38 -0
  20. package/docs/MERKLE.md +4 -0
  21. package/docs/PROJECT_CONFIG.md +3 -0
  22. package/docs/REPOSITORY_KNOWLEDGE.md +2 -0
  23. package/docs/THEME_REFINERY.md +120 -0
  24. package/docs/architecture/PROVIDER-TOOLS-AND-COMPACTION.md +60 -0
  25. package/docs/architecture/STORAGE.md +87 -0
  26. package/docs/cad-project-tools.md +69 -0
  27. package/docs/cms-scaffolding-pattern-reference.md +73 -0
  28. package/docs/plans/AGENTSAM-INTERACTIVE-UI-REQUIREMENTS-codex-tui-20260919.md +113 -0
  29. package/docs/plans/AGENTSAM-INTERACTIVE-UI-REQUIREMENTS.md +85 -0
  30. package/docs/plans/AGENTSAM-MCP-CLIENT-2026-09-19.md +181 -0
  31. package/docs/plans/ASBD-PORTABLE-WORKGRAPH-UI-DEFERRED.md +34 -0
  32. package/docs/plans/ASTRA-BRIEF-2026-09-18.md +258 -0
  33. package/docs/plans/MULTI-AGENT-SPRINTS-2026-09-19.md +373 -0
  34. package/docs/plans/NEXT-AGENT-HANDOFF.md +167 -0
  35. package/docs/plans/RECONCILIATION-2026-09-19.md +178 -0
  36. package/docs/plugins.md +43 -0
  37. package/docs/tools/README.md +57 -0
  38. package/docs/tools/agent-and-orchestration.md +49 -0
  39. package/docs/tools/browser-and-research.md +46 -0
  40. package/docs/tools/cloudflare-platform.md +32 -0
  41. package/docs/tools/cms.md +25 -0
  42. package/docs/tools/communications.md +41 -0
  43. package/docs/tools/database-and-storage.md +62 -0
  44. package/docs/tools/design-and-media.md +64 -0
  45. package/docs/tools/filesystem-and-code.md +55 -0
  46. package/docs/tools/github.md +56 -0
  47. package/docs/tools/integrations-and-misc.md +16 -0
  48. package/docs/tools/memory.md +21 -0
  49. package/docs/tools/terminal-and-execution.md +29 -0
  50. package/docs/tools/tickets-and-platform.md +30 -0
  51. package/migrations/d1/0001_agentsam_plugin_runtime.sql +177 -0
  52. package/migrations/d1/0002_agentsam_ticket_ownership.sql +8 -0
  53. package/migrations/d1/0002_dynamic_model_policies.sql +23 -0
  54. package/migrations/d1/0003_expand_tool_handler_families.sql +18 -0
  55. package/migrations/d1/0004_project_aware_retrieval_lanes.sql +24 -0
  56. package/migrations/d1/0005_portable_knowledge_identity.sql +104 -0
  57. package/migrations/d1/0006_repair_ops_trail_account_scope.sql +14 -0
  58. package/migrations/d1/0007_repair_ops_trail_agent_run_account.sql +13 -0
  59. package/migrations/d1/0008_backfill_knowledge_run_legacy_tenant.sql +14 -0
  60. package/migrations/d1/0009_normalize_cloudflare_plugin_installations.sql +137 -0
  61. package/migrations/runtime/0001_cli_runtime.sql +67 -0
  62. package/migrations/runtime/0002_project_sessions.sql +15 -0
  63. package/migrations/runtime/0003_provider_continuations.sql +8 -0
  64. package/package.json +92 -12
  65. package/packages/agentsam-brand/README.md +21 -0
  66. package/packages/agentsam-brand/package.json +22 -0
  67. package/packages/agentsam-brand/src/contract.js +59 -0
  68. package/packages/agentsam-brand/src/extract.js +126 -0
  69. package/packages/agentsam-brand/src/goap-actions.js +73 -0
  70. package/packages/agentsam-brand/src/index.js +48 -0
  71. package/packages/agentsam-brand/src/plan.js +115 -0
  72. package/packages/agentsam-brand/src/resolve.js +139 -0
  73. package/packages/agentsam-brand/src/scan.js +250 -0
  74. package/packages/agentsam-brand/test/brand-scan.test.mjs +106 -0
  75. package/packages/agentsam-contracts/README.md +23 -0
  76. package/packages/agentsam-contracts/package.json +32 -0
  77. package/packages/agentsam-contracts/src/adapter.ts +25 -0
  78. package/packages/agentsam-contracts/src/agent.ts +35 -0
  79. package/packages/agentsam-contracts/src/artifacts.ts +33 -0
  80. package/packages/agentsam-contracts/src/authority.ts +29 -0
  81. package/packages/agentsam-contracts/src/context.ts +16 -0
  82. package/packages/agentsam-contracts/src/errors.ts +46 -0
  83. package/packages/agentsam-contracts/src/events.ts +47 -0
  84. package/packages/agentsam-contracts/src/execution.ts +50 -0
  85. package/packages/agentsam-contracts/src/hooks.ts +40 -0
  86. package/packages/agentsam-contracts/src/identity.ts +16 -0
  87. package/packages/agentsam-contracts/src/index.ts +14 -0
  88. package/packages/agentsam-contracts/src/models.ts +9 -0
  89. package/packages/agentsam-contracts/src/providers.ts +33 -0
  90. package/packages/agentsam-contracts/src/repository.ts +64 -0
  91. package/packages/agentsam-contracts/src/tools.ts +98 -0
  92. package/packages/agentsam-contracts/test/contracts.test.mjs +16 -0
  93. package/packages/agentsam-contracts/test/errors-catalog.test.mjs +25 -0
  94. package/packages/agentsam-contracts/test/repository.test.mjs +18 -0
  95. package/packages/agentsam-contracts/tsconfig.json +12 -0
  96. package/packages/agentsam-errors/package.json +17 -0
  97. package/packages/agentsam-errors/src/adapters/anthropic.js +15 -0
  98. package/packages/agentsam-errors/src/adapters/cad.js +109 -0
  99. package/packages/agentsam-errors/src/adapters/cloudflare.js +21 -0
  100. package/packages/agentsam-errors/src/adapters/cursor.js +4 -0
  101. package/packages/agentsam-errors/src/adapters/device.js +38 -0
  102. package/packages/agentsam-errors/src/adapters/docker.js +28 -0
  103. package/packages/agentsam-errors/src/adapters/gcp.js +14 -0
  104. package/packages/agentsam-errors/src/adapters/github.js +22 -0
  105. package/packages/agentsam-errors/src/adapters/google.js +17 -0
  106. package/packages/agentsam-errors/src/adapters/index.js +55 -0
  107. package/packages/agentsam-errors/src/adapters/internal.js +40 -0
  108. package/packages/agentsam-errors/src/adapters/oauth.js +24 -0
  109. package/packages/agentsam-errors/src/adapters/openai.js +17 -0
  110. package/packages/agentsam-errors/src/adapters/process.js +35 -0
  111. package/packages/agentsam-errors/src/adapters/provider.js +114 -0
  112. package/packages/agentsam-errors/src/envelope.js +186 -0
  113. package/packages/agentsam-errors/src/error.js +24 -0
  114. package/packages/agentsam-errors/src/fingerprint.js +35 -0
  115. package/packages/agentsam-errors/src/index.js +10 -0
  116. package/packages/agentsam-errors/src/normalize.js +30 -0
  117. package/packages/agentsam-errors/src/redaction.js +52 -0
  118. package/packages/agentsam-errors/src/render.js +16 -0
  119. package/packages/agentsam-errors/src/retry.js +10 -0
  120. package/packages/agentsam-errors/src/transport.js +52 -0
  121. package/packages/agentsam-errors/src/vocabulary.js +320 -0
  122. package/packages/agentsam-errors/test/envelope.test.mjs +70 -0
  123. package/packages/agentsam-errors/test/providers.test.mjs +99 -0
  124. package/packages/agentsam-errors/test/redaction.test.mjs +21 -0
  125. package/packages/agentsam-errors/test/runtime-cad-device.test.mjs +76 -0
  126. package/packages/agentsam-errors/test/transport.test.mjs +46 -0
  127. package/packages/agentsam-knowledge/package.json +15 -0
  128. package/packages/agentsam-knowledge/src/autorag/index.js +64 -0
  129. package/packages/agentsam-knowledge/src/backends/index.js +26 -0
  130. package/packages/agentsam-knowledge/src/index.js +3 -0
  131. package/packages/agentsam-knowledge/src/providers/index.js +95 -0
  132. package/packages/agentsam-knowledge/test/autorag.test.mjs +42 -0
  133. package/packages/agentsam-nav/README.md +40 -0
  134. package/packages/agentsam-nav/dist/Nav.d.ts +43 -0
  135. package/packages/agentsam-nav/dist/NavCollapsible.d.ts +10 -0
  136. package/packages/agentsam-nav/dist/NavContent.d.ts +2 -0
  137. package/packages/agentsam-nav/dist/NavFooter.d.ts +2 -0
  138. package/packages/agentsam-nav/dist/NavGroup.d.ts +3 -0
  139. package/packages/agentsam-nav/dist/NavHeader.d.ts +2 -0
  140. package/packages/agentsam-nav/dist/NavMenu.d.ts +22 -0
  141. package/packages/agentsam-nav/dist/NavProvider.d.ts +35 -0
  142. package/packages/agentsam-nav/dist/NavTrigger.d.ts +2 -0
  143. package/packages/agentsam-nav/dist/Surfaces.d.ts +41 -0
  144. package/packages/agentsam-nav/dist/browser.d.ts +11 -0
  145. package/packages/agentsam-nav/dist/browser.global.js +132 -0
  146. package/packages/agentsam-nav/dist/browser.js +613 -0
  147. package/packages/agentsam-nav/dist/contracts.d.ts +76 -0
  148. package/packages/agentsam-nav/dist/index.d.ts +11 -0
  149. package/packages/agentsam-nav/dist/index.js +614 -0
  150. package/packages/agentsam-nav/dist/legacy.css +83 -0
  151. package/packages/agentsam-nav/dist/shell.css +113 -0
  152. package/packages/agentsam-nav/dist/theme.css +113 -0
  153. package/packages/agentsam-nav/dist/utils.d.ts +1 -0
  154. package/packages/agentsam-nav/package.json +43 -0
  155. package/packages/agentsam-queue-control/README.md +107 -0
  156. package/packages/agentsam-queue-control/package.json +31 -0
  157. package/packages/agentsam-queue-control/schemas/job-envelope.schema.json +56 -0
  158. package/packages/agentsam-queue-control/src/adapters/cloudflare.js +152 -0
  159. package/packages/agentsam-queue-control/src/adapters/memory.js +38 -0
  160. package/packages/agentsam-queue-control/src/contracts.js +130 -0
  161. package/packages/agentsam-queue-control/src/control-plane.js +141 -0
  162. package/packages/agentsam-queue-control/src/dispatch.js +43 -0
  163. package/packages/agentsam-queue-control/src/index.js +7 -0
  164. package/packages/agentsam-queue-control/src/policy.js +88 -0
  165. package/packages/agentsam-queue-control/src/topology.js +66 -0
  166. package/packages/agentsam-queue-control/test/queue-control.test.mjs +100 -0
  167. package/packages/agentsam-repository/src/goap.js +718 -0
  168. package/packages/agentsam-repository/src/goap.js.bak-20260922011251 +670 -0
  169. package/packages/agentsam-repository/src/index.js +5 -0
  170. package/packages/agentsam-repository/src/merkle/cloudflare-persistence.js +2 -2
  171. package/packages/agentsam-repository/src/tickets.js +184 -0
  172. package/packages/agentsam-repository/src/work-tracking.js +199 -0
  173. package/packages/agentsam-repository/src/workspace-state.js +176 -0
  174. package/packages/agentsam-repository/test/goap-tickets-workspace-state.test.mjs +152 -0
  175. package/packages/connectors/cloudflare/src/index.js +297 -15
  176. package/packages/connectors/cloudflare/src/owner.js +43 -40
  177. package/packages/connectors/cloudflare/src/routes.js +167 -26
  178. package/packages/connectors/cloudflare/tests/connector.test.mjs +112 -2
  179. package/packages/heuristic-theme/README.md +11 -0
  180. package/packages/heuristic-theme/package.json +25 -0
  181. package/packages/heuristic-theme/src/index.js +2 -0
  182. package/packages/heuristic-theme/src/registry.js +36 -0
  183. package/packages/heuristic-theme/src/theme.js +41 -0
  184. package/packages/heuristic-theme/test/theme.test.mjs +26 -0
  185. package/packages/identity/.agentsam/features/oauth-login-portal/agentsam.feature.json +64 -0
  186. package/packages/identity/.agentsam/features/oauth-login-portal/providers.json +96 -0
  187. package/packages/identity/.agentsam/features/oauth-login-portal/resources.json +47 -0
  188. package/packages/identity/.agentsam/features/oauth-login-portal/routes.json +74 -0
  189. package/packages/identity/.agentsam/features/oauth-login-portal/ui.json +35 -0
  190. package/packages/identity/package.json +3 -2
  191. package/packages/identity/src/adapters/cloudflare-d1/ids.js +4 -0
  192. package/packages/identity/src/adapters/cloudflare-d1/index.js +39 -1
  193. package/packages/identity/src/contracts/provider.js +3 -2
  194. package/packages/identity/src/frontend/auth-portal/pages/login.html +7 -0
  195. package/packages/identity/src/index.js +2 -0
  196. package/packages/identity/src/oauth/credentials.js +13 -0
  197. package/packages/identity/src/oauth/iam-platform.js +5 -5
  198. package/packages/identity/src/providers/cloudflare/index.js +19 -0
  199. package/packages/identity/src/providers/cloudflare/mapper.js +21 -0
  200. package/packages/identity/src/providers/cloudflare/oauth.js +48 -0
  201. package/packages/identity/src/providers/cloudflare/profile.js +28 -0
  202. package/packages/identity/src/providers/index.js +18 -2
  203. package/packages/identity/src/server/identity-service.js +13 -3
  204. package/packages/identity/src/server/worker-router.js +63 -8
  205. package/packages/identity/tests/identity-service.test.mjs +15 -0
  206. package/packages/providers/completeful/README.md +38 -0
  207. package/packages/providers/completeful/package.json +29 -0
  208. package/packages/providers/completeful/src/client.js +162 -0
  209. package/packages/providers/completeful/src/events.js +49 -0
  210. package/packages/providers/completeful/src/index.js +22 -0
  211. package/packages/providers/completeful/src/tools.js +579 -0
  212. package/packages/providers/completeful/src/webhooks.js +55 -0
  213. package/packages/providers/completeful/test/provider.test.mjs +196 -0
  214. package/packages/theme-church-site/README.md +10 -0
  215. package/packages/theme-church-site/package.json +30 -0
  216. package/packages/theme-church-site/src/harvest.json +14 -0
  217. package/packages/theme-church-site/src/index.js +84 -0
  218. package/packages/theme-church-site/test/theme.test.mjs +19 -0
  219. package/packages/theme-companions-site/README.md +10 -0
  220. package/packages/theme-companions-site/package.json +30 -0
  221. package/packages/theme-companions-site/src/harvest.json +12 -0
  222. package/packages/theme-companions-site/src/index.js +82 -0
  223. package/packages/theme-companions-site/test/theme.test.mjs +19 -0
  224. package/packages/theme-floors-site/README.md +10 -0
  225. package/packages/theme-floors-site/package.json +30 -0
  226. package/packages/theme-floors-site/src/harvest.json +14 -0
  227. package/packages/theme-floors-site/src/index.js +82 -0
  228. package/packages/theme-floors-site/test/theme.test.mjs +19 -0
  229. package/packages/theme-fuelnfree-site/README.md +10 -0
  230. package/packages/theme-fuelnfree-site/package.json +30 -0
  231. package/packages/theme-fuelnfree-site/src/harvest.json +13 -0
  232. package/packages/theme-fuelnfree-site/src/index.js +81 -0
  233. package/packages/theme-fuelnfree-site/test/theme.test.mjs +19 -0
  234. package/packages/theme-handyman-site/README.md +10 -0
  235. package/packages/theme-handyman-site/package.json +30 -0
  236. package/packages/theme-handyman-site/src/harvest.json +10 -0
  237. package/packages/theme-handyman-site/src/index.js +83 -0
  238. package/packages/theme-handyman-site/test/theme.test.mjs +19 -0
  239. package/packages/theme-insurance-site/README.md +10 -0
  240. package/packages/theme-insurance-site/package.json +30 -0
  241. package/packages/theme-insurance-site/src/harvest.json +10 -0
  242. package/packages/theme-insurance-site/src/index.js +83 -0
  243. package/packages/theme-insurance-site/test/theme.test.mjs +19 -0
  244. package/packages/theme-shinshu-site/README.md +10 -0
  245. package/packages/theme-shinshu-site/package.json +30 -0
  246. package/packages/theme-shinshu-site/src/harvest.json +12 -0
  247. package/packages/theme-shinshu-site/src/index.js +83 -0
  248. package/packages/theme-shinshu-site/test/theme.test.mjs +19 -0
  249. package/packages/work-graph/README.md +49 -0
  250. package/packages/work-graph/package.json +19 -0
  251. package/packages/work-graph/prototype/README.md +32 -0
  252. package/packages/work-graph/prototype/data/demo-workgraph.js +47 -0
  253. package/packages/work-graph/prototype/renderers/timeline-model.js +21 -0
  254. package/packages/work-graph/prototype/renderers/workgraph-runtime.js +38 -0
  255. package/packages/work-graph/prototype-gnantt.html +655 -0
  256. package/packages/work-graph/src/adapters/business/projects.js +23 -0
  257. package/packages/work-graph/src/adapters/engineering/git.js +22 -0
  258. package/packages/work-graph/src/adapters/engineering/mcp.js +22 -0
  259. package/packages/work-graph/src/index.js +76 -0
  260. package/packages/work-graph/src/renderers/gantt-model.js +11 -0
  261. package/packages/work-graph/src/renderers/timeline.js +16 -0
  262. package/packages/work-graph/test/work-graph.test.mjs +37 -0
  263. package/protocol/README.md +12 -0
  264. package/protocol/capabilities/cloudflare-cpu-audit-input.schema.json +30 -6
  265. package/protocol/capabilities/cloudflare-cpu-profile-input.schema.json +18 -4
  266. package/protocol/capabilities/cloudflare-wrangler-native-input.schema.json +59 -10
  267. package/protocol/capabilities/knowledge-search-input.schema.json +35 -0
  268. package/protocol/capabilities/manifest.json +163 -1
  269. package/protocol/capabilities/repository-audit-input.schema.json +39 -6
  270. package/protocol/capabilities/repository-snapshot-input.schema.json +15 -3
  271. package/protocol/capabilities/terminal-exec-input.schema.json +55 -0
  272. package/protocol/commerce/catalog.v1.json +50 -0
  273. package/protocol/errors/error-catalog.json +164 -0
  274. package/protocol/errors/error-envelope.schema.json +544 -0
  275. package/protocol/features/README.md +57 -0
  276. package/protocol/features/agentsam.feature.v1.schema.json +290 -0
  277. package/protocol/features/catalog.json +65 -0
  278. package/protocol/features/examples/provider-resend.feature.json +17 -0
  279. package/protocol/go/agentsam-go-runtime.v1.json +17 -0
  280. package/protocol/knowledge/LIFECYCLE.md +140 -0
  281. package/protocol/knowledge/README.md +4 -0
  282. package/protocol/presets/catalog.json +128 -19
  283. package/protocol/rpc/v1/errors.proto +24 -0
  284. package/protocol/theme-refinery/d1-reconciliation.md +48 -0
  285. package/protocol/theme-refinery/product-metadata.schema.json +27 -0
  286. package/protocol/theme-refinery/receipts/products-registry-batch-20260924.json +318 -0
  287. package/protocol/theme-refinery/receipts/theme-harvest-20260924.json +472 -0
  288. package/protocol/theme-refinery/reconciliation-receipt.schema.json +83 -0
  289. package/services/cad/server.py +249 -2
  290. package/src/agent/capability-adapter.js +15 -5
  291. package/src/agent/index.js +2 -1
  292. package/src/agent/model-turn.js +51 -0
  293. package/src/agent/responses-runner.js +304 -38
  294. package/src/capabilities/index.js +1 -0
  295. package/src/capabilities/terminal-exec.js +78 -0
  296. package/src/cli.js +117 -9
  297. package/src/cloudflare/index.js +6 -0
  298. package/src/cloudflare/runtime-status.js +393 -0
  299. package/src/cloudflare/wrangler.js +17 -1
  300. package/src/commands/app.js +106 -0
  301. package/src/commands/autorag.js +77 -0
  302. package/src/commands/brand.js +293 -0
  303. package/src/commands/cad.js +1 -0
  304. package/src/commands/connections.js +126 -29
  305. package/src/commands/context-economics.js +8 -0
  306. package/src/commands/db.js +7 -0
  307. package/src/commands/env.js +5 -4
  308. package/src/commands/eval.js +209 -14
  309. package/src/commands/go.js +365 -0
  310. package/src/commands/goap.js +176 -0
  311. package/src/commands/identity-init.js +27 -3
  312. package/src/commands/identity-protocol.js +195 -0
  313. package/src/commands/knowledge.js +64 -5
  314. package/src/commands/mcp.js +341 -0
  315. package/src/commands/merkle-persist.js +3 -1
  316. package/src/commands/merkle.js +18 -3
  317. package/src/commands/models.js +109 -23
  318. package/src/commands/plugins.js +175 -0
  319. package/src/commands/preferences.js +28 -8
  320. package/src/commands/product.js +53 -10
  321. package/src/commands/providers.js +118 -37
  322. package/src/commands/resume.js +9 -5
  323. package/src/commands/runtime-status.js +154 -0
  324. package/src/commands/shell.js +466 -55
  325. package/src/commands/status.js +82 -7
  326. package/src/commands/tunnel.js +228 -195
  327. package/src/commands/whoami.js +78 -6
  328. package/src/context/budget.js +6 -0
  329. package/src/context/index.js +2 -1
  330. package/src/context/project-card.js +75 -0
  331. package/src/errors/contract.js +34 -211
  332. package/src/errors/diagnostic.js +95 -51
  333. package/src/errors/index.js +6 -13
  334. package/src/eval/index.js +6 -0
  335. package/src/eval/live.js +439 -0
  336. package/src/features/resolve.js +242 -0
  337. package/src/go/build.js +108 -0
  338. package/src/go/cloudflare.js +207 -0
  339. package/src/go/contract.js +139 -0
  340. package/src/go/discover.js +96 -0
  341. package/src/go/index.js +13 -0
  342. package/src/go/receipts.js +77 -0
  343. package/src/go/registry.js +223 -0
  344. package/src/go/verify.js +31 -0
  345. package/src/index.js +100 -1
  346. package/src/knowledge/config.js +13 -5
  347. package/src/knowledge/engine.js +23 -8
  348. package/src/knowledge/index.js +1 -0
  349. package/src/knowledge/lane-registry.js +46 -0
  350. package/src/knowledge/providers/gemini.js +48 -8
  351. package/src/knowledge/service/client.js +13 -1
  352. package/src/knowledge/service/grpc-codec.js +156 -53
  353. package/src/knowledge/service/job-engine.js +133 -11
  354. package/src/knowledge/service/job-worker.js +34 -5
  355. package/src/knowledge/service/server.js +10 -1
  356. package/src/knowledge/store-discovery.js +77 -0
  357. package/src/lib/account-session.js +8 -2
  358. package/src/lib/agent-instructions.js +3 -0
  359. package/src/lib/auth.js +7 -3
  360. package/src/lib/cad/blender.js +42 -3
  361. package/src/lib/cad/d1-project-store.js +43 -0
  362. package/src/lib/cad/discovery.js +616 -0
  363. package/src/lib/cad/docker-executor.js +352 -0
  364. package/src/lib/cad/freecad.js +253 -0
  365. package/src/lib/cad/index.js +40 -0
  366. package/src/lib/cad/openscad.js +198 -0
  367. package/src/lib/cad/project-cli.d.ts +2 -0
  368. package/src/lib/cad/project-cli.js +21 -0
  369. package/src/lib/cad/project-contract.d.ts +3 -0
  370. package/src/lib/cad/project-contract.js +1 -0
  371. package/src/lib/cad/project-recipe.js +30 -0
  372. package/src/lib/cad/project-runtime.d.ts +2 -0
  373. package/src/lib/cad/project-runtime.js +53 -0
  374. package/src/lib/cad/project-store.js +25 -0
  375. package/src/lib/cad/project-workflows.js +31 -0
  376. package/src/lib/cad-docker.js +21 -2
  377. package/src/lib/cli-preferences.js +17 -2
  378. package/src/lib/core-client.js +37 -18
  379. package/src/lib/deploy/local-studio.js +6 -5
  380. package/src/lib/dockerize.js +3 -0
  381. package/src/lib/execution-approvals.js +1 -0
  382. package/src/lib/identity-scaffold.js +4 -1
  383. package/src/lib/knowledge-docker.js +9 -1
  384. package/src/lib/local-sessions.js +124 -34
  385. package/src/lib/local-status.js +35 -14
  386. package/src/lib/project-config.js +9 -0
  387. package/src/lib/provider-credentials.js +73 -11
  388. package/src/lib/scaffold/resolve-cloudflare-account.js +37 -0
  389. package/src/lib/scaffold/wizards/cms.js +2 -8
  390. package/src/lib/scaffold/wizards/worker-api.js +2 -8
  391. package/src/lib/slash-commands.js +9 -2
  392. package/src/local/migrations.js +109 -1
  393. package/src/local/runtime-store.js +31 -5
  394. package/src/local/sqlite.js +36 -1
  395. package/src/mcp/authority.js +348 -0
  396. package/src/mcp/client-adapters.js +431 -0
  397. package/src/mcp/client.js +172 -0
  398. package/src/mcp/index.js +47 -0
  399. package/src/mcp/telemetry.js +103 -0
  400. package/src/models/catalog.js +329 -51
  401. package/src/models/discovery.js +24 -4
  402. package/src/models/index.js +2 -0
  403. package/src/models/inventory-core.js +182 -0
  404. package/src/models/policy.js +20 -0
  405. package/src/plugins/cloudflare.js +103 -0
  406. package/src/plugins/completeful.js +69 -0
  407. package/src/plugins/contracts.js +86 -0
  408. package/src/plugins/index.js +11 -0
  409. package/src/plugins/registry.js +207 -0
  410. package/src/plugins/resource-scope.js +45 -0
  411. package/src/plugins/runtime.js +118 -0
  412. package/src/plugins/vectorize.js +31 -0
  413. package/src/progression/engine.js +171 -0
  414. package/src/progression/index.js +1 -0
  415. package/src/providers/cloudflare-chat.js +1 -1
  416. package/src/providers/gemini-generate-content.js +2 -1
  417. package/src/providers/openai-responses.js +45 -16
  418. package/src/providers/tool-schema.js +85 -0
  419. package/src/repository/index.js +29 -0
  420. package/src/rpc/generated/errors_pb.js +961 -1
  421. package/src/security/local-vault.js +415 -0
  422. package/src/security/process.js +20 -4
  423. package/src/status/actions.js +192 -0
  424. package/src/tools/hydrate.js +5 -1
  425. package/src/tools/index.js +7 -0
  426. package/src/tools/redact.js +64 -0
  427. package/src/tools/registry.js +83 -0
  428. package/src/tools/runtime.js +257 -0
  429. package/src/tools/search.js +21 -8
  430. package/src/ui/ansi.js +117 -3
  431. package/src/ui/cli/activity.js +76 -7
  432. package/src/ui/cli/footer.js +110 -9
  433. package/src/ui/cli/help.js +11 -4
  434. package/src/ui/wireframes.js +166 -0
  435. package/test/account-session.test.mjs +28 -0
  436. package/test/apps-scaffold-contract.test.mjs +16 -1
  437. package/test/capabilities.test.mjs +1 -1
  438. package/test/cli/eval-live.test.mjs +219 -0
  439. package/test/cli/go.test.mjs +71 -0
  440. package/test/cli/local-vault-and-provider-setup.test.mjs +268 -0
  441. package/test/cli/mcp-client.test.mjs +245 -0
  442. package/test/cli/runtime-ui.test.mjs +69 -2
  443. package/test/cli/status-actions.test.mjs +88 -0
  444. package/test/cli/wireframes-go-registry.test.mjs +54 -0
  445. package/test/cloudflare-connector.test.mjs +3 -6
  446. package/test/cloudflare-runtime.test.mjs +8 -1
  447. package/test/context.test.mjs +15 -0
  448. package/test/error-diagnostics.test.mjs +9 -0
  449. package/test/fixtures/cad/courtyard-house.json +208 -0
  450. package/test/go/cloudflare-probe.test.mjs +53 -0
  451. package/test/integration/app-command.test.mjs +55 -0
  452. package/test/integration/cad-discovery.test.mjs +158 -0
  453. package/test/integration/cad-docker-executor.test.mjs +249 -0
  454. package/test/integration/cad-execution.test.mjs +184 -0
  455. package/test/integration/cad-project-app.test.mjs +31 -0
  456. package/test/integration/cad-project-d1.test.mjs +25 -0
  457. package/test/integration/cad-project-native.test.mjs +24 -0
  458. package/test/integration/cad-project-workflow.test.mjs +9 -0
  459. package/test/integration/cad-project.test.mjs +82 -0
  460. package/test/integration/cli-help.test.mjs +4 -0
  461. package/test/integration/cms-site-tenancy-contract.test.mjs +256 -0
  462. package/test/integration/core-client.integration.test.mjs +55 -0
  463. package/test/integration/error-runtime-rpc.test.mjs +71 -0
  464. package/test/integration/features-resolve.test.mjs +128 -0
  465. package/test/integration/install-script.test.mjs +107 -0
  466. package/test/integration/inventory-core.test.mjs +53 -0
  467. package/test/integration/plugins-cloudflare.integration.test.mjs +28 -0
  468. package/test/integration/provider-env-cli.test.mjs +1 -1
  469. package/test/integration/runtime-migrations.test.mjs +6 -1
  470. package/test/integration/runtime-status.integration.test.mjs +211 -0
  471. package/test/integration/scaffold-cloudflare.test.mjs +46 -0
  472. package/test/integration/storage-architecture.test.mjs +154 -0
  473. package/test/integration/store-discovery.test.mjs +44 -0
  474. package/test/integration/terminal-exec.integration.test.mjs +86 -0
  475. package/test/integration/tool-runtime.test.mjs +124 -0
  476. package/test/integration/tool-schema.test.mjs +59 -0
  477. package/test/knowledge-service.test.mjs +4 -0
  478. package/test/local-sessions.test.mjs +11 -2
  479. package/test/local-studio-deploy.test.mjs +1 -1
  480. package/test/model-catalog.test.mjs +28 -1
  481. package/test/models.test.mjs +159 -5
  482. package/test/openai-responses.test.mjs +60 -0
  483. package/test/provider-credentials.test.mjs +15 -5
  484. package/test/responses-runner.test.mjs +321 -6
  485. package/test/shell.test.mjs +149 -4
  486. package/test/smoke.mjs +2 -2
  487. package/test/tools-search.test.mjs +33 -0
  488. package/test/unit/website-assets-bindings.test.mjs +60 -0
  489. package/test/whoami-resume.test.mjs +82 -3
  490. package/examples/gorilla-shell/README.md +0 -15
  491. package/src/lib/gorilla-template.js +0 -54
  492. package/templates/gorilla-shell/App.tsx +0 -639
  493. package/templates/gorilla-shell/README.md +0 -34
  494. package/templates/gorilla-shell/index.html +0 -15
  495. package/templates/gorilla-shell/main.jsx +0 -9
  496. package/templates/gorilla-shell/package.json +0 -19
  497. package/templates/gorilla-shell/vite.config.js +0 -21
@@ -0,0 +1,152 @@
1
+ import assert from 'node:assert/strict';
2
+ import test from 'node:test';
3
+
4
+ import {
5
+ createAgentRunId,
6
+ createTicketId,
7
+ generateTicketCreateSql,
8
+ generateTicketActivationSql,
9
+ generateTicketCloseSql,
10
+ } from '../src/tickets.js';
11
+ import { generateWorkspaceStateUpsertSql } from '../src/workspace-state.js';
12
+ import {
13
+ renderGoapStatus,
14
+ renderGoapGoal,
15
+ renderGoapWhy,
16
+ renderGoapPlan,
17
+ } from '../src/goap.js';
18
+
19
+ test('createAgentRunId / createTicketId produce prefixed, collision-resistant ids', () => {
20
+ const run1 = createAgentRunId();
21
+ const run2 = createAgentRunId();
22
+ const tkt1 = createTicketId();
23
+ assert.match(run1, /^arun_[0-9a-f]{16}$/);
24
+ assert.match(tkt1, /^tkt_[0-9a-f]{16}$/);
25
+ assert.notEqual(run1, run2);
26
+ });
27
+
28
+ test('generateTicketCreateSql requires account_id and title', () => {
29
+ assert.throws(() => generateTicketCreateSql({ title: 'x' }), /account_id_required/);
30
+ assert.throws(() => generateTicketCreateSql({ accountId: 'acc_1' }), /title_required/);
31
+ });
32
+
33
+ test('generateTicketCreateSql with status=active mints an agent_run and links it on the ticket insert', () => {
34
+ const { sql, ticketId, agentRunId } = generateTicketCreateSql({
35
+ accountId: 'acc_1',
36
+ title: 'Wire GOAP planner',
37
+ status: 'active',
38
+ now: 1000,
39
+ });
40
+ assert.ok(ticketId.startsWith('tkt_'));
41
+ assert.ok(agentRunId && agentRunId.startsWith('arun_'));
42
+ assert.match(sql, /INSERT INTO agentsam_agent_run/);
43
+ assert.match(sql, /INSERT INTO agentsam_tickets/);
44
+ assert.match(sql, /INSERT INTO agentsam_ticket_events/);
45
+ const runOccurrences = sql.split(agentRunId).length - 1;
46
+ assert.ok(runOccurrences >= 2, 'agent_run id should appear in both the run insert and the ticket insert');
47
+ });
48
+
49
+ test('generateTicketCreateSql with status=backlog does not mint an agent_run', () => {
50
+ const { sql, agentRunId } = generateTicketCreateSql({
51
+ accountId: 'acc_1',
52
+ title: 'Later work',
53
+ status: 'backlog',
54
+ });
55
+ assert.equal(agentRunId, null);
56
+ assert.doesNotMatch(sql, /INSERT INTO agentsam_agent_run/);
57
+ });
58
+
59
+ test('generateTicketCreateSql escapes single quotes and truncates the title before escaping (past 240 chars)', () => {
60
+ const longTitle = 'x'.repeat(300) + "'drop";
61
+ const { sql } = generateTicketCreateSql({
62
+ accountId: 'acc_1',
63
+ title: longTitle,
64
+ status: 'backlog',
65
+ });
66
+ // title is sliced to 240 chars BEFORE sql-escaping, so the trailing quote at position 300 never reaches the output
67
+ assert.doesNotMatch(sql, /drop/);
68
+ assert.doesNotMatch(sql, new RegExp('x'.repeat(241)));
69
+ assert.match(sql, new RegExp('x'.repeat(240)));
70
+ });
71
+
72
+ test('generateTicketCreateSql escapes a single quote embedded inside the title itself', () => {
73
+ const { sql } = generateTicketCreateSql({
74
+ accountId: 'acc_1',
75
+ title: "Sam's ticket",
76
+ status: 'backlog',
77
+ });
78
+ assert.match(sql, /Sam''s ticket/);
79
+ });
80
+
81
+ test('generateTicketActivationSql requires account and ticket id', () => {
82
+ assert.throws(() => generateTicketActivationSql({ ticketId: 't' }), /account_id_required/);
83
+ assert.throws(() => generateTicketActivationSql({ accountId: 'a' }), /ticket_id_required/);
84
+ });
85
+
86
+ test('generateTicketActivationSql wires a fresh agent_run and clears closed_at', () => {
87
+ const { sql, agentRunId } = generateTicketActivationSql({
88
+ accountId: 'acc_1',
89
+ ticketId: 'tkt_abc',
90
+ now: 1000,
91
+ });
92
+ assert.ok(agentRunId.startsWith('arun_'));
93
+ assert.match(sql, /status = 'active'/);
94
+ assert.match(sql, /closed_at = NULL/);
95
+ assert.match(sql, /COALESCE\(agent_run_id,/);
96
+ });
97
+
98
+ test('generateTicketCloseSql maps shipped -> completed and abandoned/blocked -> failed run status', () => {
99
+ const shipped = generateTicketCloseSql({ ticketId: 'tkt_1', status: 'shipped', now: 1000 });
100
+ assert.match(shipped.sql, /status = 'completed'/);
101
+ assert.match(shipped.sql, /closed_at = 1000/);
102
+
103
+ const abandoned = generateTicketCloseSql({ ticketId: 'tkt_1', status: 'abandoned', now: 1000 });
104
+ assert.match(abandoned.sql, /status = 'failed'/);
105
+
106
+ const blocked = generateTicketCloseSql({ ticketId: 'tkt_1', status: 'blocked', now: 1000 });
107
+ assert.match(blocked.sql, /status = 'failed'/);
108
+ assert.match(blocked.sql, /closed_at = closed_at/);
109
+ });
110
+
111
+ test('generateTicketCloseSql requires a ticket id', () => {
112
+ assert.throws(() => generateTicketCloseSql({}), /ticket_id_required/);
113
+ });
114
+
115
+ test('generateWorkspaceStateUpsertSql requires repository_id and derives a default workspace id (non-alnum chars become underscores)', () => {
116
+ assert.throws(() => generateWorkspaceStateUpsertSql({}), /repository_id_required/);
117
+ const sql = generateWorkspaceStateUpsertSql({ repositoryId: 'SamPrimeaux/agentsam-sdk' });
118
+ assert.match(sql, /INSERT INTO agentsam_workspace_state/);
119
+ assert.match(sql, /ON CONFLICT\(repository_id\) DO UPDATE SET/);
120
+ assert.match(sql, /ws_SamPrimeaux_agentsam_sdk/);
121
+ });
122
+
123
+ test('generateWorkspaceStateUpsertSql upsert preserves existing values via COALESCE when a field is omitted', () => {
124
+ const sql = generateWorkspaceStateUpsertSql({ repositoryId: 'repo_1', currentTaskId: 'tkt_9' });
125
+ assert.match(sql, /current_task_id = COALESCE\(excluded\.current_task_id, agentsam_workspace_state\.current_task_id\)/);
126
+ assert.match(sql, /'tkt_9'/);
127
+ });
128
+
129
+ test('renderGoapStatus reflects ticket/workspace/run state and falls back gracefully on empty state', () => {
130
+ const out = renderGoapStatus({
131
+ repositoryId: 'SamPrimeaux/agentsam-sdk',
132
+ workspaceState: { locked_by: 'agentsam_cli', current_task_id: 'tkt_1' },
133
+ activeTicket: { id: 'tkt_1', title: 'Ship GOAP', status: 'active', priority: 'P1' },
134
+ agentRun: { id: 'arun_1', status: 'running' },
135
+ git: { branch: 'main', headSha: 'abcdef1234567890', dirty: false },
136
+ });
137
+ assert.match(out, /GOAP BLACKBOARD STATUS/);
138
+ assert.match(out, /Ship GOAP/);
139
+ assert.match(out, /CLEAN/);
140
+
141
+ const empty = renderGoapStatus();
142
+ assert.match(empty, /no active ticket/);
143
+ assert.match(empty, /unlocked/);
144
+ });
145
+
146
+ test('renderGoapGoal / renderGoapWhy / renderGoapPlan render without throwing on minimal state', () => {
147
+ for (const fn of [renderGoapGoal, renderGoapWhy, renderGoapPlan]) {
148
+ const out = fn({ repositoryId: 'repo', activeTicket: {}, workspaceState: {}, agentRun: {}, git: {} });
149
+ assert.equal(typeof out, 'string');
150
+ assert.ok(out.length > 0);
151
+ }
152
+ });
@@ -7,7 +7,6 @@ export const CLOUDFLARE_OAUTH_AUTHORIZE_URL = 'https://dash.cloudflare.com/oauth
7
7
  export const CLOUDFLARE_OAUTH_TOKEN_URL = 'https://dash.cloudflare.com/oauth2/token';
8
8
  export const CLOUDFLARE_CALLBACK_PATH = '/api/connections/cloudflare/callback';
9
9
  export const CLOUDFLARE_FIXTURE_CLIENT_ID = 'sillynotreal';
10
- export const CLOUDFLARE_FIXTURE_CLIENT_SECRET = 'sillynotreal-secret';
11
10
 
12
11
  export const CLOUDFLARE_OAUTH_REVOKE_URL = 'https://dash.cloudflare.com/oauth2/revoke';
13
12
 
@@ -22,7 +21,7 @@ export const CLOUDFLARE_CAPABILITY_SCOPES = Object.freeze({
22
21
  why: 'Inspect D1 databases bound to the deployable.',
23
22
  },
24
23
  r2_inspect: {
25
- scopes: ['workers-r2-storage.read'],
24
+ scopes: ['workers-r2.read'],
26
25
  why: 'Inspect R2 buckets bound to the deployable.',
27
26
  },
28
27
  worker_logs: {
@@ -31,12 +30,200 @@ export const CLOUDFLARE_CAPABILITY_SCOPES = Object.freeze({
31
30
  },
32
31
  });
33
32
 
33
+ // Full scope catalog for the AgentSam Local Studio OAuth client (182 total,
34
+ // pasted directly from the Cloudflare dashboard's own scope picker). This is
35
+ // what gets requested at mint time -- one authorize covers everything the
36
+ // client is provisioned for, rather than a hand-curated subset that has to
37
+ // be edited in code every time a new capability is used. CLOUDFLARE_CAPABILITY_SCOPES
38
+ // above stays as documentation of which specific scopes each feature
39
+ // actually touches -- it no longer restricts what's requested.
40
+ export const CLOUDFLARE_ALL_SCOPES = Object.freeze([
41
+ 'agent-memory.write',
42
+ 'browser-rendering.read',
43
+ 'browser-rendering.write',
44
+ 'cf-agents.read',
45
+ 'cf-agents.write',
46
+ 'cloud-connector.read',
47
+ 'cloud-connector.write',
48
+ 'cloudchamber.read',
49
+ 'cloudchamber.write',
50
+ 'constellation.read',
51
+ 'constellation.write',
52
+ 'd1.read',
53
+ 'd1.write',
54
+ 'flagship.evaluate',
55
+ 'flagship.read',
56
+ 'flagship.write',
57
+ 'query-cache.read',
58
+ 'query-cache.write',
59
+ 'k2.read',
60
+ 'k2.write',
61
+ 'k2.consume',
62
+ 'k2.produce',
63
+ 'mcp-portals.read',
64
+ 'mcp-portals.write',
65
+ 'messaging.edit',
66
+ 'messaging.read',
67
+ 'cfspeed.read',
68
+ 'cfspeed.write',
69
+ 'page.read',
70
+ 'page.write',
71
+ 'pipelines.read',
72
+ 'pipelines.send',
73
+ 'pipelines.write',
74
+ 'pubsub.read',
75
+ 'pubsub.write',
76
+ 'queues.read',
77
+ 'queues.write',
78
+ 'realtime.write',
79
+ 'realtime.admin',
80
+ 'realtime.read',
81
+ 'secrets-store.read',
82
+ 'secrets-store.write',
83
+ 'vectorize.read',
84
+ 'vectorize.write',
85
+ 'workers-ci.read',
86
+ 'workers-ci.write',
87
+ 'containers.read',
88
+ 'containers.write',
89
+ 'workers-kv-storage.read',
90
+ 'workers-kv-storage.write',
91
+ 'workers-observability.read',
92
+ 'workers-observability-telemetry.write',
93
+ 'workers-observability.write',
94
+ 'r2-catalog.read',
95
+ 'r2-catalog.write',
96
+ 'r2-catalog-sql.read',
97
+ 'workers-r2-bucket-item.read',
98
+ 'workers-r2-bucket-item.write',
99
+ 'workers-r2.read',
100
+ 'workers-r2.write',
101
+ 'workers-routes.read',
102
+ 'workers-routes.write',
103
+ 'workers-scripts.read',
104
+ 'workers-scripts.write',
105
+ 'workers-tail.read',
106
+ 'aiaudit.read',
107
+ 'aiaudit.write',
108
+ 'aig.read',
109
+ 'aig.run',
110
+ 'aig.write',
111
+ 'ai-search.index',
112
+ 'ai-search.read',
113
+ 'ai-search.run',
114
+ 'ai-search.write',
115
+ 'agw.read',
116
+ 'agw.run',
117
+ 'agw.write',
118
+ 'rag.read',
119
+ 'rag.write',
120
+ 'rag.run',
121
+ 'firewall-for-ai.read',
122
+ 'firewall-for-ai.write',
123
+ 'websearch.read',
124
+ 'websearch.run',
125
+ 'websearch.write',
126
+ 'ai-model.read',
127
+ 'ai-model.write',
128
+ 'ai.read',
129
+ 'ai.write',
130
+ 'account-dns-settings.read',
131
+ 'account-dns-settings.write',
132
+ 'dns-firewall.read',
133
+ 'dns-firewall.write',
134
+ 'dns.read',
135
+ 'dns-view.read',
136
+ 'dns-view.write',
137
+ 'dns.write',
138
+ 'registrar-domains.admin',
139
+ 'registrar-domains.read',
140
+ 'registrar-sandbox-domains.admin',
141
+ 'registrar-sandbox-domains.read',
142
+ 'zone-custom-asset.read',
143
+ 'zone-custom-asset.write',
144
+ 'zone-dns-settings.read',
145
+ 'zone-dns-settings.write',
146
+ 'zone.read',
147
+ 'zone-settings.read',
148
+ 'zone-settings.write',
149
+ 'zone-versioning.read',
150
+ 'zone-versioning.write',
151
+ 'zone.write',
152
+ 'fraud-detection-pii.read',
153
+ 'account-firewall-access-rules.read',
154
+ 'account-firewall-access-rules.write',
155
+ 'account-security-center-insights.read',
156
+ 'account-security-center-insights.write',
157
+ 'account-waf.read',
158
+ 'account-waf.write',
159
+ 'request-tracer.read',
160
+ 'reports-application-security-report.read',
161
+ 'bot-management-feedback.read',
162
+ 'bot-management-feedback.write',
163
+ 'bot-management.read',
164
+ 'bot-management.write',
165
+ 'http-applications.read',
166
+ 'http-applications.write',
167
+ 'http-ddos-managed-ruleset.read',
168
+ 'http-ddos-managed-ruleset.write',
169
+ 'tag.read',
170
+ 'tag.write',
171
+ 'url-scanner.read',
172
+ 'url-scanner.write',
173
+ 'zone-security-center-insights.read',
174
+ 'zone-security-center-insights.write',
175
+ 'zone-waf.read',
176
+ 'zone-waf.write',
177
+ 'account-custom-error-rules.read',
178
+ 'account-custom-error-rules.write',
179
+ 'account-custom-pages.read',
180
+ 'account-custom-pages.write',
181
+ 'account-rule-lists.read',
182
+ 'account-rule-lists.write',
183
+ 'account-rulesets.read',
184
+ 'account-rulesets.write',
185
+ 'config-settings.read',
186
+ 'config-settings.write',
187
+ 'custom-errors.read',
188
+ 'custom-errors.write',
189
+ 'custom-pages.read',
190
+ 'custom-pages.write',
191
+ 'dynamic-redirect.read',
192
+ 'dynamic-redirect.write',
193
+ 'managed-headers.read',
194
+ 'managed-headers.write',
195
+ 'mass-url-redirects.read',
196
+ 'mass-url-redirects.write',
197
+ 'origin.read',
198
+ 'origin.write',
199
+ 'payments-gateway.read',
200
+ 'payments-gateway.write',
201
+ 'account-ssl-and-certificates.read',
202
+ 'account-ssl-and-certificates.write',
203
+ 'cache.purge',
204
+ 'cache-settings.read',
205
+ 'cache-settings.write',
206
+ 'ssl-and-certificates.read',
207
+ 'ssl-and-certificates.write',
208
+ 'account-api-gateway.write',
209
+ 'account-api-gateway.read',
210
+ 'account-custom-asset.read',
211
+ 'account-custom-asset.write',
212
+ 'account-settings.read',
213
+ 'account-settings.write',
214
+ 'apps.write',
215
+ 'integration.write',
216
+ 'memberships.read',
217
+ 'memberships.write',
218
+ 'notifications.read',
219
+ 'notifications.write',
220
+ 'scim-provisioning.write',
221
+ 'user-details.read',
222
+ 'offline_access'
223
+ ]);
224
+
34
225
  export function requestedCloudflareScopes() {
35
- const set = new Set();
36
- for (const cap of Object.values(CLOUDFLARE_CAPABILITY_SCOPES)) {
37
- for (const scope of cap.scopes) set.add(scope);
38
- }
39
- return [...set];
226
+ return [...CLOUDFLARE_ALL_SCOPES];
40
227
  }
41
228
 
42
229
  function clean(value) {
@@ -45,14 +232,17 @@ function clean(value) {
45
232
 
46
233
  export function isFixtureCloudflareCredential(value) {
47
234
  const v = clean(value);
48
- return v === CLOUDFLARE_FIXTURE_CLIENT_ID || v === CLOUDFLARE_FIXTURE_CLIENT_SECRET;
235
+ return v === CLOUDFLARE_FIXTURE_CLIENT_ID;
49
236
  }
50
237
 
51
238
  export function resolveCloudflareOAuthClient(env = {}) {
52
239
  const clientId = clean(env.CLOUDFLARE_OAUTH_CLIENT_ID);
53
- const clientSecret = clean(env.CLOUDFLARE_OAUTH_CLIENT_SECRET);
54
- const present = Boolean(clientId && clientSecret);
55
- const fixture = isFixtureCloudflareCredential(clientId) || isFixtureCloudflareCredential(clientSecret);
240
+ // AgentSam Local Studio uses Cloudflare's public PKCE client. It must never
241
+ // read a client secret: stale Worker secrets would turn an otherwise valid
242
+ // PKCE exchange into an invalid mixed-auth request. Confidential Cloudflare
243
+ // clients belong to their owning host adapter, not this connector.
244
+ const present = Boolean(clientId);
245
+ const fixture = isFixtureCloudflareCredential(clientId);
56
246
  if (!present) {
57
247
  return {
58
248
  configured: false,
@@ -60,7 +250,7 @@ export function resolveCloudflareOAuthClient(env = {}) {
60
250
  fixture: false,
61
251
  status: 'not_configured',
62
252
  clientIdConfigured: Boolean(clientId),
63
- secretConfigured: Boolean(clientSecret),
253
+ tokenAuthMethod: 'none_pkce',
64
254
  };
65
255
  }
66
256
  return {
@@ -69,20 +259,20 @@ export function resolveCloudflareOAuthClient(env = {}) {
69
259
  fixture,
70
260
  status: fixture ? 'fixture' : 'ready',
71
261
  clientIdConfigured: true,
72
- secretConfigured: true,
262
+ tokenAuthMethod: 'none_pkce',
73
263
  };
74
264
  }
75
265
 
76
266
  export function cloudflareConnectionSafeStatus(env = {}, connection = null, ownerId = '') {
77
267
  const client = resolveCloudflareOAuthClient(env);
78
- const record = connection && connection.ownerId === ownerId ? connection : null;
268
+ const record = connection && connection.ownerId === ownerId && connection.status === 'connected' ? connection : null;
79
269
  return {
80
270
  provider: 'cloudflare',
81
271
  status: record ? 'connected' : client.status === 'ready' ? 'ready' : client.status,
82
272
  configured: client.configured && client.productionReady,
83
273
  fixture: client.fixture,
84
274
  clientId: client.clientIdConfigured ? 'configured' : 'missing',
85
- secret: client.secretConfigured ? 'configured' : 'missing',
275
+ token_auth_method: client.tokenAuthMethod,
86
276
  callbackPath: CLOUDFLARE_CALLBACK_PATH,
87
277
  connection: record
88
278
  ? {
@@ -113,6 +303,98 @@ export function assertConnectionOwner(connection, ownerId) {
113
303
  return connection;
114
304
  }
115
305
 
306
+ export async function loadCloudflareAccessToken(env, ownerId, options = {}) {
307
+ if (!env?.DB || !ownerId) return null;
308
+ const row = await env.DB.prepare(`
309
+ SELECT connection_id, owner_id, cloudflare_account_id, scopes, status,
310
+ access_token_encrypted, refresh_token_encrypted, expires_at
311
+ FROM agentsam_cloudflare_connections
312
+ WHERE owner_id = ? AND status = 'connected'
313
+ ORDER BY updated_at DESC LIMIT 1
314
+ `).bind(ownerId).first();
315
+ if (!row?.access_token_encrypted || row.owner_id !== ownerId) return null;
316
+ const { decryptSecret, sealToken } = await import('./vault.js');
317
+ const aad = `cloudflare-connection:${ownerId}`;
318
+ let accessToken = await decryptSecret(env, row.access_token_encrypted, aad);
319
+ let refreshToken = row.refresh_token_encrypted
320
+ ? await decryptSecret(env, row.refresh_token_encrypted, aad)
321
+ : '';
322
+ let expiresAt = Number(row.expires_at || 0) || null;
323
+ let scopes = row.scopes ? String(row.scopes).split(' ').filter(Boolean) : [];
324
+ const now = Math.floor(Date.now() / 1000);
325
+ if (expiresAt && expiresAt <= now + 60) {
326
+ if (!refreshToken) throw new Error('cloudflare_refresh_token_missing');
327
+ const refreshParams = new URLSearchParams({
328
+ grant_type: 'refresh_token',
329
+ refresh_token: refreshToken,
330
+ client_id: String(env.CLOUDFLARE_OAUTH_CLIENT_ID || ''),
331
+ });
332
+ const refreshResponse = await (options.fetchImpl || fetch)(CLOUDFLARE_OAUTH_TOKEN_URL, {
333
+ method: 'POST',
334
+ headers: { 'content-type': 'application/x-www-form-urlencoded' },
335
+ body: refreshParams,
336
+ });
337
+ if (!refreshResponse.ok) throw new Error(`cloudflare_token_refresh_failed:${refreshResponse.status}`);
338
+ const refreshed = await refreshResponse.json();
339
+ if (!refreshed?.access_token) throw new Error('cloudflare_token_refresh_missing_access_token');
340
+ accessToken = refreshed.access_token;
341
+ refreshToken = refreshed.refresh_token || refreshToken;
342
+ scopes = String(refreshed.scope || row.scopes || '').split(' ').filter(Boolean);
343
+ expiresAt = refreshed.expires_in ? now + Number(refreshed.expires_in) : null;
344
+ const [accessEncrypted, refreshEncrypted] = await Promise.all([
345
+ sealToken(env, accessToken, aad),
346
+ sealToken(env, refreshToken, aad),
347
+ ]);
348
+ await env.DB.prepare(`
349
+ UPDATE agentsam_cloudflare_connections
350
+ SET access_token_encrypted = ?, refresh_token_encrypted = ?, scopes = ?,
351
+ expires_at = ?, status = 'connected', updated_at = unixepoch()
352
+ WHERE connection_id = ? AND owner_id = ?
353
+ `).bind(accessEncrypted, refreshEncrypted, scopes.join(' '), expiresAt, row.connection_id, ownerId).run();
354
+ }
355
+ return {
356
+ accessToken,
357
+ connectionId: row.connection_id,
358
+ accountId: row.cloudflare_account_id || null,
359
+ scopes,
360
+ expiresAt,
361
+ };
362
+ }
363
+
364
+ export async function probeCloudflareConnection(env, ownerId, options = {}) {
365
+ const startedAt = Date.now();
366
+ const checkedAt = Math.floor(startedAt / 1000);
367
+ try {
368
+ const connection = await loadCloudflareAccessToken(env, ownerId, options);
369
+ if (!connection) return { status: 'auth_error', healthy: false, checked_at: checkedAt, error_code: 'cloudflare_connection_missing' };
370
+ const response = await (options.fetchImpl || fetch)('https://dash.cloudflare.com/oauth2/userinfo', {
371
+ headers: { authorization: `Bearer ${connection.accessToken}`, accept: 'application/json' },
372
+ signal: typeof AbortSignal?.timeout === 'function' ? AbortSignal.timeout(5000) : undefined,
373
+ });
374
+ const body = await response.json().catch(() => null);
375
+ const healthy = response.ok && body?.error == null;
376
+ return {
377
+ status: healthy ? 'healthy' : response.status === 401 || response.status === 403 ? 'auth_error' : 'unhealthy',
378
+ healthy,
379
+ checked_at: checkedAt,
380
+ latency_ms: Date.now() - startedAt,
381
+ http_status: response.status,
382
+ provider_request_id: response.headers.get('cf-ray') || null,
383
+ account_id: connection.accountId,
384
+ scopes: connection.scopes,
385
+ error_code: healthy
386
+ ? null
387
+ : body?.error || (body?.errors?.[0]?.code ? String(body.errors[0].code) : `cloudflare_http_${response.status}`),
388
+ error_message: healthy ? null : body?.error_description || body?.errors?.[0]?.message || 'Cloudflare OAuth probe failed',
389
+ };
390
+ } catch (error) {
391
+ return {
392
+ status: 'unreachable', healthy: false, checked_at: checkedAt, latency_ms: Date.now() - startedAt,
393
+ error_code: 'cloudflare_probe_failed', error_message: String(error?.message || error).slice(0, 240),
394
+ };
395
+ }
396
+ }
397
+
116
398
  export function buildAuthorizeUrl({ clientId, redirectUri, state, codeChallenge, scopes }) {
117
399
  const params = new URLSearchParams({
118
400
  response_type: 'code',
@@ -1,20 +1,23 @@
1
1
  /**
2
- * Cloudflare connection ownership is derived from authenticated AgentSam session.
2
+ * Cloudflare connection ownership is derived from the REAL AgentSam identity
3
+ * session (packages/identity — the same `session` cookie set by
4
+ * /api/auth/login and every OAuth login callback). This previously
5
+ * hand-rolled its own cookie name (`agentsam_session`) and session table
6
+ * names (`agentsam_sessions`/`sessions`/`identity_sessions`) that never
7
+ * matched the actual identity system (cookie name `session`, sessions
8
+ * resolved via identity.sessionFromRequest against the real adapter) — so
9
+ * this connector could never actually authenticate anyone. Fixed to call
10
+ * the real identity service instead of guessing at its storage shape.
11
+ *
3
12
  * Browser-submitted account_id / user_id / owner_id / X-User-Id are never authority.
4
13
  */
5
14
 
6
- const UNTRUSTED = new Set(['account_id', 'user_id', 'owner_id', 'workspace_id']);
15
+ import { createIdentityService, createCloudflareD1Adapter } from '../../../identity/src/server/worker-router.js';
16
+ import { fetchIamProfile } from '../../../identity/src/providers/iam/profile.js';
17
+ import { normalizeIamIdentity } from '../../../identity/src/providers/iam/mapper.js';
18
+ import { resolveIamIssuer } from '../../../identity/src/contracts/auth-config.js';
7
19
 
8
- export function extractSessionToken(request) {
9
- const auth = request.headers.get('authorization') || '';
10
- if (/^bearer\s+/i.test(auth)) {
11
- const token = auth.replace(/^bearer\s+/i, '').trim();
12
- if (token && !token.startsWith('cf_') && token !== 'sillynotreal-secret') return token;
13
- }
14
- const cookie = request.headers.get('cookie') || '';
15
- const match = cookie.match(/(?:^|;\s*)agentsam_session=([^;]+)/);
16
- return match ? decodeURIComponent(match[1]).trim() : '';
17
- }
20
+ const UNTRUSTED = new Set(['account_id', 'user_id', 'owner_id', 'workspace_id']);
18
21
 
19
22
  export function rejectUntrustedOwnerHints(request, url, body = {}) {
20
23
  const headerUser = (request.headers.get('x-user-id') || '').trim();
@@ -36,40 +39,40 @@ export function rejectUntrustedOwnerHints(request, url, body = {}) {
36
39
 
37
40
  export async function resolveAuthenticatedOwner(request, env, url, body) {
38
41
  rejectUntrustedOwnerHints(request, url, body);
39
- const sessionToken = extractSessionToken(request);
40
- if (!sessionToken) {
42
+ // Test/portable adapters may expose an in-memory session map. Keep this
43
+ // compatibility lane deliberately opt-in; production authority is D1.
44
+ const fixtureToken = (request.headers.get('authorization') || '').replace(/^Bearer\s+/i, '').trim();
45
+ const fixtureCookie = (request.headers.get('cookie') || '').match(/(?:^|;\s*)agentsam_session=([^;]+)/)?.[1] || '';
46
+ if (env?.fixtureSessions instanceof Map) {
47
+ const fixtureOwner = env.fixtureSessions.get(fixtureToken || fixtureCookie);
48
+ if (fixtureOwner) return String(fixtureOwner);
49
+ }
50
+ if (!env?.DB) {
41
51
  const err = new Error('unauthenticated');
42
52
  err.code = 'unauthenticated';
43
53
  throw err;
44
54
  }
45
- if (env?.sessions instanceof Map) {
46
- const owner = env.sessions.get(sessionToken);
47
- if (!owner) {
48
- const err = new Error('unauthenticated');
49
- err.code = 'unauthenticated';
50
- throw err;
51
- }
52
- return String(owner);
53
- }
54
- if (env?.DB?.prepare) {
55
- const tables = [
56
- ['agentsam_sessions', 'session_token', 'user_id'],
57
- ['sessions', 'id', 'user_id'],
58
- ['identity_sessions', 'session_token', 'user_id'],
59
- ];
60
- for (const [table, tokenCol, userCol] of tables) {
61
- try {
62
- const row = await env.DB.prepare(
63
- `SELECT ${userCol} AS user_id FROM ${table} WHERE ${tokenCol} = ? LIMIT 1`,
64
- )
65
- .bind(sessionToken)
66
- .first();
67
- if (row?.user_id) return String(row.user_id);
68
- } catch {
69
- // table may not exist yet
70
- }
55
+ const adapter = createCloudflareD1Adapter(env.DB);
56
+ const identity = createIdentityService({ adapter, env });
57
+ const ctx = await identity.sessionFromRequest(request);
58
+ if (ctx?.user?.id) return String(ctx.user.id);
59
+
60
+ // Native CLI OAuth returns a bearer access token rather than a browser
61
+ // cookie. Resolve that token through IAM userinfo, then map the verified
62
+ // IAM subject to the local auth user. No caller-supplied owner id is used.
63
+ const bearer = (request.headers.get('authorization') || '').replace(/^Bearer\s+/i, '').trim();
64
+ if (bearer) {
65
+ const profile = await fetchIamProfile({
66
+ issuer: resolveIamIssuer(env),
67
+ accessToken: bearer,
68
+ });
69
+ const identityProfile = profile ? normalizeIamIdentity(profile) : null;
70
+ if (identityProfile?.subject) {
71
+ const user = await adapter.findUserByProvider('iam', identityProfile.subject);
72
+ if (user?.id) return String(user.id);
71
73
  }
72
74
  }
75
+
73
76
  const err = new Error('unauthenticated');
74
77
  err.code = 'unauthenticated';
75
78
  throw err;