@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
@@ -1,14 +1,24 @@
1
1
  import pc from 'picocolors';
2
+ import { isCancel, select } from '@clack/prompts';
2
3
  import { probeOllama, resolveOllamaConfig } from './ollama.js';
3
4
  import { listModelCatalog } from '../models/index.js';
4
5
  import { discoverProviderModels } from '../models/discovery.js';
5
6
  import { resolveProviderCredential } from '../lib/provider-credentials.js';
7
+ import { providerChoices, promptAndConfigureProvider } from './providers.js';
8
+ import {
9
+ WORKERS_AI_CURATED_MODEL_IDS,
10
+ filterWorkersAiCurated,
11
+ sanitizeInventoryForClient,
12
+ } from '../models/inventory-core.js';
13
+
14
+ export { WORKERS_AI_CURATED_MODEL_IDS, filterWorkersAiCurated, sanitizeInventoryForClient };
6
15
 
7
16
  export const API_PROVIDERS = Object.freeze([
8
17
  { id: 'openai', label: 'OpenAI', credential: 'OPENAI_API_KEY' },
9
18
  { id: 'anthropic', label: 'Anthropic', credential: 'ANTHROPIC_API_KEY' },
10
19
  { id: 'gemini', label: 'Gemini', credential: 'GEMINI_API_KEY' },
11
20
  { id: 'grok', label: 'Grok / xAI', credential: 'XAI_API_KEY' },
21
+ { id: 'cursor', label: 'Cursor', credential: 'CURSOR_API_KEY' },
12
22
  { id: 'cloudflare', label: 'Cloudflare', credential: 'CLOUDFLARE_API_TOKEN' },
13
23
  ]);
14
24
 
@@ -55,18 +65,34 @@ function mergeStaticFallbacks(discovered = []) {
55
65
  return out;
56
66
  }
57
67
 
68
+ /**
69
+ * Build credential-scoped model inventory.
70
+ *
71
+ * @param {object} [options]
72
+ * @param {Record<string, string>} [options.env]
73
+ * @param {string} [options.home]
74
+ * @param {boolean} [options.discoverRemote]
75
+ * @param {'machine'|'studio_vault'|'mixed'} [options.credentialPlane]
76
+ * @param {(providerId: string) => Promise<object|null>|object|null} [options.resolveCredential]
77
+ * Injected resolver (Studio vault). When omitted, uses machine env.d / process env.
78
+ * @param {boolean} [options.curateWorkersAi] default true — intersect Cloudflare models with curated allowlist
79
+ * @param {boolean} [options.includeLocal] default true — probe Ollama (machine plane only by default)
80
+ */
58
81
  export async function collectModelsStatus(options = {}) {
59
82
  const env = options.env || process.env;
60
83
  const ollamaFetchImpl = options.fetchImpl || fetch;
61
84
  const providerFetchImpl = options.providerFetchImpl || fetch;
62
- const ollamaConfig = resolveOllamaConfig({}, env);
63
- const ollama = await probeOllama(ollamaConfig, ollamaFetchImpl);
64
- const credentials = new Map(
65
- API_PROVIDERS.map((provider) => [
66
- provider.id,
67
- resolveProviderCredential(provider.id, { env, home: options.home }),
68
- ]),
69
- );
85
+ const credentialPlane = options.credentialPlane || (options.resolveCredential ? 'studio_vault' : 'machine');
86
+ const includeLocal = options.includeLocal ?? credentialPlane === 'machine';
87
+ const curateWorkersAi = options.curateWorkersAi !== false;
88
+
89
+ const resolveCredential = options.resolveCredential
90
+ || ((providerId) => resolveProviderCredential(providerId, { env, home: options.home }));
91
+
92
+ const credentials = new Map();
93
+ for (const provider of API_PROVIDERS) {
94
+ credentials.set(provider.id, await resolveCredential(provider.id));
95
+ }
70
96
 
71
97
  const providers = API_PROVIDERS.map((provider) => {
72
98
  const credential = credentials.get(provider.id);
@@ -84,10 +110,20 @@ export async function collectModelsStatus(options = {}) {
84
110
 
85
111
  await Promise.all(API_PROVIDERS.map(async (provider) => {
86
112
  const credential = credentials.get(provider.id);
87
- const result = shouldDiscover && credential?.configured
113
+ let result = shouldDiscover && credential?.configured
88
114
  ? await discoverProviderModels(provider.id, credential, { fetchImpl: providerFetchImpl })
89
115
  : emptyDiscovery();
116
+ if (provider.id === 'cloudflare' && result.ok && curateWorkersAi) {
117
+ const curated = filterWorkersAiCurated(result.models || [], { curated: true });
118
+ result = {
119
+ ...result,
120
+ models: curated,
121
+ returnedModelCount: curated.length,
122
+ curation: 'agentsam_workers_ai_allowlist',
123
+ };
124
+ }
90
125
  discovery[provider.id] = providerSummary(result);
126
+ if (result.curation) discovery[provider.id].curation = result.curation;
91
127
  providerModels[provider.id] = result.models || [];
92
128
  }));
93
129
 
@@ -95,25 +131,42 @@ export async function collectModelsStatus(options = {}) {
95
131
  const exactAvailable = discovered.filter((row) => row.availability === 'available');
96
132
  const catalogModels = mergeStaticFallbacks(discovered);
97
133
 
134
+ let local = {
135
+ provider: 'ollama',
136
+ configured: false,
137
+ online: false,
138
+ endpoint: null,
139
+ chatModel: null,
140
+ embedModel: null,
141
+ models: [],
142
+ error: null,
143
+ };
144
+ if (includeLocal) {
145
+ const ollamaConfig = resolveOllamaConfig({}, env);
146
+ const ollama = await probeOllama(ollamaConfig, ollamaFetchImpl);
147
+ local = {
148
+ provider: 'ollama',
149
+ configured: ollama.online,
150
+ online: ollama.online,
151
+ endpoint: ollama.endpoint,
152
+ chatModel: ollamaConfig.model,
153
+ embedModel: ollamaConfig.embedModel,
154
+ models: ollama.models || [],
155
+ error: ollama.error || null,
156
+ };
157
+ }
158
+
98
159
  return {
99
160
  schemaVersion: 'agentsam-model-inventory-v3',
100
161
  generatedAt: new Date().toISOString(),
101
162
  authority: 'per_credential_provider_discovery',
163
+ credential_plane: credentialPlane,
102
164
  providers,
103
165
  discovery,
104
166
  providerModels,
105
167
  catalogModels,
106
168
  availableModels: exactAvailable,
107
- local: {
108
- provider: 'ollama',
109
- configured: ollama.online,
110
- online: ollama.online,
111
- endpoint: ollama.endpoint,
112
- chatModel: ollamaConfig.model,
113
- embedModel: ollamaConfig.embedModel,
114
- models: ollama.models || [],
115
- error: ollama.error || null,
116
- },
169
+ local,
117
170
  };
118
171
  }
119
172
 
@@ -176,6 +229,10 @@ export function renderModelsStatus(status) {
176
229
  if (names.length > 30) lines.push(` ${pc.dim(`… ${names.length - 30} more`)}`);
177
230
  }
178
231
 
232
+ const unconfiguredCount = status.providers.filter((p) => !p.configured).length;
233
+ if (unconfiguredCount > 0) {
234
+ lines.push(` ${pc.yellow('Tip:')} Select your preferred provider to continue, or run 'agentsam providers'.`);
235
+ }
179
236
  lines.push('');
180
237
  lines.push(` ${pc.dim('Use /model inside Agent Sam. The picker is built from the models visible to your own connected provider credentials.')}`);
181
238
  lines.push('');
@@ -185,7 +242,7 @@ export function renderModelsStatus(status) {
185
242
  export async function runModels(argv = [], options = {}) {
186
243
  if (argv.some((arg) => arg === '--help' || arg === '-h')) {
187
244
  const text = [
188
- 'agentsam models [--json] [--no-discover]',
245
+ 'agentsam models [--json] [--no-discover] [--setup]',
189
246
  '',
190
247
  'Probe the provider accounts configured on this machine and list the models visible to those exact credentials.',
191
248
  'Context/output limits are taken from provider metadata when available; otherwise Agent Sam reports unknown or a clearly-labeled SDK reference.',
@@ -195,7 +252,7 @@ export async function runModels(argv = [], options = {}) {
195
252
  return;
196
253
  }
197
254
 
198
- const allowed = new Set(['--json', '--no-discover']);
255
+ const allowed = new Set(['--json', '--no-discover', '--setup']);
199
256
  const unknown = argv.filter((arg) => !allowed.has(arg));
200
257
  if (unknown.length) throw new Error(`unknown models option: ${unknown[0]}`);
201
258
 
@@ -204,7 +261,36 @@ export async function runModels(argv = [], options = {}) {
204
261
  discoverRemote: !argv.includes('--no-discover'),
205
262
  });
206
263
  const write = options.write || ((text) => process.stdout.write(text));
207
- if (argv.includes('--json')) writeLine(write, JSON.stringify(status, null, 2));
208
- else write(renderModelsStatus(status));
264
+ if (argv.includes('--json')) {
265
+ writeLine(write, JSON.stringify(status, null, 2));
266
+ return status;
267
+ }
268
+ write(renderModelsStatus(status));
269
+
270
+ const allUnconfigured = status.providers.every((p) => !p.configured);
271
+ const interactive = options.interactive ?? Boolean(process.stdin.isTTY && process.stdout.isTTY);
272
+ if (interactive && (argv.includes('--setup') || allUnconfigured)) {
273
+ const promptSelect = options.selectImpl || select;
274
+ const choices = [
275
+ ...providerChoices(options),
276
+ { value: '__skip__', label: 'Skip / Continue', hint: 'set up provider credentials later' },
277
+ ];
278
+ const choice = await promptSelect({
279
+ message: 'Tip: Select your preferred provider to continue',
280
+ options: choices,
281
+ });
282
+ if (!isCancel(choice) && choice !== '__skip__') {
283
+ const result = await promptAndConfigureProvider(choice, options);
284
+ if (result?.saved) {
285
+ const updated = await collectModelsStatus({
286
+ ...options,
287
+ discoverRemote: !argv.includes('--no-discover'),
288
+ });
289
+ write(renderModelsStatus(updated));
290
+ return updated;
291
+ }
292
+ }
293
+ }
294
+
209
295
  return status;
210
296
  }
@@ -0,0 +1,175 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { AGENTSAM_MCP_PLUGIN_MANIFEST, normalizePluginKey } from '../plugins/index.js';
4
+ import { authenticateViaBrowser } from '../lib/auth.js';
5
+ import { promptToOpenUrl } from '../lib/open-url.js';
6
+ import { readAccountSession, resolveAccountApiKey, saveAccountSession } from '../lib/account-session.js';
7
+
8
+ const CATALOG = Object.freeze({ 'agentsam-mcp': AGENTSAM_MCP_PLUGIN_MANIFEST });
9
+ const PLUGIN_MIGRATION = '0001_agentsam_plugin_runtime.sql';
10
+
11
+ function statePath(cwd) { return path.join(path.resolve(cwd), '.agentsam', 'plugins.json'); }
12
+ function readState(cwd) {
13
+ const filename = statePath(cwd);
14
+ if (!fs.existsSync(filename)) return { schema_version: 1, plugins: {} };
15
+ const parsed = JSON.parse(fs.readFileSync(filename, 'utf8'));
16
+ return { schema_version: 1, plugins: parsed?.plugins || {} };
17
+ }
18
+
19
+ function installMigration(cwd) {
20
+ const source = new URL(`../../migrations/d1/${PLUGIN_MIGRATION}`, import.meta.url);
21
+ const migrationsDir = path.join(path.resolve(cwd), 'migrations', 'd1');
22
+ const destination = path.join(migrationsDir, PLUGIN_MIGRATION);
23
+ fs.mkdirSync(migrationsDir, { recursive: true });
24
+ if (!fs.existsSync(destination)) fs.copyFileSync(source, destination);
25
+ return path.relative(path.resolve(cwd), destination);
26
+ }
27
+ function parse(argv) {
28
+ const out = {
29
+ action: argv[0] || 'list', key: '', cwd: process.cwd(), json: false,
30
+ origin: process.env.AGENTSAM_ORIGIN || process.env.AGENTSAM_API_ORIGIN || 'https://agentsam.inneranimalmedia.com',
31
+ timeoutMs: 180_000, noOpen: false,
32
+ };
33
+ for (let i = 1; i < argv.length; i += 1) {
34
+ if (argv[i] === '--cwd') out.cwd = argv[++i] || out.cwd;
35
+ else if (argv[i] === '--json') out.json = true;
36
+ else if (argv[i] === '--origin') out.origin = argv[++i] || out.origin;
37
+ else if (argv[i] === '--timeout') out.timeoutMs = Math.max(1_000, Number(argv[++i]) || out.timeoutMs);
38
+ else if (argv[i] === '--no-open') out.noOpen = true;
39
+ else if (!out.key) out.key = argv[i];
40
+ else throw new Error(`unknown plugins option:${argv[i]}`);
41
+ }
42
+ return out;
43
+ }
44
+
45
+ function writeJson(value) { process.stdout.write(`${JSON.stringify(value, null, 2)}\n`); }
46
+
47
+ async function resolveCliBearer(opts) {
48
+ const apiKey = resolveAccountApiKey();
49
+ if (apiKey.value) return { token: apiKey.value, source: apiKey.source };
50
+ let session = readAccountSession();
51
+ if (!session?.access_token) {
52
+ if (opts.json) writeJson({ ok: false, step: 'account_login_required' });
53
+ else console.log('\n No AgentSam account session found. Opening account sign-in first.\n');
54
+ session = await authenticateViaBrowser();
55
+ if (!readAccountSession()) saveAccountSession(session);
56
+ }
57
+ if (!session?.access_token) throw new Error('account_login_did_not_return_access_token');
58
+ return { token: session.access_token, source: 'agentsam_browser_oauth' };
59
+ }
60
+
61
+ async function fetchConnector(opts, token, pathname, init = {}) {
62
+ const origin = String(opts.origin).replace(/\/$/, '');
63
+ const headers = new Headers(init.headers || {});
64
+ headers.set('accept', 'application/json');
65
+ headers.set('authorization', `Bearer ${token}`);
66
+ return fetch(`${origin}${pathname}`, { ...init, headers });
67
+ }
68
+
69
+ async function connectPlugin(opts, key) {
70
+ if (key !== 'agentsam-mcp') throw new Error(`plugin_connect_not_supported:${key}`);
71
+ const state = readState(opts.cwd);
72
+ if (!state.plugins[key]) {
73
+ state.plugins[key] = { plugin_key: key, installed_at: new Date().toISOString(), manifest: CATALOG[key] };
74
+ fs.mkdirSync(path.dirname(statePath(opts.cwd)), { recursive: true, mode: 0o700 });
75
+ fs.writeFileSync(statePath(opts.cwd), `${JSON.stringify(state, null, 2)}\n`, { mode: 0o600 });
76
+ installMigration(opts.cwd);
77
+ if (!opts.json) console.log(`\n Installed @${key}.`);
78
+ }
79
+
80
+ const { token } = await resolveCliBearer(opts);
81
+ const start = await fetchConnector(opts, token, '/api/connections/cloudflare/start');
82
+ const startBody = await start.json().catch(() => ({}));
83
+ if (!start.ok || !startBody.authorize_url) {
84
+ throw new Error(`plugin_connect_start_failed:${startBody.error || start.status}`);
85
+ }
86
+
87
+ if (!opts.json) {
88
+ console.log('\n Connect @agentsam-mcp to Cloudflare');
89
+ console.log(' Your browser will ask you to approve the requested Cloudflare access.');
90
+ }
91
+ if (opts.noOpen) {
92
+ process.stdout.write(`${startBody.authorize_url}\n`);
93
+ } else {
94
+ await promptToOpenUrl(startBody.authorize_url, {
95
+ heading: 'Open Cloudflare authorization:',
96
+ prompt: 'Press ENTER to open Cloudflare in your browser, or copy the URL above.',
97
+ });
98
+ }
99
+
100
+ const started = Date.now();
101
+ let statusBody = {};
102
+ while (Date.now() - started < opts.timeoutMs) {
103
+ const status = await fetchConnector(opts, token, '/api/connections/cloudflare');
104
+ statusBody = await status.json().catch(() => ({}));
105
+ if (statusBody?.status === 'connected' || statusBody?.connection?.status === 'connected') break;
106
+ if (!opts.json) process.stdout.write('.');
107
+ await new Promise((resolve) => setTimeout(resolve, 2_000));
108
+ }
109
+ const connected = statusBody?.status === 'connected' || statusBody?.connection?.status === 'connected';
110
+ const result = {
111
+ ok: connected,
112
+ action: 'connect',
113
+ plugin_key: key,
114
+ provider: 'cloudflare',
115
+ status: connected ? 'connected' : (statusBody?.status || 'pending'),
116
+ cloudflare_account_id: statusBody?.cloudflareAccountId
117
+ || statusBody?.connection?.cloudflareAccountId
118
+ || statusBody?.connection?.cloudflare_account_id
119
+ || null,
120
+ scopes: statusBody?.scopes || statusBody?.connection?.scopes || [],
121
+ };
122
+ if (opts.json) writeJson(result);
123
+ else console.log(connected ? `\n\n ✓ Connected @${key}\n` : `\n\n Authorization is still pending. Run \'agentsam plugins status @${key}\' to check again.\n`);
124
+ return result;
125
+ }
126
+
127
+ async function statusPlugin(opts, key) {
128
+ if (key !== 'agentsam-mcp') throw new Error(`unknown_plugin:${key}`);
129
+ const { token } = await resolveCliBearer(opts);
130
+ const response = await fetchConnector(opts, token, '/api/connections/cloudflare');
131
+ const body = await response.json().catch(() => ({}));
132
+ if (!response.ok) throw new Error(`plugin_status_failed:${body.error || response.status}`);
133
+ const result = { ok: true, plugin_key: key, provider: 'cloudflare', ...body };
134
+ if (opts.json) writeJson(result);
135
+ else console.log(`\n ${result.status === 'connected' ? '✓' : '○'} @${key} ${result.status || 'not_configured'}\n`);
136
+ return result;
137
+ }
138
+
139
+ export async function runPlugins(argv = []) {
140
+ const opts = parse(argv);
141
+ if (opts.action === 'list') {
142
+ const state = readState(opts.cwd);
143
+ const rows = Object.values(CATALOG).map((manifest) => ({
144
+ plugin_key: manifest.plugin_key,
145
+ display_name: manifest.display_name,
146
+ description: manifest.description,
147
+ installed: Boolean(state.plugins[manifest.plugin_key]),
148
+ tools: manifest.tools.map((tool) => tool.tool_key),
149
+ }));
150
+ if (opts.json) process.stdout.write(`${JSON.stringify(rows, null, 2)}\n`);
151
+ else for (const row of rows) console.log(` ${row.installed ? '✓' : '○'} @${row.plugin_key.padEnd(16)} ${row.description}`);
152
+ return rows;
153
+ }
154
+ const key = normalizePluginKey(opts.key || 'agentsam-mcp');
155
+ const manifest = CATALOG[key];
156
+ if (!manifest) throw new Error(`unknown_plugin:${key}`);
157
+ if (opts.action === 'connect') return connectPlugin(opts, key);
158
+ if (opts.action === 'status') return statusPlugin(opts, key);
159
+ if (opts.action !== 'install' && opts.action !== 'remove') throw new Error(`unknown plugins action:${opts.action}`);
160
+ const state = readState(opts.cwd);
161
+ let migration = null;
162
+ if (opts.action === 'install') {
163
+ state.plugins[key] = { plugin_key: key, installed_at: new Date().toISOString(), manifest };
164
+ migration = installMigration(opts.cwd);
165
+ } else {
166
+ delete state.plugins[key];
167
+ }
168
+ const filename = statePath(opts.cwd);
169
+ fs.mkdirSync(path.dirname(filename), { recursive: true, mode: 0o700 });
170
+ fs.writeFileSync(filename, `${JSON.stringify(state, null, 2)}\n`, { mode: 0o600 });
171
+ const result = { ok: true, action: opts.action, plugin_key: key, state_file: '.agentsam/plugins.json', migration };
172
+ if (opts.json) process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
173
+ else console.log(`\n${opts.action === 'install' ? 'Installed' : 'Removed'} @${key}\n state: ${result.state_file}${migration ? `\n migration: ${migration}` : ''}\n`);
174
+ return result;
175
+ }
@@ -3,7 +3,7 @@ import path from 'node:path';
3
3
  import { spawnSync } from 'node:child_process';
4
4
  import { cancel, confirm, intro, isCancel, outro, select, text } from '@clack/prompts';
5
5
  import { collectModelsStatus } from './models.js';
6
- import { getModelRecord } from '../models/index.js';
6
+ import { getModelRecord, mergeModelReference } from '../models/index.js';
7
7
  import { detectCliProject, readCliPreferences, writeCliPreferences } from '../lib/cli-preferences.js';
8
8
  import { readAccountSession } from '../lib/account-session.js';
9
9
 
@@ -42,6 +42,7 @@ export function availableShells(env = process.env) {
42
42
  export function modelOptions(status) {
43
43
  const options = [{ value: 'auto', label: 'Automatic', hint: 'runtime chooses from this credential\'s verified inventory', model: null }];
44
44
  for (const model of status.availableModels || []) {
45
+ if (model.provider === 'openai' && model.capabilities?.agent_runtime !== true) continue;
45
46
  const context = Number(model.context_window) > 0 ? ` · ctx ${Math.round(Number(model.context_window) / 1000)}k` : ' · ctx unknown';
46
47
  options.push({
47
48
  value: model.model_key,
@@ -62,22 +63,36 @@ export function modelOptions(status) {
62
63
  },
63
64
  });
64
65
  }
66
+ options.push({
67
+ value: '__configure_provider__',
68
+ label: '+ Configure an AI Provider',
69
+ hint: 'Add OpenAI, Anthropic, Gemini, Cursor, or Grok API key',
70
+ model: null,
71
+ });
65
72
  return options;
66
73
  }
67
74
 
68
75
  function resolvedModel(modelPreference, modelSnapshot) {
69
- if (modelSnapshot?.model_key === modelPreference) return modelSnapshot;
76
+ if (modelSnapshot?.model_key === modelPreference) return mergeModelReference(modelSnapshot);
70
77
  return getModelRecord(modelPreference);
71
78
  }
72
79
 
73
80
  function reasoningOptions(modelPreference, modelSnapshot) {
74
81
  const record = resolvedModel(modelPreference, modelSnapshot);
75
82
  if (!record) return [{ value: 'auto', label: 'Automatic', hint: 'runtime/provider default' }];
76
- return record.reasoning_efforts.map((value) => ({
77
- value,
78
- label: value === 'xhigh' ? 'Extra high' : value === 'max' ? 'Max' : value[0].toUpperCase() + value.slice(1),
79
- hint: value === 'low' ? 'lighter reasoning' : value === 'max' ? 'highest supported reasoning depth' : undefined,
80
- }));
83
+ const providerDefault = record.default_reasoning_effort || 'provider default';
84
+ return [
85
+ { value: 'auto', label: 'Automatic', hint: 'omit reasoning.effort · provider default ' + providerDefault },
86
+ ...record.reasoning_efforts.map((value) => ({
87
+ value,
88
+ label: value === 'xhigh' ? 'Extra high' : value === 'max' ? 'Max' : value[0].toUpperCase() + value.slice(1),
89
+ hint: value === record.default_reasoning_effort
90
+ ? 'provider default'
91
+ : value === 'low' ? 'lighter reasoning'
92
+ : value === 'max' ? 'highest supported reasoning depth'
93
+ : undefined,
94
+ })),
95
+ ];
81
96
  }
82
97
 
83
98
  function serviceTierOptions(modelPreference, modelSnapshot) {
@@ -96,8 +111,13 @@ async function promptModelPreferences(identity, existing, options = {}) {
96
111
  const models = modelOptions(status);
97
112
  const initialModel = models.some((row) => row.value === existing.modelPreference) ? existing.modelPreference : 'auto';
98
113
  const modelPreference = stopIfCancelled(await select({ message: 'Model', initialValue: initialModel, options: models.map(({ model, ...row }) => row) }));
114
+ if (modelPreference === '__configure_provider__') {
115
+ const { runProviders } = await import('./providers.js');
116
+ await runProviders([], { interactive: true, ...(options.modelStatusOptions || {}) });
117
+ return promptModelPreferences(identity, existing, options);
118
+ }
99
119
  const selected = models.find((row) => row.value === modelPreference)?.model || null;
100
- const modelSnapshot = selected || (existing.modelSnapshot?.model_key === modelPreference ? existing.modelSnapshot : null);
120
+ const modelSnapshot = selected || (existing.modelSnapshot?.model_key === modelPreference ? mergeModelReference(existing.modelSnapshot) : null);
101
121
 
102
122
  const reasoning = reasoningOptions(modelPreference, modelSnapshot);
103
123
  const initialReasoning = reasoning.some((row) => row.value === existing.reasoningEffort) ? existing.reasoningEffort : reasoning[0].value;
@@ -126,6 +126,18 @@ export async function runCapabilities(argv = []) {
126
126
 
127
127
  function featureStatePath(cwd) { return path.join(cwd, '.agentsam', 'features.json'); }
128
128
 
129
+ function parseAddArgs(argv = []) {
130
+ const opts = parseCommon(argv);
131
+ opts.provider = '';
132
+ opts.schemaProfile = '';
133
+ for (let i = 0; i < argv.length; i += 1) {
134
+ const arg = argv[i];
135
+ if (arg === '--provider') opts.provider = argv[++i] || '';
136
+ else if (arg === '--schema' || arg === '--schema-profile') opts.schemaProfile = argv[++i] || '';
137
+ }
138
+ return opts;
139
+ }
140
+
129
141
  export function applyPresetSelection(cwd, preset) {
130
142
  const filename = projectConfigPath(cwd);
131
143
  if (!fs.existsSync(filename)) throw new Error('not_agentsam_project');
@@ -136,31 +148,62 @@ export function applyPresetSelection(cwd, preset) {
136
148
  }
137
149
 
138
150
  export async function runAdd(argv = []) {
139
- const opts = parseCommon(argv);
151
+ const opts = parseAddArgs(argv);
140
152
  const id = opts.positionals[0];
141
153
  if (!id || id === '--help') {
142
154
  const rows = listAddons();
143
- console.log(`agentsam add <${rows.map(x => x.id).join('|')}> [--cwd PATH] [--json]`);
155
+ console.log(`agentsam add <${rows.map(x => x.id).join('|')}> [--cwd PATH] [--provider <id>] [--schema <profile>] [--json]`);
144
156
  return null;
145
157
  }
146
158
  const addon = getAddon(id);
147
159
  if (!addon) throw new Error(`unknown_addon:${id}`);
148
160
  const cwd = path.resolve(opts.cwd);
149
161
  if (!fs.existsSync(projectConfigPath(cwd))) throw new Error('not_agentsam_project');
150
- fs.mkdirSync(path.dirname(featureStatePath(cwd)), { recursive: true });
151
- let state = { schema_version: 1, features: {} };
152
- if (fs.existsSync(featureStatePath(cwd))) state = JSON.parse(fs.readFileSync(featureStatePath(cwd), 'utf8'));
153
- state.features ||= {};
154
- state.features[addon.id] = { selected: true, capabilities: addon.capabilities, selected_at: new Date().toISOString() };
155
- fs.writeFileSync(featureStatePath(cwd), `${JSON.stringify(state, null, 2)}\n`, 'utf8');
162
+
163
+ const { writeFeatureSelections } = await import('../features/resolve.js');
164
+ let state = { schema_version: 2, features: {} };
165
+ if (fs.existsSync(featureStatePath(cwd))) {
166
+ state = JSON.parse(fs.readFileSync(featureStatePath(cwd), 'utf8'));
167
+ state.schema_version = 2;
168
+ state.features ||= {};
169
+ }
170
+
171
+ /** @type {Record<string, unknown>} */
172
+ const entry = {
173
+ selected: true,
174
+ capabilities: addon.capabilities,
175
+ selected_at: new Date().toISOString(),
176
+ };
177
+ if (addon.id === 'auth') {
178
+ const { normalizeProviderTemplateId } = await import('../features/resolve.js');
179
+ entry.provider_template = normalizeProviderTemplateId(opts.provider) || 'inneranimalmedia';
180
+ if (opts.schemaProfile) entry.schema_profile = opts.schemaProfile;
181
+ }
182
+ state.features[addon.id] = entry;
183
+
184
+ const written = writeFeatureSelections(cwd, state);
156
185
  if (addon.id === 'deploy-cloudflare') {
157
186
  const config = readProjectConfig(cwd);
158
187
  setDeployTarget(config, 'cloudflare');
159
188
  writeProjectConfig(cwd, config);
160
189
  }
161
- const result = { ok: true, feature: addon.id, capabilities: addon.capabilities, description: addon.description, state_file: '.agentsam/features.json' };
190
+ const result = {
191
+ ok: true,
192
+ feature: addon.id,
193
+ capabilities: addon.capabilities,
194
+ description: addon.description,
195
+ state_file: '.agentsam/features.json',
196
+ resolved_file: 'generated/.agentsam/features-resolved.json',
197
+ provider_template: entry.provider_template || null,
198
+ schema_profile: entry.schema_profile || null,
199
+ resources: written.snapshot?.features?.[addon.id]?.resources || null,
200
+ };
162
201
  if (opts.json) process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
163
- else console.log(`\nAdded ${addon.id}\n ${addon.description}\n state: ${result.state_file}\n`);
202
+ else {
203
+ console.log(`\nAdded ${addon.id}\n ${addon.description}\n state: ${result.state_file}`);
204
+ if (entry.provider_template) console.log(` provider: ${entry.provider_template}`);
205
+ console.log(` resolved: ${result.resolved_file}\n`);
206
+ }
164
207
  return result;
165
208
  }
166
209