madarx 2.15.1 → 2.16.0

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 (377) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-build-manifest.json +322 -321
  3. package/.next/standalone/.next/app-path-routes-manifest.json +81 -81
  4. package/.next/standalone/.next/build-manifest.json +2 -2
  5. package/.next/standalone/.next/prerender-manifest.json +9 -9
  6. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  7. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  8. package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
  9. package/.next/standalone/.next/server/app/activity/page_client-reference-manifest.js +1 -1
  10. package/.next/standalone/.next/server/app/admin/page.js +2 -2
  11. package/.next/standalone/.next/server/app/admin/page_client-reference-manifest.js +1 -1
  12. package/.next/standalone/.next/server/app/agents/[id]/page.js +6 -6
  13. package/.next/standalone/.next/server/app/agents/[id]/page.js.nft.json +1 -1
  14. package/.next/standalone/.next/server/app/agents/[id]/page_client-reference-manifest.js +1 -1
  15. package/.next/standalone/.next/server/app/agents/page.js +1 -1
  16. package/.next/standalone/.next/server/app/agents/page.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/agents/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/api/activity/route_client-reference-manifest.js +1 -1
  19. package/.next/standalone/.next/server/app/api/admin/audit-export/route_client-reference-manifest.js +1 -1
  20. package/.next/standalone/.next/server/app/api/admin/share-links/route_client-reference-manifest.js +1 -1
  21. package/.next/standalone/.next/server/app/api/agent-memory/route_client-reference-manifest.js +1 -1
  22. package/.next/standalone/.next/server/app/api/agent-runs/[id]/cancel/route_client-reference-manifest.js +1 -1
  23. package/.next/standalone/.next/server/app/api/agent-runs/[id]/events/route_client-reference-manifest.js +1 -1
  24. package/.next/standalone/.next/server/app/api/agent-runs/[id]/log/route_client-reference-manifest.js +1 -1
  25. package/.next/standalone/.next/server/app/api/agent-runs/[id]/route_client-reference-manifest.js +1 -1
  26. package/.next/standalone/.next/server/app/api/agent-runs/route_client-reference-manifest.js +1 -1
  27. package/.next/standalone/.next/server/app/api/agents/[id]/chain/route_client-reference-manifest.js +1 -1
  28. package/.next/standalone/.next/server/app/api/agents/[id]/memory/route_client-reference-manifest.js +1 -1
  29. package/.next/standalone/.next/server/app/api/agents/[id]/reports/route_client-reference-manifest.js +1 -1
  30. package/.next/standalone/.next/server/app/api/agents/[id]/run/route_client-reference-manifest.js +1 -1
  31. package/.next/standalone/.next/server/app/api/agents/[id]/skills/route_client-reference-manifest.js +1 -1
  32. package/.next/standalone/.next/server/app/api/agents/create/route_client-reference-manifest.js +1 -1
  33. package/.next/standalone/.next/server/app/api/agents/ops/route_client-reference-manifest.js +1 -1
  34. package/.next/standalone/.next/server/app/api/approvals/[id]/route_client-reference-manifest.js +1 -1
  35. package/.next/standalone/.next/server/app/api/approvals/route_client-reference-manifest.js +1 -1
  36. package/.next/standalone/.next/server/app/api/artifacts/[id]/acl/route_client-reference-manifest.js +1 -1
  37. package/.next/standalone/.next/server/app/api/artifacts/[id]/protect/route_client-reference-manifest.js +1 -1
  38. package/.next/standalone/.next/server/app/api/artifacts/[id]/raw/route_client-reference-manifest.js +1 -1
  39. package/.next/standalone/.next/server/app/api/artifacts/[id]/route_client-reference-manifest.js +1 -1
  40. package/.next/standalone/.next/server/app/api/artifacts/[id]/share-link/[linkId]/route_client-reference-manifest.js +1 -1
  41. package/.next/standalone/.next/server/app/api/artifacts/[id]/share-link/route_client-reference-manifest.js +1 -1
  42. package/.next/standalone/.next/server/app/api/artifacts/upload/route_client-reference-manifest.js +1 -1
  43. package/.next/standalone/.next/server/app/api/audit/list/route_client-reference-manifest.js +1 -1
  44. package/.next/standalone/.next/server/app/api/audit/search/route_client-reference-manifest.js +1 -1
  45. package/.next/standalone/.next/server/app/api/auth/callback/route_client-reference-manifest.js +1 -1
  46. package/.next/standalone/.next/server/app/api/auth/config/route_client-reference-manifest.js +1 -1
  47. package/.next/standalone/.next/server/app/api/auth/join-bootstrap/route_client-reference-manifest.js +1 -1
  48. package/.next/standalone/.next/server/app/api/auth/session/route_client-reference-manifest.js +1 -1
  49. package/.next/standalone/.next/server/app/api/brand/route_client-reference-manifest.js +1 -1
  50. package/.next/standalone/.next/server/app/api/chat/sessions/[id]/route_client-reference-manifest.js +1 -1
  51. package/.next/standalone/.next/server/app/api/chat/sessions/route_client-reference-manifest.js +1 -1
  52. package/.next/standalone/.next/server/app/api/config/env/route_client-reference-manifest.js +1 -1
  53. package/.next/standalone/.next/server/app/api/config/route_client-reference-manifest.js +1 -1
  54. package/.next/standalone/.next/server/app/api/connections/[service]/route_client-reference-manifest.js +1 -1
  55. package/.next/standalone/.next/server/app/api/connections/[service]/verify/route.js +2 -2
  56. package/.next/standalone/.next/server/app/api/connections/[service]/verify/route_client-reference-manifest.js +1 -1
  57. package/.next/standalone/.next/server/app/api/connections/route_client-reference-manifest.js +1 -1
  58. package/.next/standalone/.next/server/app/api/cron/tick/route_client-reference-manifest.js +1 -1
  59. package/.next/standalone/.next/server/app/api/dashboard/spaces/[id]/move/route_client-reference-manifest.js +1 -1
  60. package/.next/standalone/.next/server/app/api/dashboard/spaces/[id]/route_client-reference-manifest.js +1 -1
  61. package/.next/standalone/.next/server/app/api/dashboard/spaces/[id]/share-link/[linkId]/route_client-reference-manifest.js +1 -1
  62. package/.next/standalone/.next/server/app/api/dashboard/spaces/[id]/share-link/route_client-reference-manifest.js +1 -1
  63. package/.next/standalone/.next/server/app/api/dashboard/spaces/import/route_client-reference-manifest.js +1 -1
  64. package/.next/standalone/.next/server/app/api/dashboard/spaces/route_client-reference-manifest.js +1 -1
  65. package/.next/standalone/.next/server/app/api/disk/files/[id]/blob/route_client-reference-manifest.js +1 -1
  66. package/.next/standalone/.next/server/app/api/disk/files/[id]/route_client-reference-manifest.js +1 -1
  67. package/.next/standalone/.next/server/app/api/disk/files/[id]/transcribe/route_client-reference-manifest.js +1 -1
  68. package/.next/standalone/.next/server/app/api/disk/files/route_client-reference-manifest.js +1 -1
  69. package/.next/standalone/.next/server/app/api/disk/folders/route_client-reference-manifest.js +1 -1
  70. package/.next/standalone/.next/server/app/api/events/since/[cursor]/route_client-reference-manifest.js +1 -1
  71. package/.next/standalone/.next/server/app/api/events/stream/route_client-reference-manifest.js +1 -1
  72. package/.next/standalone/.next/server/app/api/fs/create-folder/route_client-reference-manifest.js +1 -1
  73. package/.next/standalone/.next/server/app/api/fs/pick-folder/route_client-reference-manifest.js +1 -1
  74. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/blueprint/route_client-reference-manifest.js +1 -1
  75. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/diagnostic/route_client-reference-manifest.js +1 -1
  76. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/governance/route_client-reference-manifest.js +1 -1
  77. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/interview/route_client-reference-manifest.js +1 -1
  78. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/pilot/route_client-reference-manifest.js +1 -1
  79. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/quarterly/route_client-reference-manifest.js +1 -1
  80. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/route_client-reference-manifest.js +1 -1
  81. package/.next/standalone/.next/server/app/api/hail/engagements/[id]/setup-package/route_client-reference-manifest.js +1 -1
  82. package/.next/standalone/.next/server/app/api/hail/engagements/route_client-reference-manifest.js +1 -1
  83. package/.next/standalone/.next/server/app/api/hail/interviews/[id]/responses/route_client-reference-manifest.js +1 -1
  84. package/.next/standalone/.next/server/app/api/hail/interviews/[id]/route_client-reference-manifest.js +1 -1
  85. package/.next/standalone/.next/server/app/api/hail/setup-packages/[id]/apply/route_client-reference-manifest.js +1 -1
  86. package/.next/standalone/.next/server/app/api/hail/setup-packages/validate/route_client-reference-manifest.js +1 -1
  87. package/.next/standalone/.next/server/app/api/heartbeat/tick/route_client-reference-manifest.js +1 -1
  88. package/.next/standalone/.next/server/app/api/heartbeat/worker/route_client-reference-manifest.js +1 -1
  89. package/.next/standalone/.next/server/app/api/help/route_client-reference-manifest.js +1 -1
  90. package/.next/standalone/.next/server/app/api/hermes/jobs/[id]/events/route_client-reference-manifest.js +1 -1
  91. package/.next/standalone/.next/server/app/api/hermes/jobs/[id]/route_client-reference-manifest.js +1 -1
  92. package/.next/standalone/.next/server/app/api/hermes/jobs/route_client-reference-manifest.js +1 -1
  93. package/.next/standalone/.next/server/app/api/integrations/google/callback/route_client-reference-manifest.js +1 -1
  94. package/.next/standalone/.next/server/app/api/integrations/google/oauth/route_client-reference-manifest.js +1 -1
  95. package/.next/standalone/.next/server/app/api/marketplace/[id]/route_client-reference-manifest.js +1 -1
  96. package/.next/standalone/.next/server/app/api/marketplace/open-design/route_client-reference-manifest.js +1 -1
  97. package/.next/standalone/.next/server/app/api/marketplace/route_client-reference-manifest.js +1 -1
  98. package/.next/standalone/.next/server/app/api/mines/import-roots/route_client-reference-manifest.js +1 -1
  99. package/.next/standalone/.next/server/app/api/mines/portfolio/route_client-reference-manifest.js +1 -1
  100. package/.next/standalone/.next/server/app/api/mines/projects/[id]/chunks/route_client-reference-manifest.js +1 -1
  101. package/.next/standalone/.next/server/app/api/mines/projects/[id]/diligence/route_client-reference-manifest.js +1 -1
  102. package/.next/standalone/.next/server/app/api/mines/projects/[id]/import/route_client-reference-manifest.js +1 -1
  103. package/.next/standalone/.next/server/app/api/mines/projects/[id]/publish/route_client-reference-manifest.js +1 -1
  104. package/.next/standalone/.next/server/app/api/mines/projects/route_client-reference-manifest.js +1 -1
  105. package/.next/standalone/.next/server/app/api/missions/route_client-reference-manifest.js +1 -1
  106. package/.next/standalone/.next/server/app/api/models/route_client-reference-manifest.js +1 -1
  107. package/.next/standalone/.next/server/app/api/onboarding/blueprint/route_client-reference-manifest.js +1 -1
  108. package/.next/standalone/.next/server/app/api/onboarding/launch/route_client-reference-manifest.js +1 -1
  109. package/.next/standalone/.next/server/app/api/orchestrator/command/route_client-reference-manifest.js +1 -1
  110. package/.next/standalone/.next/server/app/api/orchestrator/stream/route_client-reference-manifest.js +1 -1
  111. package/.next/standalone/.next/server/app/api/orchestrator/upload/route_client-reference-manifest.js +1 -1
  112. package/.next/standalone/.next/server/app/api/org/route_client-reference-manifest.js +1 -1
  113. package/.next/standalone/.next/server/app/api/orgs/[id]/invites/[inviteId]/route_client-reference-manifest.js +1 -1
  114. package/.next/standalone/.next/server/app/api/orgs/[id]/invites/route_client-reference-manifest.js +1 -1
  115. package/.next/standalone/.next/server/app/api/orgs/[id]/members/[userId]/role/route_client-reference-manifest.js +1 -1
  116. package/.next/standalone/.next/server/app/api/orgs/[id]/members/[userId]/route_client-reference-manifest.js +1 -1
  117. package/.next/standalone/.next/server/app/api/orgs/[id]/members/route_client-reference-manifest.js +1 -1
  118. package/.next/standalone/.next/server/app/api/orgs/[id]/route_client-reference-manifest.js +1 -1
  119. package/.next/standalone/.next/server/app/api/orgs/invites/pending/route_client-reference-manifest.js +1 -1
  120. package/.next/standalone/.next/server/app/api/orgs/join/route_client-reference-manifest.js +1 -1
  121. package/.next/standalone/.next/server/app/api/orgs/join-complete/route_client-reference-manifest.js +1 -1
  122. package/.next/standalone/.next/server/app/api/orgs/route_client-reference-manifest.js +1 -1
  123. package/.next/standalone/.next/server/app/api/printing-press/clis/route_client-reference-manifest.js +1 -1
  124. package/.next/standalone/.next/server/app/api/printing-press/install/route_client-reference-manifest.js +1 -1
  125. package/.next/standalone/.next/server/app/api/printing-press/security-mode/route_client-reference-manifest.js +1 -1
  126. package/.next/standalone/.next/server/app/api/privacy/config/route_client-reference-manifest.js +1 -1
  127. package/.next/standalone/.next/server/app/api/privacy/verify/route_client-reference-manifest.js +1 -1
  128. package/.next/standalone/.next/server/app/api/processes/[id]/route_client-reference-manifest.js +1 -1
  129. package/.next/standalone/.next/server/app/api/processes/[id]/share-link/route_client-reference-manifest.js +1 -1
  130. package/.next/standalone/.next/server/app/api/processes/[id]/stages/[stageId]/override/route_client-reference-manifest.js +1 -1
  131. package/.next/standalone/.next/server/app/api/processes/[id]/stages/[stageId]/retry/route_client-reference-manifest.js +1 -1
  132. package/.next/standalone/.next/server/app/api/processes/[id]/stages/[stageId]/submit/route_client-reference-manifest.js +1 -1
  133. package/.next/standalone/.next/server/app/api/processes/definitions/[slug]/route_client-reference-manifest.js +1 -1
  134. package/.next/standalone/.next/server/app/api/processes/definitions/[slug]/settings/route_client-reference-manifest.js +1 -1
  135. package/.next/standalone/.next/server/app/api/processes/definitions/route_client-reference-manifest.js +1 -1
  136. package/.next/standalone/.next/server/app/api/processes/definitions/validate/route_client-reference-manifest.js +1 -1
  137. package/.next/standalone/.next/server/app/api/processes/route_client-reference-manifest.js +1 -1
  138. package/.next/standalone/.next/server/app/api/processes/start-and-route/route_client-reference-manifest.js +1 -1
  139. package/.next/standalone/.next/server/app/api/projects/[slug]/library/route_client-reference-manifest.js +1 -1
  140. package/.next/standalone/.next/server/app/api/projects/[slug]/route_client-reference-manifest.js +1 -1
  141. package/.next/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  142. package/.next/standalone/.next/server/app/api/runs/approve-claude-run/route_client-reference-manifest.js +1 -1
  143. package/.next/standalone/.next/server/app/api/runs/claude-code-dry-run/route_client-reference-manifest.js +1 -1
  144. package/.next/standalone/.next/server/app/api/runs/competitor-report/route_client-reference-manifest.js +1 -1
  145. package/.next/standalone/.next/server/app/api/runs/engine-ping/route_client-reference-manifest.js +1 -1
  146. package/.next/standalone/.next/server/app/api/runs/marketing-plan/route_client-reference-manifest.js +1 -1
  147. package/.next/standalone/.next/server/app/api/schedules/upsert/route_client-reference-manifest.js +1 -1
  148. package/.next/standalone/.next/server/app/api/secrets/[name]/route_client-reference-manifest.js +1 -1
  149. package/.next/standalone/.next/server/app/api/secrets/route_client-reference-manifest.js +1 -1
  150. package/.next/standalone/.next/server/app/api/settings/trust-mode/route_client-reference-manifest.js +1 -1
  151. package/.next/standalone/.next/server/app/api/share/[token]/otp/route_client-reference-manifest.js +1 -1
  152. package/.next/standalone/.next/server/app/api/share/[token]/route_client-reference-manifest.js +1 -1
  153. package/.next/standalone/.next/server/app/api/share/[token]/verify/route_client-reference-manifest.js +1 -1
  154. package/.next/standalone/.next/server/app/api/share/space/[token]/otp/route_client-reference-manifest.js +1 -1
  155. package/.next/standalone/.next/server/app/api/share/space/[token]/route_client-reference-manifest.js +1 -1
  156. package/.next/standalone/.next/server/app/api/share/space/[token]/verify/route_client-reference-manifest.js +1 -1
  157. package/.next/standalone/.next/server/app/api/shared/spaces/[id]/acl/route_client-reference-manifest.js +1 -1
  158. package/.next/standalone/.next/server/app/api/shared/spaces/publish/route_client-reference-manifest.js +1 -1
  159. package/.next/standalone/.next/server/app/api/shared/spaces/route_client-reference-manifest.js +1 -1
  160. package/.next/standalone/.next/server/app/api/shared/spaces/status/route_client-reference-manifest.js +1 -1
  161. package/.next/standalone/.next/server/app/api/shared/spaces/unpublish/route_client-reference-manifest.js +1 -1
  162. package/.next/standalone/.next/server/app/api/state/route_client-reference-manifest.js +1 -1
  163. package/.next/standalone/.next/server/app/api/system/update/route_client-reference-manifest.js +1 -1
  164. package/.next/standalone/.next/server/app/api/tasks/[id]/active-run/route_client-reference-manifest.js +1 -1
  165. package/.next/standalone/.next/server/app/api/tasks/[id]/attachments/route_client-reference-manifest.js +1 -1
  166. package/.next/standalone/.next/server/app/api/tasks/[id]/checklist/[itemId]/route_client-reference-manifest.js +1 -1
  167. package/.next/standalone/.next/server/app/api/tasks/[id]/checklist/route_client-reference-manifest.js +1 -1
  168. package/.next/standalone/.next/server/app/api/tasks/[id]/checkout/route_client-reference-manifest.js +1 -1
  169. package/.next/standalone/.next/server/app/api/tasks/[id]/children/route_client-reference-manifest.js +1 -1
  170. package/.next/standalone/.next/server/app/api/tasks/[id]/comments/route_client-reference-manifest.js +1 -1
  171. package/.next/standalone/.next/server/app/api/tasks/[id]/events/route_client-reference-manifest.js +1 -1
  172. package/.next/standalone/.next/server/app/api/tasks/[id]/live-runs/route_client-reference-manifest.js +1 -1
  173. package/.next/standalone/.next/server/app/api/tasks/[id]/release/route_client-reference-manifest.js +1 -1
  174. package/.next/standalone/.next/server/app/api/tasks/[id]/route_client-reference-manifest.js +1 -1
  175. package/.next/standalone/.next/server/app/api/tasks/route_client-reference-manifest.js +1 -1
  176. package/.next/standalone/.next/server/app/api/tool-allowlists/[id]/route_client-reference-manifest.js +1 -1
  177. package/.next/standalone/.next/server/app/api/tool-allowlists/route_client-reference-manifest.js +1 -1
  178. package/.next/standalone/.next/server/app/api/tool-egress/route_client-reference-manifest.js +1 -1
  179. package/.next/standalone/.next/server/app/api/tools/[name]/approve/route_client-reference-manifest.js +1 -1
  180. package/.next/standalone/.next/server/app/api/tools/[name]/route_client-reference-manifest.js +1 -1
  181. package/.next/standalone/.next/server/app/api/tools/route_client-reference-manifest.js +1 -1
  182. package/.next/standalone/.next/server/app/api/transcripts/route_client-reference-manifest.js +1 -1
  183. package/.next/standalone/.next/server/app/api/voice/providers/route_client-reference-manifest.js +1 -1
  184. package/.next/standalone/.next/server/app/api/voice/realtime/context/route_client-reference-manifest.js +1 -1
  185. package/.next/standalone/.next/server/app/api/voice/realtime/session/route_client-reference-manifest.js +1 -1
  186. package/.next/standalone/.next/server/app/api/voice/realtime/tool-result/route_client-reference-manifest.js +1 -1
  187. package/.next/standalone/.next/server/app/api/voice/realtime/tools/route_client-reference-manifest.js +1 -1
  188. package/.next/standalone/.next/server/app/api/voice/tts/route_client-reference-manifest.js +1 -1
  189. package/.next/standalone/.next/server/app/api/whatsapp/allowlist/route_client-reference-manifest.js +1 -1
  190. package/.next/standalone/.next/server/app/api/whatsapp/disconnect/route_client-reference-manifest.js +1 -1
  191. package/.next/standalone/.next/server/app/api/whatsapp/messages/route_client-reference-manifest.js +1 -1
  192. package/.next/standalone/.next/server/app/api/whatsapp/qr/route_client-reference-manifest.js +1 -1
  193. package/.next/standalone/.next/server/app/api/whatsapp/send/route_client-reference-manifest.js +1 -1
  194. package/.next/standalone/.next/server/app/api/whatsapp/status/route_client-reference-manifest.js +1 -1
  195. package/.next/standalone/.next/server/app/approvals/page.js +1 -1
  196. package/.next/standalone/.next/server/app/approvals/page_client-reference-manifest.js +1 -1
  197. package/.next/standalone/.next/server/app/architecture/page_client-reference-manifest.js +1 -1
  198. package/.next/standalone/.next/server/app/architecture.html +2 -2
  199. package/.next/standalone/.next/server/app/architecture.rsc +2 -2
  200. package/.next/standalone/.next/server/app/audit/live/page_client-reference-manifest.js +1 -1
  201. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  202. package/.next/standalone/.next/server/app/brand/page_client-reference-manifest.js +1 -1
  203. package/.next/standalone/.next/server/app/brand.html +1 -1
  204. package/.next/standalone/.next/server/app/brand.rsc +2 -2
  205. package/.next/standalone/.next/server/app/disk/page_client-reference-manifest.js +1 -1
  206. package/.next/standalone/.next/server/app/federated-ai/page_client-reference-manifest.js +1 -1
  207. package/.next/standalone/.next/server/app/federated-ai.html +2 -2
  208. package/.next/standalone/.next/server/app/federated-ai.rsc +2 -2
  209. package/.next/standalone/.next/server/app/hail/[id]/governance/page_client-reference-manifest.js +1 -1
  210. package/.next/standalone/.next/server/app/hail/[id]/interview/page.js +1 -1
  211. package/.next/standalone/.next/server/app/hail/[id]/interview/page_client-reference-manifest.js +1 -1
  212. package/.next/standalone/.next/server/app/hail/[id]/page.js +1 -1
  213. package/.next/standalone/.next/server/app/hail/[id]/page_client-reference-manifest.js +1 -1
  214. package/.next/standalone/.next/server/app/hail/[id]/setup/page.js +2 -2
  215. package/.next/standalone/.next/server/app/hail/[id]/setup/page_client-reference-manifest.js +1 -1
  216. package/.next/standalone/.next/server/app/hail/page.js +1 -1
  217. package/.next/standalone/.next/server/app/hail/page_client-reference-manifest.js +1 -1
  218. package/.next/standalone/.next/server/app/help/[slug]/page_client-reference-manifest.js +1 -1
  219. package/.next/standalone/.next/server/app/help/page_client-reference-manifest.js +1 -1
  220. package/.next/standalone/.next/server/app/index.html +2 -2
  221. package/.next/standalone/.next/server/app/index.rsc +2 -2
  222. package/.next/standalone/.next/server/app/join/page_client-reference-manifest.js +1 -1
  223. package/.next/standalone/.next/server/app/join.html +1 -1
  224. package/.next/standalone/.next/server/app/join.rsc +2 -2
  225. package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  226. package/.next/standalone/.next/server/app/marketplace/page.js +4 -3
  227. package/.next/standalone/.next/server/app/marketplace/page.js.nft.json +1 -1
  228. package/.next/standalone/.next/server/app/marketplace/page_client-reference-manifest.js +1 -1
  229. package/.next/standalone/.next/server/app/mines/[projectId]/page_client-reference-manifest.js +1 -1
  230. package/.next/standalone/.next/server/app/mines/[projectId]/results/page_client-reference-manifest.js +1 -1
  231. package/.next/standalone/.next/server/app/mines/page_client-reference-manifest.js +1 -1
  232. package/.next/standalone/.next/server/app/missions/page.js +2 -2
  233. package/.next/standalone/.next/server/app/missions/page_client-reference-manifest.js +1 -1
  234. package/.next/standalone/.next/server/app/onboarding/org/page_client-reference-manifest.js +1 -1
  235. package/.next/standalone/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
  236. package/.next/standalone/.next/server/app/onboarding.html +2 -2
  237. package/.next/standalone/.next/server/app/onboarding.rsc +2 -2
  238. package/.next/standalone/.next/server/app/org/page.js +1 -1
  239. package/.next/standalone/.next/server/app/org/page.js.nft.json +1 -1
  240. package/.next/standalone/.next/server/app/org/page_client-reference-manifest.js +1 -1
  241. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  242. package/.next/standalone/.next/server/app/projects/[slug]/log/page_client-reference-manifest.js +1 -1
  243. package/.next/standalone/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
  244. package/.next/standalone/.next/server/app/projects/new/page.js +3 -2
  245. package/.next/standalone/.next/server/app/projects/new/page.js.nft.json +1 -1
  246. package/.next/standalone/.next/server/app/projects/new/page_client-reference-manifest.js +1 -1
  247. package/.next/standalone/.next/server/app/projects/new.html +1 -1
  248. package/.next/standalone/.next/server/app/projects/new.rsc +3 -3
  249. package/.next/standalone/.next/server/app/projects/page.js +32 -15
  250. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  251. package/.next/standalone/.next/server/app/reports/[file]/route_client-reference-manifest.js +1 -1
  252. package/.next/standalone/.next/server/app/reports/page_client-reference-manifest.js +1 -1
  253. package/.next/standalone/.next/server/app/runtime/page_client-reference-manifest.js +1 -1
  254. package/.next/standalone/.next/server/app/schedules/page.js +2 -2
  255. package/.next/standalone/.next/server/app/schedules/page_client-reference-manifest.js +1 -1
  256. package/.next/standalone/.next/server/app/settings/account/page_client-reference-manifest.js +1 -1
  257. package/.next/standalone/.next/server/app/settings/advanced/page_client-reference-manifest.js +1 -1
  258. package/.next/standalone/.next/server/app/settings/appearance/page.js +1 -1
  259. package/.next/standalone/.next/server/app/settings/appearance/page_client-reference-manifest.js +1 -1
  260. package/.next/standalone/.next/server/app/settings/brand/page.js +1 -1
  261. package/.next/standalone/.next/server/app/settings/brand/page_client-reference-manifest.js +1 -1
  262. package/.next/standalone/.next/server/app/settings/brand.html +2 -2
  263. package/.next/standalone/.next/server/app/settings/brand.rsc +3 -3
  264. package/.next/standalone/.next/server/app/settings/connectors/page_client-reference-manifest.js +1 -1
  265. package/.next/standalone/.next/server/app/settings/engines/page_client-reference-manifest.js +1 -1
  266. package/.next/standalone/.next/server/app/settings/onboarding/page.js +1 -1
  267. package/.next/standalone/.next/server/app/settings/onboarding/page_client-reference-manifest.js +1 -1
  268. package/.next/standalone/.next/server/app/settings/onboarding.html +2 -2
  269. package/.next/standalone/.next/server/app/settings/onboarding.rsc +3 -3
  270. package/.next/standalone/.next/server/app/settings/organization/page.js +2 -2
  271. package/.next/standalone/.next/server/app/settings/organization/page.js.nft.json +1 -1
  272. package/.next/standalone/.next/server/app/settings/organization/page_client-reference-manifest.js +1 -1
  273. package/.next/standalone/.next/server/app/settings/page.js +1 -1
  274. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  275. package/.next/standalone/.next/server/app/settings/runtime/page.js +1 -1
  276. package/.next/standalone/.next/server/app/settings/runtime/page_client-reference-manifest.js +1 -1
  277. package/.next/standalone/.next/server/app/settings/team/page.js +1 -1
  278. package/.next/standalone/.next/server/app/settings/team/page_client-reference-manifest.js +1 -1
  279. package/.next/standalone/.next/server/app/settings/tools/page_client-reference-manifest.js +1 -1
  280. package/.next/standalone/.next/server/app/settings.html +2 -2
  281. package/.next/standalone/.next/server/app/settings.rsc +3 -3
  282. package/.next/standalone/.next/server/app/share/[token]/page_client-reference-manifest.js +1 -1
  283. package/.next/standalone/.next/server/app/share/space/[token]/page_client-reference-manifest.js +1 -1
  284. package/.next/standalone/.next/server/app/tasks/[id]/page.js +2 -2
  285. package/.next/standalone/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
  286. package/.next/standalone/.next/server/app/tasks/page.js +2 -2
  287. package/.next/standalone/.next/server/app/tasks/page_client-reference-manifest.js +1 -1
  288. package/.next/standalone/.next/server/app/team/[agentId]/page_client-reference-manifest.js +1 -1
  289. package/.next/standalone/.next/server/app/team/page_client-reference-manifest.js +1 -1
  290. package/.next/standalone/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  291. package/.next/standalone/.next/server/app/whatsapp/page_client-reference-manifest.js +1 -1
  292. package/.next/standalone/.next/server/app/whatsapp.html +1 -1
  293. package/.next/standalone/.next/server/app/whatsapp.rsc +2 -2
  294. package/.next/standalone/.next/server/app/workflows/[caseId]/page_client-reference-manifest.js +1 -1
  295. package/.next/standalone/.next/server/app/workflows/new/[caseId]/page_client-reference-manifest.js +1 -1
  296. package/.next/standalone/.next/server/app/workflows/new/definition/page_client-reference-manifest.js +1 -1
  297. package/.next/standalone/.next/server/app/workflows/page_client-reference-manifest.js +1 -1
  298. package/.next/standalone/.next/server/app/workflows/share/[caseId]/page_client-reference-manifest.js +1 -1
  299. package/.next/standalone/.next/server/app-paths-manifest.json +81 -81
  300. package/.next/standalone/.next/server/chunks/1648.js +1 -1
  301. package/.next/standalone/.next/server/chunks/1699.js +39 -22
  302. package/.next/standalone/.next/server/chunks/3230.js +2 -2
  303. package/.next/standalone/.next/server/chunks/5093.js +1 -0
  304. package/.next/standalone/.next/server/chunks/5864.js +1 -0
  305. package/.next/standalone/.next/server/chunks/{9801.js → 7500.js} +1 -1
  306. package/.next/standalone/.next/server/functions-config-manifest.json +42 -42
  307. package/.next/standalone/.next/server/middleware-manifest.json +5 -5
  308. package/.next/standalone/.next/server/pages/404.html +1 -1
  309. package/.next/standalone/.next/server/pages/500.html +1 -1
  310. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  311. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  312. package/.next/standalone/.next/static/chunks/7695-04c7f1a5233de027.js +1 -0
  313. package/.next/standalone/.next/static/chunks/app/agents/[id]/page-474f640e84f7b4b5.js +1 -0
  314. package/.next/standalone/.next/static/chunks/app/agents/page-b79b611acd56712b.js +1 -0
  315. package/.next/standalone/.next/static/chunks/app/marketplace/page-0b7d3a6309302de3.js +1 -0
  316. package/.next/standalone/.next/static/chunks/app/projects/page-e1cfb0b17418e719.js +1 -0
  317. package/.next/standalone/.next/static/chunks/app/settings/layout-08f6b30132b26dd1.js +1 -0
  318. package/.next/standalone/.next/static/chunks/app/settings/team/page-9a2e675124de6aac.js +1 -0
  319. package/.next/standalone/.next/static/css/{65c472079b6fd086.css → 9fbf057b7ce95c36.css} +1 -1
  320. package/.next/standalone/CHANGELOG.md +14 -0
  321. package/.next/standalone/data/.artifacts-migrated-v1 +1 -1
  322. package/.next/standalone/data/.default-project-seeded +1 -1
  323. package/.next/standalone/data/madarx.sqlite +0 -0
  324. package/.next/standalone/data/madarx.sqlite-shm +0 -0
  325. package/.next/standalone/data/madarx.sqlite-wal +0 -0
  326. package/.next/standalone/package.json +1 -1
  327. package/.next/static/chunks/7695-04c7f1a5233de027.js +1 -0
  328. package/.next/static/chunks/app/agents/[id]/page-474f640e84f7b4b5.js +1 -0
  329. package/.next/static/chunks/app/agents/page-b79b611acd56712b.js +1 -0
  330. package/.next/static/chunks/app/marketplace/page-0b7d3a6309302de3.js +1 -0
  331. package/.next/static/chunks/app/projects/page-e1cfb0b17418e719.js +1 -0
  332. package/.next/static/chunks/app/settings/layout-08f6b30132b26dd1.js +1 -0
  333. package/.next/static/chunks/app/settings/team/page-9a2e675124de6aac.js +1 -0
  334. package/.next/static/css/{65c472079b6fd086.css → 9fbf057b7ce95c36.css} +1 -1
  335. package/CHANGELOG.md +14 -0
  336. package/app/agents/[id]/agent-activity-feed.tsx +96 -0
  337. package/app/agents/[id]/agent-detail-simple.tsx +71 -83
  338. package/app/agents/[id]/agent-quick-controls.tsx +497 -0
  339. package/app/agents/[id]/page.js +90 -2
  340. package/app/api/connections/[service]/verify/route.js +17 -2
  341. package/app/globals.css +347 -32
  342. package/lib/agent-templates.js +12 -0
  343. package/lib/connection-grant.js +106 -0
  344. package/lib/connection-seeds.js +126 -0
  345. package/lib/connections/health-check-verify.js +114 -0
  346. package/lib/connections/manifest-validator.js +161 -0
  347. package/lib/marketplace-modules.js +45 -0
  348. package/lib/marketplace-seeds.js +105 -0
  349. package/lib/marketplace.js +1 -0
  350. package/lib/oauth/flow.js +204 -0
  351. package/lib/oauth/provider-registry.js +102 -0
  352. package/lib/runtime.js +74 -1
  353. package/lib/schema.js +17 -0
  354. package/lib/tools/adapters/http-api-call.js +92 -28
  355. package/lib/tools/connectors/connector-validator.js +27 -1
  356. package/package.json +1 -1
  357. package/.next/standalone/.next/server/chunks/1887.js +0 -2
  358. package/.next/standalone/.next/server/chunks/3711.js +0 -1
  359. package/.next/standalone/.next/server/chunks/6098.js +0 -1
  360. package/.next/standalone/.next/static/chunks/9077-f54ea987eb597e43.js +0 -1
  361. package/.next/standalone/.next/static/chunks/app/agents/[id]/page-66477263de089865.js +0 -1
  362. package/.next/standalone/.next/static/chunks/app/agents/page-64d6bdc6ba3ad4d7.js +0 -1
  363. package/.next/standalone/.next/static/chunks/app/marketplace/page-45c6d49f8eddad67.js +0 -1
  364. package/.next/standalone/.next/static/chunks/app/projects/page-15a7a85fa216b575.js +0 -1
  365. package/.next/standalone/.next/static/chunks/app/settings/layout-2c1e6807acb6fdad.js +0 -1
  366. package/.next/standalone/.next/static/chunks/app/settings/team/page-0aee40dfa9e7a430.js +0 -1
  367. package/.next/static/chunks/9077-f54ea987eb597e43.js +0 -1
  368. package/.next/static/chunks/app/agents/[id]/page-66477263de089865.js +0 -1
  369. package/.next/static/chunks/app/agents/page-64d6bdc6ba3ad4d7.js +0 -1
  370. package/.next/static/chunks/app/marketplace/page-45c6d49f8eddad67.js +0 -1
  371. package/.next/static/chunks/app/projects/page-15a7a85fa216b575.js +0 -1
  372. package/.next/static/chunks/app/settings/layout-2c1e6807acb6fdad.js +0 -1
  373. package/.next/static/chunks/app/settings/team/page-0aee40dfa9e7a430.js +0 -1
  374. /package/.next/standalone/.next/static/{JcJc6PlL89SQvtZvP-LnU → JGJBLnQfb05RAKCcECbJt}/_buildManifest.js +0 -0
  375. /package/.next/standalone/.next/static/{JcJc6PlL89SQvtZvP-LnU → JGJBLnQfb05RAKCcECbJt}/_ssgManifest.js +0 -0
  376. /package/.next/static/{JcJc6PlL89SQvtZvP-LnU → JGJBLnQfb05RAKCcECbJt}/_buildManifest.js +0 -0
  377. /package/.next/static/{JcJc6PlL89SQvtZvP-LnU → JGJBLnQfb05RAKCcECbJt}/_ssgManifest.js +0 -0
@@ -0,0 +1,204 @@
1
+ // lib/oauth/flow.js — OAuth2 authorization-code flow primitives.
2
+ //
3
+ // Local-first and provider-agnostic. Three responsibilities:
4
+ // 1. CSRF state — a single-use, server-stored random state value (oauth_states
5
+ // table). createAuthState() issues one; consumeAuthState() validates +
6
+ // burns it exactly once. Replay or expiry is rejected.
7
+ // 2. PKCE — S256 code_verifier/code_challenge generation (RFC 7636).
8
+ // 3. Token I/O — exchangeCodeForTokens() and refreshAccessToken(), both taking
9
+ // an injectable fetchFn so tests use a mock and never hit a live provider.
10
+ //
11
+ // SECURITY: this module never persists access/refresh tokens — that is the
12
+ // caller's job (the vault, via setSecret). The state ledger stores only the PKCE
13
+ // verifier and non-secret scope metadata. Tokens never appear in audit/log here.
14
+
15
+ import { createHash, randomBytes } from 'node:crypto';
16
+ import { getDb, nowIso } from '../db.js';
17
+
18
+ const DEFAULT_TTL_MS = 10 * 60 * 1000; // 10 minutes
19
+
20
+ function base64url(buf) {
21
+ return Buffer.from(buf).toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
22
+ }
23
+
24
+ /** Generate a PKCE verifier + S256 challenge pair. */
25
+ export function generatePkce() {
26
+ const verifier = base64url(randomBytes(32));
27
+ const challenge = base64url(createHash('sha256').update(verifier).digest());
28
+ return { code_verifier: verifier, code_challenge: challenge, code_challenge_method: 'S256' };
29
+ }
30
+
31
+ /**
32
+ * Issue a single-use state value and persist it (with the PKCE verifier and
33
+ * scope metadata) so the callback can validate the round-trip.
34
+ *
35
+ * @returns {{ state, code_verifier?, code_challenge?, code_challenge_method? }}
36
+ */
37
+ export function createAuthState({ service_key, provider, scope = null, redirect_uri = null, pkce = false, ttl_ms = DEFAULT_TTL_MS } = {}) {
38
+ if (!service_key) throw new Error('service_key is required');
39
+ const db = getDb();
40
+ const state = base64url(randomBytes(24));
41
+ const now = Date.now();
42
+ const created_at = nowIso();
43
+ const expires_at = new Date(now + (Number(ttl_ms) || DEFAULT_TTL_MS)).toISOString();
44
+
45
+ let pkceParts = null;
46
+ if (pkce) pkceParts = generatePkce();
47
+
48
+ db.prepare(`
49
+ INSERT INTO oauth_states (state, service_key, provider, scope_json, code_verifier, redirect_uri, created_at, expires_at, consumed_at)
50
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, NULL)
51
+ `).run(
52
+ state,
53
+ String(service_key),
54
+ String(provider || 'custom'),
55
+ scope ? JSON.stringify(scope) : null,
56
+ pkceParts?.code_verifier || null,
57
+ redirect_uri || null,
58
+ created_at,
59
+ expires_at,
60
+ );
61
+
62
+ return {
63
+ state,
64
+ code_verifier: pkceParts?.code_verifier || null,
65
+ code_challenge: pkceParts?.code_challenge || null,
66
+ code_challenge_method: pkceParts?.code_challenge_method || null,
67
+ };
68
+ }
69
+
70
+ /**
71
+ * Validate + burn a state value. Returns the stored row (scope + verifier) on
72
+ * success, or throws. Single-use: a second call with the same state fails.
73
+ */
74
+ export function consumeAuthState(state) {
75
+ if (!state) { const e = new Error('missing state'); e.code = 'state_invalid'; throw e; }
76
+ const db = getDb();
77
+ const row = db.prepare('SELECT * FROM oauth_states WHERE state = ?').get(String(state));
78
+ if (!row) { const e = new Error('unknown or already-consumed state'); e.code = 'state_invalid'; throw e; }
79
+ if (row.consumed_at) { const e = new Error('state already used'); e.code = 'state_replayed'; throw e; }
80
+ if (row.expires_at && Date.parse(row.expires_at) < Date.now()) {
81
+ const e = new Error('state expired'); e.code = 'state_expired'; throw e;
82
+ }
83
+ // Burn it. The WHERE clause guards against a concurrent double-consume.
84
+ const res = db.prepare('UPDATE oauth_states SET consumed_at = ? WHERE state = ? AND consumed_at IS NULL')
85
+ .run(nowIso(), String(state));
86
+ if (res.changes !== 1) { const e = new Error('state already used'); e.code = 'state_replayed'; throw e; }
87
+
88
+ let scope = null;
89
+ try { scope = row.scope_json ? JSON.parse(row.scope_json) : null; } catch { scope = null; }
90
+ return {
91
+ state: row.state,
92
+ service_key: row.service_key,
93
+ provider: row.provider,
94
+ scope,
95
+ code_verifier: row.code_verifier || null,
96
+ redirect_uri: row.redirect_uri || null,
97
+ };
98
+ }
99
+
100
+ /**
101
+ * Build the provider authorize URL the "Sign in with…" button redirects to.
102
+ *
103
+ * @param {object} provider resolved provider (resolveProvider output)
104
+ * @param {object} opts { client_id, redirect_uri, state, code_challenge }
105
+ */
106
+ export function buildAuthorizeUrl(provider, opts = {}) {
107
+ if (!provider?.authorize_url) throw new Error('provider.authorize_url required');
108
+ if (!opts.client_id) throw new Error('client_id required');
109
+ if (!opts.redirect_uri) throw new Error('redirect_uri required');
110
+ const url = new URL(provider.authorize_url);
111
+ url.searchParams.set('response_type', 'code');
112
+ url.searchParams.set('client_id', String(opts.client_id));
113
+ url.searchParams.set('redirect_uri', String(opts.redirect_uri));
114
+ if (provider.scopes?.length) url.searchParams.set('scope', provider.scopes.join(' '));
115
+ if (opts.state) url.searchParams.set('state', String(opts.state));
116
+ if (provider.pkce && opts.code_challenge) {
117
+ url.searchParams.set('code_challenge', String(opts.code_challenge));
118
+ url.searchParams.set('code_challenge_method', 'S256');
119
+ }
120
+ for (const [k, v] of Object.entries(provider.extra_auth_params || {})) {
121
+ if (v != null) url.searchParams.set(k, String(v));
122
+ }
123
+ return url.toString();
124
+ }
125
+
126
+ function parseTokenResponse(data) {
127
+ if (!data || typeof data !== 'object') return null;
128
+ const access_token = data.access_token || null;
129
+ if (!access_token) return null;
130
+ return {
131
+ access_token,
132
+ refresh_token: data.refresh_token || null,
133
+ token_type: data.token_type || 'Bearer',
134
+ expires_in: Number.isFinite(data.expires_in) ? data.expires_in : null,
135
+ scope: data.scope || null,
136
+ };
137
+ }
138
+
139
+ async function postForm(tokenUrl, params, fetchFn) {
140
+ const body = new URLSearchParams(params).toString();
141
+ const res = await fetchFn(tokenUrl, {
142
+ method: 'POST',
143
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded', Accept: 'application/json' },
144
+ body,
145
+ });
146
+ let data = null;
147
+ try { data = await res.json(); } catch { data = null; }
148
+ return { res, data };
149
+ }
150
+
151
+ /**
152
+ * Exchange an authorization code for tokens.
153
+ *
154
+ * @param {object} provider resolved provider config (needs token_url)
155
+ * @param {object} opts { code, client_id, client_secret, redirect_uri, code_verifier }
156
+ * @param {Function} fetchFn injectable fetch (tests pass a mock)
157
+ */
158
+ export async function exchangeCodeForTokens(provider, opts = {}, fetchFn = fetch) {
159
+ if (!provider?.token_url) throw new Error('provider.token_url required');
160
+ if (!opts.code) throw new Error('code required');
161
+ const params = {
162
+ grant_type: 'authorization_code',
163
+ code: opts.code,
164
+ client_id: opts.client_id || '',
165
+ redirect_uri: opts.redirect_uri || '',
166
+ };
167
+ if (opts.client_secret) params.client_secret = opts.client_secret;
168
+ if (opts.code_verifier) params.code_verifier = opts.code_verifier;
169
+
170
+ const { res, data } = await postForm(provider.token_url, params, fetchFn);
171
+ if (!res.ok) {
172
+ return { ok: false, error: 'token_exchange_failed', http_status: res.status, detail: data?.error || null };
173
+ }
174
+ const tokens = parseTokenResponse(data);
175
+ if (!tokens) return { ok: false, error: 'no_access_token' };
176
+ return { ok: true, ...tokens };
177
+ }
178
+
179
+ /**
180
+ * Re-mint an access token from a refresh token. Used by http_api_call on a 401.
181
+ *
182
+ * @param {object} provider resolved provider config (needs token_url)
183
+ * @param {object} opts { refresh_token, client_id, client_secret }
184
+ * @param {Function} fetchFn injectable fetch
185
+ */
186
+ export async function refreshAccessToken(provider, opts = {}, fetchFn = fetch) {
187
+ if (!provider?.token_url) throw new Error('provider.token_url required');
188
+ if (!opts.refresh_token) throw new Error('refresh_token required');
189
+ const params = {
190
+ grant_type: 'refresh_token',
191
+ refresh_token: opts.refresh_token,
192
+ client_id: opts.client_id || '',
193
+ };
194
+ if (opts.client_secret) params.client_secret = opts.client_secret;
195
+
196
+ const { res, data } = await postForm(provider.token_url, params, fetchFn);
197
+ if (!res.ok) {
198
+ return { ok: false, error: 'refresh_failed', http_status: res.status, detail: data?.error || null };
199
+ }
200
+ const tokens = parseTokenResponse(data);
201
+ if (!tokens) return { ok: false, error: 'no_access_token' };
202
+ // Providers often omit a new refresh_token on refresh — keep the old one.
203
+ return { ok: true, ...tokens, refresh_token: tokens.refresh_token || opts.refresh_token };
204
+ }
@@ -0,0 +1,102 @@
1
+ // lib/oauth/provider-registry.js — declarative OAuth2 provider catalog.
2
+ //
3
+ // Each provider is INERT DATA: authorize/token endpoints, default scopes, and
4
+ // whether PKCE is used. NO secrets live here — client id/secret are supplied by
5
+ // the operator once (per connection) and referenced from the vault by name.
6
+ //
7
+ // This registry is the single source of truth for "how do I talk to provider X's
8
+ // OAuth endpoints". A connection manifest's `oauth.provider` keys into it; the
9
+ // manifest may also override authorize_url/token_url/scopes inline so Tool-Smith
10
+ // connectors for not-yet-catalogued providers still work without editing code.
11
+ //
12
+ // Pure ESM — no DB, fs, or network imports.
13
+
14
+ const PROVIDERS = {
15
+ google: {
16
+ label: 'Google',
17
+ authorize_url: 'https://accounts.google.com/o/oauth2/v2/auth',
18
+ token_url: 'https://oauth2.googleapis.com/token',
19
+ pkce: true,
20
+ // Default to read-only mail+calendar scopes; connections add what they need.
21
+ default_scopes: ['openid', 'email'],
22
+ // Google requires these to mint a refresh token.
23
+ extra_auth_params: { access_type: 'offline', prompt: 'consent' },
24
+ },
25
+ meta: {
26
+ label: 'Meta (Facebook/Instagram)',
27
+ authorize_url: 'https://www.facebook.com/v19.0/dialog/oauth',
28
+ token_url: 'https://graph.facebook.com/v19.0/oauth/access_token',
29
+ pkce: false,
30
+ default_scopes: ['public_profile'],
31
+ extra_auth_params: {},
32
+ },
33
+ linkedin: {
34
+ label: 'LinkedIn',
35
+ authorize_url: 'https://www.linkedin.com/oauth/v2/authorization',
36
+ token_url: 'https://www.linkedin.com/oauth/v2/accessToken',
37
+ pkce: false,
38
+ default_scopes: ['r_liteprofile'],
39
+ extra_auth_params: {},
40
+ },
41
+ tiktok: {
42
+ label: 'TikTok',
43
+ authorize_url: 'https://www.tiktok.com/v2/auth/authorize/',
44
+ token_url: 'https://open.tiktokapis.com/v2/oauth/token/',
45
+ pkce: true,
46
+ default_scopes: ['user.info.basic'],
47
+ extra_auth_params: {},
48
+ },
49
+ hubspot: {
50
+ label: 'HubSpot',
51
+ authorize_url: 'https://app.hubspot.com/oauth/authorize',
52
+ token_url: 'https://api.hubapi.com/oauth/v1/token',
53
+ pkce: false,
54
+ default_scopes: ['oauth'],
55
+ extra_auth_params: {},
56
+ },
57
+ };
58
+
59
+ /**
60
+ * Resolve a provider config, layering manifest-supplied overrides on top of the
61
+ * built-in catalog. Either source may be absent: a fully-inline connection
62
+ * manifest needs no catalog entry; a catalogued provider needs no inline URLs.
63
+ *
64
+ * @param {string} providerKey e.g. 'google'
65
+ * @param {object} [overrides] connection.oauth block (authorize_url, token_url, scopes, pkce, extra_auth_params)
66
+ * @returns {object|null} normalized provider config, or null if unresolvable
67
+ */
68
+ export function resolveProvider(providerKey, overrides = {}) {
69
+ const base = providerKey && PROVIDERS[providerKey] ? PROVIDERS[providerKey] : null;
70
+ const authorize_url = overrides.authorize_url || base?.authorize_url || null;
71
+ const token_url = overrides.token_url || base?.token_url || null;
72
+ if (!authorize_url || !token_url) return null;
73
+
74
+ const scopes = Array.isArray(overrides.scopes) && overrides.scopes.length
75
+ ? overrides.scopes.slice()
76
+ : (base?.default_scopes || []).slice();
77
+
78
+ const pkce = typeof overrides.pkce === 'boolean' ? overrides.pkce : Boolean(base?.pkce);
79
+
80
+ const extra_auth_params = {
81
+ ...(base?.extra_auth_params || {}),
82
+ ...(overrides.extra_auth_params && typeof overrides.extra_auth_params === 'object'
83
+ ? overrides.extra_auth_params
84
+ : {}),
85
+ };
86
+
87
+ return {
88
+ provider: providerKey || 'custom',
89
+ label: base?.label || providerKey || 'Custom provider',
90
+ authorize_url,
91
+ token_url,
92
+ scopes,
93
+ pkce,
94
+ extra_auth_params,
95
+ };
96
+ }
97
+
98
+ export function listProviders() {
99
+ return Object.entries(PROVIDERS).map(([key, p]) => ({ provider: key, label: p.label, pkce: p.pkce }));
100
+ }
101
+
102
+ export { PROVIDERS };
package/lib/runtime.js CHANGED
@@ -12,7 +12,7 @@ import { listApprovalRequests } from './approvals.js';
12
12
  import { defaultModelForEngine, normalizeAgentEngine } from './agent-engines.js';
13
13
  import { DEFAULT_PROJECT_ID, appendProjectChangelog, getProject } from './projects.js';
14
14
  import { listActivity, listTasks, reportingSnapshot } from './delegation.js';
15
- import { getMainAgentTrustMode } from './tools/registry.js';
15
+ import { getMainAgentTrustMode, listMarketplaceTools } from './tools/registry.js';
16
16
  import { defaultSkillsMarkdown } from './marketplace-seeds.js';
17
17
  import { getConfig } from './config.js';
18
18
  import { publishLiveEvent, publishStateChanged } from './live-events.js';
@@ -154,6 +154,79 @@ export function setAgentToolPermission(agentId, toolName, mode = 'approval_requi
154
154
  return rowToAgentToolPermission(db.prepare('SELECT * FROM agent_tool_permissions WHERE agent_id = ? AND tool_name = ?').get(agentId, toolName));
155
155
  }
156
156
 
157
+ /**
158
+ * Set an agent's declared toolset from the simple agent page.
159
+ *
160
+ * Two sources of truth are kept in sync:
161
+ * - `agents.tools` (JSON list) drives the runner prompt and the /agents card
162
+ * icons — it is the agent's *declared* toolset.
163
+ * - `agent_tool_permissions` is the *enforcement* layer the runtime actually
164
+ * gates on. Newly added tools get a safe default mode (read-only → auto,
165
+ * anything that can write/send → approval_required), matching the Caretaker
166
+ * seeding convention. Existing non-disabled rows are left untouched so the
167
+ * deep per-tool modes set in Configuration survive a simple-page edit.
168
+ *
169
+ * Unknown tool names are dropped (a stale form can't poison the toolset).
170
+ * Workspace files are intentionally NOT rewritten here — writeAgentFiles would
171
+ * regenerate skills.md from defaults and clobber an owner's edits.
172
+ */
173
+ export function updateAgentToolset(agentId, toolNames = []) {
174
+ if (!agentId) return { ok: false, error: 'agent_id is required' };
175
+ const db = getDb();
176
+ const agentRow = db.prepare('SELECT id, tools FROM agents WHERE id = ?').get(agentId);
177
+ if (!agentRow) return { ok: false, error: 'agent not found' };
178
+
179
+ const known = new Map(listMarketplaceTools().map(tool => [tool.name, tool]));
180
+ const next = [...new Set(
181
+ (Array.isArray(toolNames) ? toolNames : [])
182
+ .map(name => String(name || '').trim())
183
+ .filter(name => name && known.has(name))
184
+ )];
185
+ const desired = new Set(next);
186
+
187
+ // Reconcile against the enforcement layer (permission rows), NOT just the
188
+ // declared `agents.tools` column — agents created via createAgent carry a
189
+ // tools list but no permission rows, so a pure column diff would leave newly
190
+ // "kept" tools non-functional.
191
+ const existing = listAgentToolPermissions(agentId);
192
+ const existingMode = new Map(existing.map(p => [p.tool_name, p.mode]));
193
+ const prevEnabled = new Set(existing.filter(p => p.mode !== 'disabled').map(p => p.tool_name));
194
+
195
+ // 1) Declared toolset (drives the runner prompt + the /agents card icons).
196
+ db.prepare('UPDATE agents SET tools = ? WHERE id = ?').run(JSON.stringify(next), agentId);
197
+
198
+ // 2) Enable every desired tool. Existing non-disabled rows are left untouched
199
+ // so deep per-tool modes set in Configuration survive a simple-page edit;
200
+ // new or previously-disabled tools get a safe default (read-only → auto,
201
+ // anything that can write/send → approval_required).
202
+ for (const name of next) {
203
+ const cur = existingMode.get(name);
204
+ if (cur && cur !== 'disabled') continue;
205
+ const tool = known.get(name);
206
+ const mode = (tool?.risk_level === 'low' || tool?.approval_mode === 'auto')
207
+ ? 'auto'
208
+ : 'approval_required';
209
+ setAgentToolPermission(agentId, name, mode);
210
+ }
211
+ // 3) Disable previously-enabled tools the owner removed.
212
+ for (const p of existing) {
213
+ if (p.mode !== 'disabled' && !desired.has(p.tool_name)) {
214
+ setAgentToolPermission(agentId, p.tool_name, 'disabled');
215
+ }
216
+ }
217
+
218
+ const added = next.filter(name => !prevEnabled.has(name));
219
+ const removed = [...prevEnabled].filter(name => !desired.has(name));
220
+
221
+ appendAudit({
222
+ type: 'agent.tools.update',
223
+ summary: `Updated toolset for ${agentId}`,
224
+ status: 'complete',
225
+ meta: { agent_id: agentId, added, removed, count: next.length, surface: 'agent-detail-simple' },
226
+ });
227
+ return { ok: true, tools: next, added, removed };
228
+ }
229
+
157
230
  export function ensureOpsAgent({ silent = false } = {}) {
158
231
  const tools = ['directory_list', 'file_read', 'file_search', 'terminal_run', 'web_search', 'web_fetch'];
159
232
  const created = createAgent({
package/lib/schema.js CHANGED
@@ -1555,6 +1555,23 @@ CREATE TABLE IF NOT EXISTS tool_proposals (
1555
1555
  );
1556
1556
  CREATE INDEX IF NOT EXISTS idx_tool_proposals_status ON tool_proposals(status);
1557
1557
 
1558
+ -- OAuth2 authorization-code state ledger. Single-use CSRF state values for the
1559
+ -- connection OAuth flow. A row is created at /oauth/start and consumed exactly
1560
+ -- once at /oauth/callback (consumed_at set). Replay of a consumed/expired state
1561
+ -- is rejected. code_verifier holds the PKCE verifier (never the access token).
1562
+ CREATE TABLE IF NOT EXISTS oauth_states (
1563
+ state TEXT PRIMARY KEY,
1564
+ service_key TEXT NOT NULL,
1565
+ provider TEXT NOT NULL,
1566
+ scope_json TEXT,
1567
+ code_verifier TEXT,
1568
+ redirect_uri TEXT,
1569
+ created_at TEXT NOT NULL,
1570
+ expires_at TEXT NOT NULL,
1571
+ consumed_at TEXT
1572
+ );
1573
+ CREATE INDEX IF NOT EXISTS idx_oauth_states_service ON oauth_states(service_key);
1574
+
1558
1575
 
1559
1576
  `;
1560
1577
 
@@ -14,10 +14,12 @@
14
14
  // Risk + approval gating happen UPSTREAM in executeRegistryTool on the endpoint's
15
15
  // declared (clamped) risk tier before this adapter is ever called.
16
16
 
17
- import { getSecret } from '../../secrets.js';
17
+ import { getSecret, setSecret } from '../../secrets.js';
18
18
  import { wrapFetch } from '../../egress.js';
19
19
  import { assertPublicHttpUrl } from './web.js';
20
20
  import { resolveConnectorEndpoint } from '../connectors/registry.js';
21
+ import { resolveProvider } from '../../oauth/provider-registry.js';
22
+ import { refreshAccessToken } from '../../oauth/flow.js';
21
23
 
22
24
  const MAX_RESPONSE_BYTES = 512000;
23
25
  const RESERVED_KEYS = new Set(['__connector_slug', '__endpoint', 'approval_id', 'body', 'query']);
@@ -59,11 +61,50 @@ function buildAuth(auth = {}) {
59
61
  const user = need(auth.username_ref);
60
62
  const pass = need(auth.password_ref);
61
63
  headers.Authorization = `Basic ${Buffer.from(`${user}:${pass}`).toString('base64')}`;
64
+ } else if (auth.type === 'oauth2') {
65
+ const secret = need(auth.access_token_ref);
66
+ headers[auth.header || 'Authorization'] = `${auth.prefix ?? 'Bearer '}${secret}`;
62
67
  }
63
68
  // type 'none' → no injection.
64
69
  return { headers, query };
65
70
  }
66
71
 
72
+ /**
73
+ * Attempt a single OAuth2 access-token refresh for an oauth2 connector, re-storing
74
+ * the new token in the vault. Returns true on success. Best-effort: any missing
75
+ * refresh material or provider config means "no refresh" (returns false). The
76
+ * minted token is never logged or returned to the caller.
77
+ */
78
+ async function tryRefreshOauthToken(auth, fetchFn) {
79
+ if (auth?.type !== 'oauth2' || !auth.refresh_token_ref) return false;
80
+ const refreshToken = getSecret(auth.refresh_token_ref);
81
+ if (!refreshToken) return false;
82
+ const provider = resolveProvider(auth.provider, { token_url: auth.token_url });
83
+ if (!provider?.token_url) return false;
84
+ const clientId = auth.client_id_ref ? getSecret(auth.client_id_ref) : null;
85
+ const clientSecret = auth.client_secret_ref ? getSecret(auth.client_secret_ref) : null;
86
+ let result;
87
+ try {
88
+ result = await refreshAccessToken(
89
+ provider,
90
+ { refresh_token: String(refreshToken), client_id: clientId || '', client_secret: clientSecret || '' },
91
+ fetchFn,
92
+ );
93
+ } catch {
94
+ return false;
95
+ }
96
+ if (!result?.ok || !result.access_token) return false;
97
+ try {
98
+ setSecret(auth.access_token_ref, result.access_token, { source: 'oauth_refresh' });
99
+ if (result.refresh_token && auth.refresh_token_ref) {
100
+ setSecret(auth.refresh_token_ref, result.refresh_token, { source: 'oauth_refresh' });
101
+ }
102
+ } catch {
103
+ return false;
104
+ }
105
+ return true;
106
+ }
107
+
67
108
  export async function httpApiCall(input = {}, options = {}) {
68
109
  const connectorSlug = input.__connector_slug;
69
110
  const endpointName = input.__endpoint;
@@ -128,7 +169,7 @@ export async function httpApiCall(input = {}, options = {}) {
128
169
  // baseHeaders never carry the secret; authHeaderKeys are injected only when the
129
170
  // target host matches the original (auth must never ride a cross-host redirect).
130
171
  const baseHeaders = { Accept: 'application/json', ...(manifest.default_headers || {}) };
131
- const authHeaderKeys = Object.keys(authParts.headers);
172
+ let authHeaderKeys = Object.keys(authParts.headers);
132
173
  const method = endpointDef.method;
133
174
  const hasBody = ['POST', 'PUT', 'PATCH', 'DELETE'].includes(method);
134
175
  let bodyStr = null;
@@ -170,35 +211,58 @@ export async function httpApiCall(input = {}, options = {}) {
170
211
  // allowlist before the next request; a redirect outside the allowlist is refused.
171
212
  const wrappedFetch = wrapFetch(toolName, options.agent_id ?? null);
172
213
  const REDIRECT_CODES = new Set([301, 302, 303, 307, 308]);
173
- let currentUrl = url;
174
214
  let res;
175
- for (let hop = 0; hop < 5; hop++) {
176
- try {
177
- res = await wrappedFetch(currentUrl, buildInit(currentUrl.hostname.toLowerCase()));
178
- } catch (err) {
179
- return { ok: false, status: 'error', error: 'request_failed', message: String(err?.message || err) };
180
- }
181
- if (!REDIRECT_CODES.has(res.status)) break;
182
- const loc = res.headers.get('location');
183
- if (!loc) break; // 3xx with no Location — return it as-is below.
184
- let next;
185
- try {
186
- next = new URL(loc, currentUrl);
187
- } catch {
188
- return { ok: false, status: 'error', error: 'bad_redirect', message: `Invalid redirect target: ${loc}` };
189
- }
190
- try {
191
- assertPublicHttpUrl(next.toString());
192
- } catch (err) {
193
- return { ok: false, status: 'error', error: 'blocked_redirect', message: `Redirect blocked: ${err.message}` };
194
- }
195
- if (!manifest.allowed_hosts.includes(next.hostname.toLowerCase())) {
196
- return { ok: false, status: 'error', error: 'blocked_redirect', message: `Redirect to ${next.hostname} is not in the connector allowlist` };
215
+ // Outer loop allows a SINGLE OAuth2 refresh-on-401 retry. attempt 0 is the
216
+ // normal call; attempt 1 only runs after a successful token refresh.
217
+ for (let attempt = 0; attempt < 2; attempt++) {
218
+ let currentUrl = url;
219
+ let redirectError = null;
220
+ for (let hop = 0; hop < 5; hop++) {
221
+ try {
222
+ res = await wrappedFetch(currentUrl, buildInit(currentUrl.hostname.toLowerCase()));
223
+ } catch (err) {
224
+ return { ok: false, status: 'error', error: 'request_failed', message: String(err?.message || err) };
225
+ }
226
+ if (!REDIRECT_CODES.has(res.status)) break;
227
+ const loc = res.headers.get('location');
228
+ if (!loc) break; // 3xx with no Location return it as-is below.
229
+ let next;
230
+ try {
231
+ next = new URL(loc, currentUrl);
232
+ } catch {
233
+ return { ok: false, status: 'error', error: 'bad_redirect', message: `Invalid redirect target: ${loc}` };
234
+ }
235
+ try {
236
+ assertPublicHttpUrl(next.toString());
237
+ } catch (err) {
238
+ return { ok: false, status: 'error', error: 'blocked_redirect', message: `Redirect blocked: ${err.message}` };
239
+ }
240
+ if (!manifest.allowed_hosts.includes(next.hostname.toLowerCase())) {
241
+ return { ok: false, status: 'error', error: 'blocked_redirect', message: `Redirect to ${next.hostname} is not in the connector allowlist` };
242
+ }
243
+ currentUrl = next;
244
+ if (hop === 4) {
245
+ redirectError = { ok: false, status: 'error', error: 'too_many_redirects', message: 'Exceeded redirect limit' };
246
+ break;
247
+ }
197
248
  }
198
- currentUrl = next;
199
- if (hop === 4) {
200
- return { ok: false, status: 'error', error: 'too_many_redirects', message: 'Exceeded redirect limit' };
249
+ if (redirectError) return redirectError;
250
+
251
+ // OAuth2 transparent refresh: on a 401, attempt exactly one token refresh,
252
+ // re-store the new token, rebuild auth headers, and retry once.
253
+ if (attempt === 0 && res.status === 401 && (manifest.auth || {}).type === 'oauth2') {
254
+ const refreshed = await tryRefreshOauthToken(manifest.auth, wrappedFetch);
255
+ if (refreshed) {
256
+ try {
257
+ authParts = buildAuth(manifest.auth || {});
258
+ authHeaderKeys = Object.keys(authParts.headers);
259
+ } catch {
260
+ break; // can't rebuild auth — return the 401 as-is.
261
+ }
262
+ continue; // retry with the fresh token.
263
+ }
201
264
  }
265
+ break;
202
266
  }
203
267
 
204
268
  const respContentType = res.headers.get('content-type') || '';
@@ -37,7 +37,7 @@
37
37
 
38
38
  export const CONNECTOR_SLUG_REGEX = /^[a-z][a-z0-9-]{2,63}$/;
39
39
  export const MAX_CONNECTOR_BYTES = 64 * 1024;
40
- export const VALID_AUTH_TYPES = new Set(['bearer', 'api_key', 'basic', 'none']);
40
+ export const VALID_AUTH_TYPES = new Set(['bearer', 'api_key', 'basic', 'oauth2', 'none']);
41
41
 
42
42
  // Ordered low→high. 'blocked' is never authorable and is intentionally absent.
43
43
  export const RISK_ORDER = ['low', 'medium', 'high', 'irreversible_external'];
@@ -53,6 +53,8 @@ const MAX_ENDPOINTS = 50;
53
53
  // comparison is applied at runtime).
54
54
  const RAW_SECRET_KEYS = new Set([
55
55
  'token', 'key', 'secret', 'password', 'value', 'api_key', 'bearer', 'credentials',
56
+ // oauth2 raw-token names — must be referenced via *_ref, never inline.
57
+ 'access_token', 'refresh_token', 'client_id', 'client_secret',
56
58
  ]);
57
59
 
58
60
  // ─── Internal helpers ────────────────────────────────────────────────────────
@@ -171,6 +173,27 @@ function validateAuth(auth, errors) {
171
173
  pushErr(errors, 'auth.password_ref', `must match ${SECRET_REF_REGEX}`);
172
174
  }
173
175
  }
176
+
177
+ if (type === 'oauth2') {
178
+ // The access token is referenced from the vault, never inline. Refresh fields
179
+ // are optional (a connector can carry a long-lived token with no refresh).
180
+ if (!auth.access_token_ref || typeof auth.access_token_ref !== 'string') {
181
+ pushErr(errors, 'auth.access_token_ref', 'required for oauth2 auth (vault ref)');
182
+ } else if (!SECRET_REF_REGEX.test(auth.access_token_ref)) {
183
+ pushErr(errors, 'auth.access_token_ref', `must match ${SECRET_REF_REGEX}`);
184
+ }
185
+ for (const field of ['refresh_token_ref', 'client_id_ref', 'client_secret_ref']) {
186
+ if (auth[field] == null) continue;
187
+ if (typeof auth[field] !== 'string' || !SECRET_REF_REGEX.test(auth[field])) {
188
+ pushErr(errors, `auth.${field}`, `must match ${SECRET_REF_REGEX}`);
189
+ }
190
+ }
191
+ if (auth.token_url != null) {
192
+ let ok = false;
193
+ try { ok = new URL(auth.token_url).protocol === 'https:'; } catch { ok = false; }
194
+ if (!ok) pushErr(errors, 'auth.token_url', 'must be a valid https URL');
195
+ }
196
+ }
174
197
  }
175
198
 
176
199
  function validateDefaultHeaders(headers, errors) {
@@ -417,6 +440,9 @@ export function validateConnectorManifest(manifest, opts = {}) {
417
440
  const allowedAuthKeys = new Set([
418
441
  'type', 'header', 'prefix', 'query_param',
419
442
  'secret_ref', 'username_ref', 'password_ref',
443
+ // oauth2: token reference + refresh material (all *_ref, never raw)
444
+ 'access_token_ref', 'refresh_token_ref', 'client_id_ref', 'client_secret_ref',
445
+ 'token_url', 'provider',
420
446
  ]);
421
447
  for (const [k, v] of Object.entries(manifest.auth)) {
422
448
  if (allowedAuthKeys.has(k)) normalizedAuth[k] = v;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "madarx",
3
- "version": "2.15.1",
3
+ "version": "2.16.0",
4
4
  "type": "module",
5
5
  "description": "Madarx OS — Next.js product with SQLite-backed runtime, scheduled cron daemon, and approval-gated local runners.",
6
6
  "license": "MIT",