@desplega.ai/agent-swarm 1.20.0 → 1.49.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 (810) hide show
  1. package/.claude/settings.json +84 -0
  2. package/.claude/settings.local.json +3 -1
  3. package/.entire/settings.json +4 -0
  4. package/.env.docker.example +40 -23
  5. package/.env.example +39 -1
  6. package/.github/ISSUE_TEMPLATE/bug_report.yml +78 -0
  7. package/.github/ISSUE_TEMPLATE/community-template.yml +77 -0
  8. package/.github/ISSUE_TEMPLATE/config.yml +8 -0
  9. package/.github/ISSUE_TEMPLATE/feature_request.yml +60 -0
  10. package/.github/PULL_REQUEST_TEMPLATE/community-template.md +29 -0
  11. package/.github/workflows/ci.yml +3 -27
  12. package/.github/workflows/docker-and-deploy.yml +20 -5
  13. package/.github/workflows/merge-gate.yml +233 -0
  14. package/.opencode/plugins/entire.ts +133 -0
  15. package/.superset/config.json +6 -0
  16. package/.wts-setup.ts +103 -34
  17. package/CHANGELOG.md +447 -0
  18. package/CLAUDE.md +422 -5
  19. package/CONTRIBUTING.md +46 -1
  20. package/DEPLOYMENT.md +26 -9
  21. package/Dockerfile +15 -7
  22. package/Dockerfile.worker +99 -67
  23. package/MCP.md +452 -17
  24. package/README.md +271 -169
  25. package/api-entrypoint.sh +56 -0
  26. package/depot.json +1 -0
  27. package/docker-compose.example.yml +194 -3
  28. package/docker-compose.local.yml +119 -0
  29. package/docker-entrypoint.sh +393 -113
  30. package/docs-site/app/api/search/route.ts +4 -0
  31. package/docs-site/app/docs/[[...slug]]/page.tsx +87 -0
  32. package/docs-site/app/docs/layout.tsx +12 -0
  33. package/docs-site/app/globals.css +24 -0
  34. package/docs-site/app/layout.config.tsx +34 -0
  35. package/docs-site/app/layout.tsx +119 -0
  36. package/docs-site/app/llms-full.txt/route.ts +11 -0
  37. package/docs-site/app/llms.mdx/docs/[[...slug]]/route.ts +24 -0
  38. package/docs-site/app/llms.txt/route.ts +8 -0
  39. package/docs-site/app/page.tsx +5 -0
  40. package/docs-site/app/robots.ts +13 -0
  41. package/docs-site/app/sitemap.ts +37 -0
  42. package/docs-site/components/api-page.client.tsx +4 -0
  43. package/docs-site/components/api-page.tsx +7 -0
  44. package/docs-site/components/mdx/mermaid.tsx +55 -0
  45. package/docs-site/content/docs/(documentation)/architecture/agents.mdx +117 -0
  46. package/docs-site/content/docs/(documentation)/architecture/hooks.mdx +77 -0
  47. package/docs-site/content/docs/(documentation)/architecture/memory.mdx +96 -0
  48. package/docs-site/content/docs/(documentation)/architecture/meta.json +4 -0
  49. package/docs-site/content/docs/(documentation)/architecture/overview.mdx +172 -0
  50. package/docs-site/content/docs/(documentation)/concepts/epics.mdx +98 -0
  51. package/docs-site/content/docs/(documentation)/concepts/meta.json +4 -0
  52. package/docs-site/content/docs/(documentation)/concepts/scheduling.mdx +136 -0
  53. package/docs-site/content/docs/(documentation)/concepts/services.mdx +104 -0
  54. package/docs-site/content/docs/(documentation)/concepts/task-lifecycle.mdx +148 -0
  55. package/docs-site/content/docs/(documentation)/concepts/workflows.mdx +209 -0
  56. package/docs-site/content/docs/(documentation)/contributing.mdx +158 -0
  57. package/docs-site/content/docs/(documentation)/getting-started.mdx +157 -0
  58. package/docs-site/content/docs/(documentation)/guides/agentmail-integration.mdx +79 -0
  59. package/docs-site/content/docs/(documentation)/guides/deployment.mdx +171 -0
  60. package/docs-site/content/docs/(documentation)/guides/github-integration.mdx +81 -0
  61. package/docs-site/content/docs/(documentation)/guides/gitlab-integration.mdx +93 -0
  62. package/docs-site/content/docs/(documentation)/guides/linear-integration.mdx +98 -0
  63. package/docs-site/content/docs/(documentation)/guides/meta.json +13 -0
  64. package/docs-site/content/docs/(documentation)/guides/sentry-integration.mdx +52 -0
  65. package/docs-site/content/docs/(documentation)/guides/slack-integration.mdx +179 -0
  66. package/docs-site/content/docs/(documentation)/guides/x402-payments.mdx +154 -0
  67. package/docs-site/content/docs/(documentation)/index.mdx +65 -0
  68. package/docs-site/content/docs/(documentation)/meta.json +19 -0
  69. package/docs-site/content/docs/(documentation)/reference/cli.mdx +241 -0
  70. package/docs-site/content/docs/(documentation)/reference/environment-variables.mdx +205 -0
  71. package/docs-site/content/docs/(documentation)/reference/mcp-tools.mdx +449 -0
  72. package/docs-site/content/docs/(documentation)/reference/meta.json +4 -0
  73. package/docs-site/content/docs/api-reference/active-sessions.mdx +9 -0
  74. package/docs-site/content/docs/api-reference/agents.mdx +9 -0
  75. package/docs-site/content/docs/api-reference/channels.mdx +9 -0
  76. package/docs-site/content/docs/api-reference/config.mdx +9 -0
  77. package/docs-site/content/docs/api-reference/debug.mdx +9 -0
  78. package/docs-site/content/docs/api-reference/ecosystem.mdx +9 -0
  79. package/docs-site/content/docs/api-reference/epics.mdx +9 -0
  80. package/docs-site/content/docs/api-reference/index.mdx +32 -0
  81. package/docs-site/content/docs/api-reference/memory.mdx +9 -0
  82. package/docs-site/content/docs/api-reference/meta.json +25 -0
  83. package/docs-site/content/docs/api-reference/poll.mdx +9 -0
  84. package/docs-site/content/docs/api-reference/repos.mdx +9 -0
  85. package/docs-site/content/docs/api-reference/schedules.mdx +9 -0
  86. package/docs-site/content/docs/api-reference/session-data.mdx +9 -0
  87. package/docs-site/content/docs/api-reference/stats.mdx +9 -0
  88. package/docs-site/content/docs/api-reference/tasks.mdx +9 -0
  89. package/docs-site/content/docs/api-reference/trackers.mdx +9 -0
  90. package/docs-site/content/docs/api-reference/webhooks.mdx +9 -0
  91. package/docs-site/content/docs/api-reference/workflows.mdx +9 -0
  92. package/docs-site/content/docs/meta.json +3 -0
  93. package/docs-site/lib/get-llm-text.ts +10 -0
  94. package/docs-site/lib/openapi.ts +23 -0
  95. package/docs-site/lib/source.ts +8 -0
  96. package/docs-site/mdx-components.tsx +13 -0
  97. package/docs-site/next.config.mjs +29 -0
  98. package/docs-site/package.json +35 -0
  99. package/docs-site/pnpm-lock.yaml +5407 -0
  100. package/docs-site/postcss.config.mjs +8 -0
  101. package/docs-site/scripts/generate-docs.ts +171 -0
  102. package/docs-site/source.config.ts +17 -0
  103. package/docs-site/tsconfig.json +46 -0
  104. package/ecosystem.config.cjs +4 -4
  105. package/landing/next.config.ts +14 -0
  106. package/landing/package.json +31 -0
  107. package/landing/pnpm-lock.yaml +1091 -0
  108. package/landing/postcss.config.mjs +8 -0
  109. package/landing/public/apple-touch-icon.png +0 -0
  110. package/landing/public/favicon.ico +0 -0
  111. package/landing/public/logo.png +0 -0
  112. package/landing/public/og-image.png +0 -0
  113. package/landing/public/omghost-desplega.svg +30 -0
  114. package/landing/public/omghost-openfort.svg +9 -0
  115. package/landing/src/app/actions/waitlist.ts +25 -0
  116. package/landing/src/app/blog/openfort-hackathon/page.tsx +863 -0
  117. package/landing/src/app/blog/page.tsx +162 -0
  118. package/landing/src/app/blog/swarm-metrics/page.tsx +685 -0
  119. package/landing/src/app/examples/page.tsx +174 -0
  120. package/landing/src/app/examples/x402/page.tsx +456 -0
  121. package/landing/src/app/globals.css +122 -0
  122. package/landing/src/app/layout.tsx +134 -0
  123. package/landing/src/app/page.tsx +27 -0
  124. package/landing/src/app/robots.ts +13 -0
  125. package/landing/src/app/sitemap.ts +44 -0
  126. package/landing/src/components/architecture.tsx +163 -0
  127. package/landing/src/components/cta.tsx +52 -0
  128. package/landing/src/components/features.tsx +160 -0
  129. package/landing/src/components/footer.tsx +100 -0
  130. package/landing/src/components/hero.tsx +217 -0
  131. package/landing/src/components/how-it-works.tsx +165 -0
  132. package/landing/src/components/navbar.tsx +147 -0
  133. package/landing/src/components/waitlist.tsx +110 -0
  134. package/landing/src/components/why-choose.tsx +149 -0
  135. package/landing/src/components/workshops.tsx +328 -0
  136. package/landing/src/lib/utils.ts +6 -0
  137. package/landing/tsconfig.json +41 -0
  138. package/misc/transcripts/2026-03-09-pi-mono-e2e-verification.md +154 -0
  139. package/new-ui/CLAUDE.md +92 -0
  140. package/new-ui/README.md +73 -0
  141. package/new-ui/biome.json +42 -0
  142. package/new-ui/components.json +21 -0
  143. package/new-ui/index.html +25 -0
  144. package/new-ui/package.json +49 -0
  145. package/new-ui/pnpm-lock.yaml +4845 -0
  146. package/new-ui/public/logo.png +0 -0
  147. package/new-ui/src/api/client.ts +814 -0
  148. package/new-ui/src/api/hooks/index.ts +64 -0
  149. package/new-ui/src/api/hooks/use-agents.ts +58 -0
  150. package/new-ui/src/api/hooks/use-channels.ts +115 -0
  151. package/new-ui/src/api/hooks/use-config-api.ts +46 -0
  152. package/new-ui/src/api/hooks/use-costs.ts +122 -0
  153. package/new-ui/src/api/hooks/use-db-query.ts +29 -0
  154. package/new-ui/src/api/hooks/use-epics.ts +75 -0
  155. package/new-ui/src/api/hooks/use-repos.ts +61 -0
  156. package/new-ui/src/api/hooks/use-schedules.ts +81 -0
  157. package/new-ui/src/api/hooks/use-services.ts +16 -0
  158. package/new-ui/src/api/hooks/use-stats.ts +27 -0
  159. package/new-ui/src/api/hooks/use-tasks.ts +89 -0
  160. package/new-ui/src/api/hooks/use-workflows.ts +109 -0
  161. package/{ui/src/types/api.ts → new-ui/src/api/types.ts} +236 -10
  162. package/new-ui/src/app/App.tsx +13 -0
  163. package/new-ui/src/app/providers.tsx +32 -0
  164. package/new-ui/src/app/router.tsx +52 -0
  165. package/new-ui/src/components/layout/app-header.tsx +47 -0
  166. package/new-ui/src/components/layout/app-sidebar.tsx +128 -0
  167. package/new-ui/src/components/layout/breadcrumbs.tsx +57 -0
  168. package/new-ui/src/components/layout/config-guard.tsx +22 -0
  169. package/new-ui/src/components/layout/root-layout.tsx +40 -0
  170. package/new-ui/src/components/layout/swarm-switcher.tsx +85 -0
  171. package/new-ui/src/components/shared/command-menu.tsx +131 -0
  172. package/new-ui/src/components/shared/data-grid.tsx +141 -0
  173. package/new-ui/src/components/shared/empty-state.tsx +24 -0
  174. package/new-ui/src/components/shared/error-boundary.tsx +72 -0
  175. package/new-ui/src/components/shared/json-viewer.tsx +47 -0
  176. package/new-ui/src/components/shared/name-connection-modal.tsx +99 -0
  177. package/new-ui/src/components/shared/page-skeleton.tsx +16 -0
  178. package/new-ui/src/components/shared/session-log-viewer.tsx +364 -0
  179. package/new-ui/src/components/shared/stats-bar.tsx +132 -0
  180. package/new-ui/src/components/shared/status-badge.tsx +131 -0
  181. package/new-ui/src/components/shared/usage-summary.tsx +179 -0
  182. package/new-ui/src/components/ui/alert-dialog.tsx +176 -0
  183. package/new-ui/src/components/ui/alert.tsx +60 -0
  184. package/new-ui/src/components/ui/avatar.tsx +96 -0
  185. package/new-ui/src/components/ui/badge.tsx +46 -0
  186. package/new-ui/src/components/ui/button.tsx +62 -0
  187. package/new-ui/src/components/ui/card.tsx +75 -0
  188. package/new-ui/src/components/ui/command.tsx +160 -0
  189. package/new-ui/src/components/ui/dialog.tsx +143 -0
  190. package/new-ui/src/components/ui/dropdown-menu.tsx +226 -0
  191. package/new-ui/src/components/ui/input.tsx +21 -0
  192. package/new-ui/src/components/ui/label.tsx +19 -0
  193. package/new-ui/src/components/ui/progress.tsx +26 -0
  194. package/new-ui/src/components/ui/scroll-area.tsx +54 -0
  195. package/new-ui/src/components/ui/select.tsx +175 -0
  196. package/new-ui/src/components/ui/separator.tsx +28 -0
  197. package/new-ui/src/components/ui/sheet.tsx +132 -0
  198. package/new-ui/src/components/ui/sidebar.tsx +691 -0
  199. package/new-ui/src/components/ui/skeleton.tsx +13 -0
  200. package/new-ui/src/components/ui/sonner.tsx +35 -0
  201. package/new-ui/src/components/ui/switch.tsx +33 -0
  202. package/new-ui/src/components/ui/table.tsx +92 -0
  203. package/new-ui/src/components/ui/tabs.tsx +79 -0
  204. package/new-ui/src/components/ui/textarea.tsx +18 -0
  205. package/new-ui/src/components/ui/tooltip.tsx +51 -0
  206. package/new-ui/src/components/workflows/action-node.tsx +53 -0
  207. package/new-ui/src/components/workflows/condition-node.tsx +50 -0
  208. package/new-ui/src/components/workflows/graph-utils.ts +124 -0
  209. package/new-ui/src/components/workflows/json-tree.tsx +189 -0
  210. package/new-ui/src/components/workflows/node-styles.ts +10 -0
  211. package/new-ui/src/components/workflows/step-detail-sheet.tsx +87 -0
  212. package/new-ui/src/components/workflows/trigger-node.tsx +41 -0
  213. package/new-ui/src/components/workflows/workflow-graph.tsx +65 -0
  214. package/{ui/src/hooks/useAutoScroll.ts → new-ui/src/hooks/use-auto-scroll.ts} +0 -1
  215. package/new-ui/src/hooks/use-config.ts +203 -0
  216. package/new-ui/src/hooks/use-keyboard-shortcuts.ts +41 -0
  217. package/new-ui/src/hooks/use-mobile.ts +19 -0
  218. package/new-ui/src/hooks/use-theme.ts +60 -0
  219. package/new-ui/src/lib/config.ts +188 -0
  220. package/new-ui/src/lib/slugs.ts +71 -0
  221. package/{ui → new-ui}/src/lib/utils.ts +32 -0
  222. package/new-ui/src/main.tsx +11 -0
  223. package/new-ui/src/pages/agents/[id]/page.tsx +492 -0
  224. package/new-ui/src/pages/agents/page.tsx +134 -0
  225. package/new-ui/src/pages/chat/page.tsx +674 -0
  226. package/new-ui/src/pages/config/page.tsx +1109 -0
  227. package/new-ui/src/pages/dashboard/page.tsx +454 -0
  228. package/new-ui/src/pages/debug/page.tsx +275 -0
  229. package/new-ui/src/pages/epics/[id]/page.tsx +809 -0
  230. package/new-ui/src/pages/epics/page.tsx +321 -0
  231. package/new-ui/src/pages/not-found/page.tsx +18 -0
  232. package/new-ui/src/pages/repos/page.tsx +369 -0
  233. package/new-ui/src/pages/schedules/[id]/page.tsx +664 -0
  234. package/new-ui/src/pages/schedules/page.tsx +477 -0
  235. package/new-ui/src/pages/services/page.tsx +128 -0
  236. package/new-ui/src/pages/tasks/[id]/page.tsx +670 -0
  237. package/new-ui/src/pages/tasks/page.tsx +592 -0
  238. package/new-ui/src/pages/usage/page.tsx +195 -0
  239. package/new-ui/src/pages/workflow-runs/[id]/page.tsx +363 -0
  240. package/new-ui/src/pages/workflows/[id]/page.tsx +417 -0
  241. package/new-ui/src/pages/workflows/page.tsx +266 -0
  242. package/new-ui/src/styles/ag-grid.css +36 -0
  243. package/new-ui/src/styles/globals.css +213 -0
  244. package/new-ui/test-results/.last-run.json +4 -0
  245. package/{ui/tsconfig.json → new-ui/tsconfig.app.json} +7 -4
  246. package/new-ui/tsconfig.json +4 -0
  247. package/new-ui/tsconfig.node.json +26 -0
  248. package/new-ui/vercel.json +4 -0
  249. package/new-ui/vite.config.ts +28 -0
  250. package/openapi.json +4436 -0
  251. package/package.json +31 -7
  252. package/plugin/build-pi-skills.ts +233 -0
  253. package/plugin/commands/close-issue.md +7 -3
  254. package/plugin/commands/create-pr.md +18 -12
  255. package/plugin/commands/implement-issue.md +7 -3
  256. package/plugin/commands/respond-github.md +8 -4
  257. package/plugin/commands/review-pr.md +44 -10
  258. package/plugin/commands/start-leader.md +1 -3
  259. package/plugin/commands/start-worker.md +1 -3
  260. package/plugin/commands/work-on-task.md +22 -3
  261. package/plugin/pi-skills/close-issue/SKILL.md +90 -0
  262. package/plugin/pi-skills/create-pr/SKILL.md +99 -0
  263. package/plugin/pi-skills/implement-issue/SKILL.md +135 -0
  264. package/plugin/pi-skills/investigate-sentry-issue/SKILL.md +138 -0
  265. package/plugin/pi-skills/respond-github/SKILL.md +98 -0
  266. package/plugin/pi-skills/review-offered-task/SKILL.md +45 -0
  267. package/plugin/pi-skills/review-pr/SKILL.md +261 -0
  268. package/plugin/pi-skills/start-leader/SKILL.md +121 -0
  269. package/plugin/pi-skills/start-worker/SKILL.md +60 -0
  270. package/plugin/pi-skills/swarm-chat/SKILL.md +82 -0
  271. package/plugin/pi-skills/todos/SKILL.md +66 -0
  272. package/plugin/pi-skills/work-on-task/SKILL.md +65 -0
  273. package/plugin/skills/artifacts/examples/approval-flow.ts +34 -0
  274. package/plugin/skills/artifacts/examples/hono-dashboard.ts +31 -0
  275. package/plugin/skills/artifacts/examples/multi-artifact.ts +20 -0
  276. package/plugin/skills/artifacts/examples/static-report.sh +17 -0
  277. package/plugin/skills/artifacts/skill.md +71 -0
  278. package/prek.toml +75 -0
  279. package/scripts/check-db-boundary.sh +60 -0
  280. package/scripts/e2e-docker-provider.ts +820 -0
  281. package/scripts/e2e-io-schemas-test.ts +807 -0
  282. package/scripts/e2e-provider-test.ts +220 -0
  283. package/scripts/e2e-workflow-redesign.sh +229 -0
  284. package/scripts/e2e-workflow-test.sh +285 -0
  285. package/scripts/e2e-workflow-test.ts +857 -0
  286. package/scripts/generate-openapi.ts +26 -0
  287. package/scripts/measure-tool-tokens.ts +118 -0
  288. package/scripts/x402-e2e-test.ts +195 -0
  289. package/scripts/x402-test-server.ts +236 -0
  290. package/scripts/x402-testnet-e2e.ts +668 -0
  291. package/slack-manifest.json +17 -0
  292. package/src/agentmail/app.ts +65 -0
  293. package/src/agentmail/handlers.ts +207 -0
  294. package/src/agentmail/index.ts +9 -0
  295. package/src/agentmail/types.ts +51 -0
  296. package/src/artifact-sdk/browser-sdk.ts +30 -0
  297. package/src/artifact-sdk/index.ts +2 -0
  298. package/src/artifact-sdk/localtunnel.d.ts +20 -0
  299. package/src/artifact-sdk/port.ts +12 -0
  300. package/src/artifact-sdk/server.ts +156 -0
  301. package/src/artifact-sdk/tunnel.ts +19 -0
  302. package/src/be/chunking.ts +193 -0
  303. package/src/be/db-queries/oauth.ts +90 -0
  304. package/src/be/db-queries/tracker.ts +182 -0
  305. package/src/be/db.ts +2729 -770
  306. package/src/be/embedding.ts +80 -0
  307. package/src/be/migrations/001_initial.sql +409 -0
  308. package/src/be/migrations/002_one_time_schedules.sql +59 -0
  309. package/src/be/migrations/003_workflows.sql +51 -0
  310. package/src/be/migrations/004_workflow_source.sql +81 -0
  311. package/src/be/migrations/005_epic_next_steps.sql +2 -0
  312. package/src/be/migrations/006_vcs_provider.sql +94 -0
  313. package/src/be/migrations/007_task_dir.sql +2 -0
  314. package/src/be/migrations/008_workflow_redesign.sql +85 -0
  315. package/src/be/migrations/009_tracker_integration.sql +144 -0
  316. package/src/be/migrations/010_step_diagnostics.sql +1 -0
  317. package/src/be/migrations/011_step_next_port.sql +1 -0
  318. package/src/be/migrations/012_trigger_schema.sql +1 -0
  319. package/src/be/migrations/013_task_output_schema.sql +2 -0
  320. package/src/be/migrations/runner.ts +188 -0
  321. package/src/cli.tsx +231 -299
  322. package/src/commands/artifact.ts +241 -0
  323. package/src/commands/onboard/compose-generator.ts +169 -0
  324. package/src/commands/onboard/env-generator.ts +79 -0
  325. package/src/commands/onboard/manifest.ts +37 -0
  326. package/src/commands/onboard/presets.ts +85 -0
  327. package/src/commands/onboard/service-names.ts +47 -0
  328. package/src/commands/onboard/steps/core-credentials.tsx +111 -0
  329. package/src/commands/onboard/steps/custom-templates.tsx +168 -0
  330. package/src/commands/onboard/steps/generate.tsx +154 -0
  331. package/src/commands/onboard/steps/harness-credentials.tsx +195 -0
  332. package/src/commands/onboard/steps/harness.tsx +21 -0
  333. package/src/commands/onboard/steps/health-check.tsx +171 -0
  334. package/src/commands/onboard/steps/integration-github.tsx +105 -0
  335. package/src/commands/onboard/steps/integration-gitlab.tsx +79 -0
  336. package/src/commands/onboard/steps/integration-menu.tsx +58 -0
  337. package/src/commands/onboard/steps/integration-sentry.tsx +79 -0
  338. package/src/commands/onboard/steps/integration-slack.tsx +165 -0
  339. package/src/commands/onboard/steps/post-connect.tsx +145 -0
  340. package/src/commands/onboard/steps/post-dashboard.tsx +34 -0
  341. package/src/commands/onboard/steps/post-task.tsx +103 -0
  342. package/src/commands/onboard/steps/prereq-check.tsx +178 -0
  343. package/src/commands/onboard/steps/review.tsx +82 -0
  344. package/src/commands/onboard/steps/start.tsx +97 -0
  345. package/src/commands/onboard/templates.ts +34 -0
  346. package/src/commands/onboard/types.ts +259 -0
  347. package/src/commands/onboard.tsx +425 -0
  348. package/src/commands/runner.ts +1376 -559
  349. package/src/commands/setup.tsx +23 -38
  350. package/src/commands/shared/client-config.ts +41 -0
  351. package/src/github/app.ts +8 -0
  352. package/src/github/handlers.ts +93 -75
  353. package/src/github/index.ts +1 -0
  354. package/src/github/types.ts +1 -0
  355. package/src/gitlab/auth.ts +63 -0
  356. package/src/gitlab/handlers.ts +327 -0
  357. package/src/gitlab/index.ts +19 -0
  358. package/src/gitlab/reactions.ts +104 -0
  359. package/src/gitlab/types.ts +130 -0
  360. package/src/heartbeat/heartbeat.ts +425 -0
  361. package/src/heartbeat/index.ts +1 -0
  362. package/src/hooks/hook.ts +555 -4
  363. package/src/hooks/tool-loop-detection.test.ts +158 -0
  364. package/src/hooks/tool-loop-detection.ts +167 -0
  365. package/src/http/active-sessions.ts +172 -0
  366. package/src/http/agents.ts +328 -0
  367. package/src/http/config.ts +191 -0
  368. package/src/http/core.ts +309 -0
  369. package/src/http/db-query.ts +91 -0
  370. package/src/http/ecosystem.ts +63 -0
  371. package/src/http/epics.ts +460 -0
  372. package/src/http/index.ts +213 -0
  373. package/src/http/mcp.ts +77 -0
  374. package/src/http/memory.ts +168 -0
  375. package/src/http/openapi.ts +109 -0
  376. package/src/http/poll.ts +178 -0
  377. package/src/http/repos.ts +195 -0
  378. package/src/http/route-def.ts +123 -0
  379. package/src/http/schedules.ts +391 -0
  380. package/src/http/session-data.ts +241 -0
  381. package/src/http/stats.ts +174 -0
  382. package/src/http/tasks.ts +468 -0
  383. package/src/http/trackers/index.ts +10 -0
  384. package/src/http/trackers/linear.ts +187 -0
  385. package/src/http/types.ts +12 -0
  386. package/src/http/utils.ts +87 -0
  387. package/src/http/webhooks.ts +432 -0
  388. package/src/http/workflows.ts +522 -0
  389. package/src/http.ts +1 -1890
  390. package/src/linear/README.md +65 -0
  391. package/src/linear/app.ts +48 -0
  392. package/src/linear/client.ts +18 -0
  393. package/src/linear/index.ts +1 -0
  394. package/src/linear/oauth.ts +35 -0
  395. package/src/linear/outbound.ts +212 -0
  396. package/src/linear/sync.ts +543 -0
  397. package/src/linear/types.ts +7 -0
  398. package/src/linear/webhook.ts +104 -0
  399. package/src/oauth/README.md +66 -0
  400. package/src/oauth/index.ts +6 -0
  401. package/src/oauth/wrapper.ts +204 -0
  402. package/src/prompts/base-prompt.ts +366 -24
  403. package/src/prompts/defaults.ts +196 -0
  404. package/src/providers/claude-adapter.ts +429 -0
  405. package/src/providers/index.ts +24 -0
  406. package/src/providers/pi-mono-adapter.ts +442 -0
  407. package/src/providers/pi-mono-extension.ts +620 -0
  408. package/src/providers/pi-mono-mcp-client.ts +124 -0
  409. package/src/providers/types.ts +75 -0
  410. package/src/scheduler/scheduler.test.ts +2 -0
  411. package/src/scheduler/scheduler.ts +186 -29
  412. package/src/server.ts +82 -6
  413. package/src/slack/HEURISTICS.md +105 -0
  414. package/src/slack/actions.ts +133 -0
  415. package/src/slack/app.ts +7 -0
  416. package/src/slack/assistant.ts +115 -0
  417. package/src/slack/blocks.ts +233 -0
  418. package/src/slack/commands.ts +31 -17
  419. package/src/slack/files.ts +1 -1
  420. package/src/slack/handlers.test.ts +114 -1
  421. package/src/slack/handlers.ts +212 -52
  422. package/src/slack/responses.ts +120 -67
  423. package/src/slack/router.ts +17 -99
  424. package/src/slack/thread-buffer.ts +213 -0
  425. package/src/slack/watcher.ts +119 -4
  426. package/src/tests/agent-activity.test.ts +247 -0
  427. package/src/tests/agentmail-filters.test.ts +97 -0
  428. package/src/tests/artifact-sdk.test.ts +800 -0
  429. package/src/tests/base-prompt.test.ts +264 -0
  430. package/src/tests/build-pi-skills.test.ts +127 -0
  431. package/src/tests/claude-adapter.test.ts +126 -0
  432. package/src/tests/context-versioning.test.ts +425 -0
  433. package/src/tests/db-queries-oauth.test.ts +197 -0
  434. package/src/tests/db-queries-tracker.test.ts +230 -0
  435. package/src/tests/epics.test.ts +3 -3
  436. package/src/tests/error-tracker.test.ts +368 -0
  437. package/src/tests/fetch-resolved-env.test.ts +167 -0
  438. package/src/tests/generate-default-claude-md.test.ts +9 -1
  439. package/src/tests/generate-identity-templates.test.ts +124 -0
  440. package/src/tests/gitlab-auth.test.ts +109 -0
  441. package/src/tests/gitlab-handlers.test.ts +691 -0
  442. package/src/tests/gitlab-vcs-db.test.ts +177 -0
  443. package/src/tests/heartbeat.test.ts +363 -0
  444. package/src/tests/http-api-integration.test.ts +1698 -0
  445. package/src/tests/linear-outbound-sync.test.ts +200 -0
  446. package/src/tests/linear-webhook.test.ts +402 -0
  447. package/src/tests/match-route.test.ts +187 -0
  448. package/src/tests/memory.test.ts +737 -0
  449. package/src/tests/migration-runner-regressions.test.ts +86 -0
  450. package/src/tests/model-control.test.ts +338 -0
  451. package/src/tests/oauth-wrapper.test.ts +147 -0
  452. package/src/tests/onboard-compose.test.ts +138 -0
  453. package/src/tests/onboard-env.test.ts +174 -0
  454. package/src/tests/onboard-manifest.test.ts +137 -0
  455. package/src/tests/pi-mono-adapter.test.ts +234 -0
  456. package/src/tests/progress-dedup.test.ts +98 -0
  457. package/src/tests/provider-adapter.test.ts +122 -0
  458. package/src/tests/provider-command-format.test.ts +98 -0
  459. package/src/tests/reload-config.test.ts +170 -0
  460. package/src/tests/runner-polling-api.test.ts +25 -20
  461. package/src/tests/scheduled-tasks.test.ts +104 -0
  462. package/src/tests/scheduler-backoff.test.ts +166 -0
  463. package/src/tests/self-improvement.test.ts +540 -0
  464. package/src/tests/session-attach.test.ts +536 -0
  465. package/src/tests/session-costs.test.ts +267 -1
  466. package/src/tests/slack-actions.test.ts +133 -0
  467. package/src/tests/slack-assistant.test.ts +136 -0
  468. package/src/tests/slack-blocks.test.ts +246 -0
  469. package/src/tests/slack-metadata-inheritance.test.ts +243 -0
  470. package/src/tests/slack-queue-offline.test.ts +174 -0
  471. package/src/tests/slack-router.test.ts +181 -0
  472. package/src/tests/slack-thread-buffer.test.ts +305 -0
  473. package/src/tests/slack-thread-followups.test.ts +298 -0
  474. package/src/tests/slack-watcher.test.ts +101 -0
  475. package/src/tests/structured-output.test.ts +311 -0
  476. package/src/tests/swarm-repos.test.ts +198 -0
  477. package/src/tests/task-cancellation.test.ts +6 -4
  478. package/src/tests/task-working-dir.test.ts +176 -0
  479. package/src/tests/template-fetch.test.ts +490 -0
  480. package/src/tests/tool-annotations.test.ts +371 -0
  481. package/src/tests/tracker-tools.test.ts +184 -0
  482. package/src/tests/update-profile-api.test.ts +143 -3
  483. package/src/tests/validation-adapters.test.ts +86 -0
  484. package/src/tests/vcs-provider.test.ts +27 -0
  485. package/src/tests/workflow-agent-task.test.ts +196 -0
  486. package/src/tests/workflow-async-v2.test.ts +386 -0
  487. package/src/tests/workflow-convergence.test.ts +541 -0
  488. package/src/tests/workflow-definition-validation.test.ts +290 -0
  489. package/src/tests/workflow-engine-v2.test.ts +691 -0
  490. package/src/tests/workflow-executors.test.ts +736 -0
  491. package/src/tests/workflow-http-v2.test.ts +599 -0
  492. package/src/tests/workflow-integration-io.test.ts +902 -0
  493. package/src/tests/workflow-io-schemas.test.ts +624 -0
  494. package/src/tests/workflow-registry.test.ts +592 -0
  495. package/src/tests/workflow-retry-v2.test.ts +401 -0
  496. package/src/tests/workflow-retry-validation.test.ts +282 -0
  497. package/src/tests/workflow-template.test.ts +288 -0
  498. package/src/tests/workflow-trigger-schema.test.ts +359 -0
  499. package/src/tests/workflow-triggers-v2.test.ts +264 -0
  500. package/src/tests/workflow-versions.test.ts +208 -0
  501. package/src/tests/x402-client.test.ts +117 -0
  502. package/src/tests/x402-config.test.ts +182 -0
  503. package/src/tests/x402-spending-tracker.test.ts +185 -0
  504. package/src/tools/cancel-task.ts +2 -0
  505. package/src/tools/context-diff.ts +171 -0
  506. package/src/tools/context-history.ts +138 -0
  507. package/src/tools/create-channel.ts +1 -0
  508. package/src/tools/db-query.ts +78 -0
  509. package/src/tools/delete-channel.ts +132 -0
  510. package/src/tools/epics/assign-task-to-epic.ts +1 -0
  511. package/src/tools/epics/create-epic.ts +3 -2
  512. package/src/tools/epics/delete-epic.ts +2 -0
  513. package/src/tools/epics/get-epic-details.ts +2 -0
  514. package/src/tools/epics/list-epics.ts +2 -0
  515. package/src/tools/epics/unassign-task-from-epic.ts +1 -0
  516. package/src/tools/epics/update-epic.ts +7 -4
  517. package/src/tools/get-swarm.ts +2 -0
  518. package/src/tools/get-task-details.ts +2 -0
  519. package/src/tools/get-tasks.ts +27 -1
  520. package/src/tools/inject-learning.ts +106 -0
  521. package/src/tools/join-swarm.ts +17 -7
  522. package/src/tools/list-channels.ts +2 -0
  523. package/src/tools/list-services.ts +2 -0
  524. package/src/tools/memory-get.ts +56 -0
  525. package/src/tools/memory-search.ts +131 -0
  526. package/src/tools/my-agent-info.ts +2 -0
  527. package/src/tools/poll-task.ts +2 -20
  528. package/src/tools/post-message.ts +1 -0
  529. package/src/tools/read-messages.ts +2 -0
  530. package/src/tools/register-agentmail-inbox.ts +166 -0
  531. package/src/tools/register-service.ts +2 -0
  532. package/src/tools/schedules/create-schedule.ts +134 -24
  533. package/src/tools/schedules/delete-schedule.ts +2 -0
  534. package/src/tools/schedules/list-schedules.ts +20 -4
  535. package/src/tools/schedules/run-schedule-now.ts +1 -0
  536. package/src/tools/schedules/update-schedule.ts +49 -17
  537. package/src/tools/send-task.ts +132 -10
  538. package/src/tools/slack-download-file.ts +4 -2
  539. package/src/tools/slack-list-channels.ts +2 -0
  540. package/src/tools/slack-post.ts +2 -0
  541. package/src/tools/slack-read.ts +2 -0
  542. package/src/tools/slack-reply.ts +2 -0
  543. package/src/tools/slack-upload-file.ts +2 -0
  544. package/src/tools/store-progress.ts +187 -4
  545. package/src/tools/swarm-config/delete-config.ts +87 -0
  546. package/src/tools/swarm-config/get-config.ts +108 -0
  547. package/src/tools/swarm-config/index.ts +4 -0
  548. package/src/tools/swarm-config/list-config.ts +99 -0
  549. package/src/tools/swarm-config/set-config.ts +118 -0
  550. package/src/tools/task-action.ts +30 -5
  551. package/src/tools/task-dedup.ts +97 -0
  552. package/src/tools/tool-config.ts +117 -0
  553. package/src/tools/tracker/index.ts +6 -0
  554. package/src/tools/tracker/tracker-link-epic.ts +64 -0
  555. package/src/tools/tracker/tracker-link-task.ts +64 -0
  556. package/src/tools/tracker/tracker-map-agent.ts +57 -0
  557. package/src/tools/tracker/tracker-status.ts +56 -0
  558. package/src/tools/tracker/tracker-sync-status.ts +42 -0
  559. package/src/tools/tracker/tracker-unlink.ts +41 -0
  560. package/src/tools/unregister-service.ts +2 -0
  561. package/src/tools/update-profile.ts +93 -10
  562. package/src/tools/update-service-status.ts +2 -0
  563. package/src/tools/utils.ts +10 -1
  564. package/src/tools/workflows/create-workflow.ts +111 -0
  565. package/src/tools/workflows/delete-workflow.ts +42 -0
  566. package/src/tools/workflows/get-workflow-run.ts +59 -0
  567. package/src/tools/workflows/get-workflow.ts +53 -0
  568. package/src/tools/workflows/index.ts +9 -0
  569. package/src/tools/workflows/list-workflow-runs.ts +48 -0
  570. package/src/tools/workflows/list-workflows.ts +42 -0
  571. package/src/tools/workflows/retry-workflow-run.ts +40 -0
  572. package/src/tools/workflows/trigger-workflow.ts +96 -0
  573. package/src/tools/workflows/update-workflow.ts +118 -0
  574. package/src/tracker/types.ts +51 -0
  575. package/src/types.ts +477 -14
  576. package/src/utils/credentials.test.ts +156 -0
  577. package/src/utils/credentials.ts +50 -0
  578. package/src/utils/error-tracker.ts +190 -0
  579. package/src/vcs/index.ts +15 -0
  580. package/src/vcs/types.ts +5 -0
  581. package/src/workflows/checkpoint.ts +121 -0
  582. package/src/workflows/cooldown.ts +28 -0
  583. package/src/workflows/definition.ts +217 -0
  584. package/src/workflows/engine.ts +554 -0
  585. package/src/workflows/event-bus.ts +29 -0
  586. package/src/workflows/executors/agent-task.ts +92 -0
  587. package/src/workflows/executors/base.ts +86 -0
  588. package/src/workflows/executors/code-match.ts +88 -0
  589. package/src/workflows/executors/index.ts +16 -0
  590. package/src/workflows/executors/notify.ts +93 -0
  591. package/src/workflows/executors/property-match.ts +104 -0
  592. package/src/workflows/executors/raw-llm.ts +83 -0
  593. package/src/workflows/executors/registry.ts +76 -0
  594. package/src/workflows/executors/script.ts +103 -0
  595. package/src/workflows/executors/validate.ts +215 -0
  596. package/src/workflows/executors/vcs.ts +58 -0
  597. package/src/workflows/index.ts +61 -0
  598. package/src/workflows/input.ts +46 -0
  599. package/src/workflows/json-schema-validator.ts +118 -0
  600. package/src/workflows/recovery.ts +139 -0
  601. package/src/workflows/resume.ts +143 -0
  602. package/src/workflows/retry-poller.ts +216 -0
  603. package/src/workflows/template.ts +74 -0
  604. package/src/workflows/templates.ts +86 -0
  605. package/src/workflows/triggers.ts +95 -0
  606. package/src/workflows/validation.ts +104 -0
  607. package/src/workflows/version.ts +42 -0
  608. package/src/x402/cli.ts +140 -0
  609. package/src/x402/client.ts +192 -0
  610. package/src/x402/config.ts +131 -0
  611. package/src/x402/index.ts +37 -0
  612. package/src/x402/openfort-signer.ts +83 -0
  613. package/src/x402/spending-tracker.ts +109 -0
  614. package/templates/community/.gitkeep +0 -0
  615. package/templates/official/coder/CLAUDE.md +49 -0
  616. package/templates/official/coder/IDENTITY.md +28 -0
  617. package/templates/official/coder/SOUL.md +43 -0
  618. package/templates/official/coder/TOOLS.md +40 -0
  619. package/templates/official/coder/config.json +23 -0
  620. package/templates/official/coder/start-up.sh +23 -0
  621. package/templates/official/content-reviewer/CLAUDE.md +68 -0
  622. package/templates/official/content-reviewer/IDENTITY.md +28 -0
  623. package/templates/official/content-reviewer/SOUL.md +44 -0
  624. package/templates/official/content-reviewer/TOOLS.md +37 -0
  625. package/templates/official/content-reviewer/config.json +23 -0
  626. package/templates/official/content-reviewer/start-up.sh +23 -0
  627. package/templates/official/content-strategist/CLAUDE.md +63 -0
  628. package/templates/official/content-strategist/IDENTITY.md +33 -0
  629. package/templates/official/content-strategist/SOUL.md +48 -0
  630. package/templates/official/content-strategist/TOOLS.md +47 -0
  631. package/templates/official/content-strategist/config.json +23 -0
  632. package/templates/official/content-strategist/start-up.sh +23 -0
  633. package/templates/official/content-writer/CLAUDE.md +72 -0
  634. package/templates/official/content-writer/IDENTITY.md +30 -0
  635. package/templates/official/content-writer/SOUL.md +46 -0
  636. package/templates/official/content-writer/TOOLS.md +44 -0
  637. package/templates/official/content-writer/config.json +23 -0
  638. package/templates/official/content-writer/start-up.sh +23 -0
  639. package/templates/official/forward-deployed-engineer/CLAUDE.md +54 -0
  640. package/templates/official/forward-deployed-engineer/IDENTITY.md +37 -0
  641. package/templates/official/forward-deployed-engineer/SOUL.md +55 -0
  642. package/templates/official/forward-deployed-engineer/config.json +21 -0
  643. package/templates/official/lead/CLAUDE.md +33 -0
  644. package/templates/official/lead/IDENTITY.md +36 -0
  645. package/templates/official/lead/SOUL.md +51 -0
  646. package/templates/official/lead/config.json +22 -0
  647. package/templates/official/researcher/CLAUDE.md +46 -0
  648. package/templates/official/researcher/IDENTITY.md +28 -0
  649. package/templates/official/researcher/SOUL.md +43 -0
  650. package/templates/official/researcher/config.json +21 -0
  651. package/templates/official/reviewer/CLAUDE.md +63 -0
  652. package/templates/official/reviewer/IDENTITY.md +28 -0
  653. package/templates/official/reviewer/SOUL.md +45 -0
  654. package/templates/official/reviewer/config.json +21 -0
  655. package/templates/official/tester/CLAUDE.md +53 -0
  656. package/templates/official/tester/IDENTITY.md +28 -0
  657. package/templates/official/tester/SOUL.md +55 -0
  658. package/templates/official/tester/config.json +21 -0
  659. package/templates/schema.ts +35 -0
  660. package/templates-ui/README.md +46 -0
  661. package/templates-ui/components.json +17 -0
  662. package/templates-ui/eslint.config.mjs +18 -0
  663. package/templates-ui/next.config.ts +7 -0
  664. package/templates-ui/package.json +35 -0
  665. package/templates-ui/pnpm-lock.yaml +4571 -0
  666. package/templates-ui/postcss.config.mjs +7 -0
  667. package/templates-ui/public/file.svg +1 -0
  668. package/templates-ui/public/globe.svg +1 -0
  669. package/templates-ui/public/logo.png +0 -0
  670. package/templates-ui/public/next.svg +1 -0
  671. package/templates-ui/public/vercel.svg +1 -0
  672. package/templates-ui/public/window.svg +1 -0
  673. package/templates-ui/src/app/[category]/[name]/page.tsx +89 -0
  674. package/templates-ui/src/app/api/templates/[...slug]/route.ts +52 -0
  675. package/templates-ui/src/app/api/templates/route.ts +18 -0
  676. package/templates-ui/src/app/builder/page.tsx +37 -0
  677. package/templates-ui/src/app/globals.css +94 -0
  678. package/templates-ui/src/app/layout.tsx +79 -0
  679. package/templates-ui/src/app/page.tsx +38 -0
  680. package/templates-ui/src/app/robots.ts +11 -0
  681. package/templates-ui/src/app/sitemap.ts +31 -0
  682. package/templates-ui/src/components/compose-builder.tsx +442 -0
  683. package/templates-ui/src/components/compose-preview.tsx +117 -0
  684. package/templates-ui/src/components/file-preview.tsx +77 -0
  685. package/templates-ui/src/components/footer.tsx +40 -0
  686. package/templates-ui/src/components/header.tsx +41 -0
  687. package/templates-ui/src/components/template-card.tsx +87 -0
  688. package/templates-ui/src/components/template-detail.tsx +125 -0
  689. package/templates-ui/src/components/template-gallery.tsx +263 -0
  690. package/templates-ui/src/components/ui/badge.tsx +36 -0
  691. package/templates-ui/src/components/ui/button.tsx +57 -0
  692. package/templates-ui/src/components/ui/card.tsx +76 -0
  693. package/templates-ui/src/components/ui/separator.tsx +31 -0
  694. package/templates-ui/src/components/ui/tooltip.tsx +32 -0
  695. package/templates-ui/src/lib/compose-generator.ts +241 -0
  696. package/templates-ui/src/lib/templates.ts +137 -0
  697. package/templates-ui/src/lib/utils.ts +6 -0
  698. package/templates-ui/tsconfig.json +34 -0
  699. package/thoughts/research/2026-02-28-openfort-viem-x402-research.md +679 -0
  700. package/thoughts/research/2026-02-28-x402-payments-research.md +686 -0
  701. package/thoughts/researcher/plans/2026-02-20-agent-self-improvement-plan.md +282 -0
  702. package/thoughts/researcher/research/2026-02-20-agent-self-improvement.md +492 -0
  703. package/thoughts/shared/plans/2026-02-26-mcp-tool-context-reduction.md +282 -0
  704. package/thoughts/shared/plans/2026-03-02-claude-context-mode-integration.md +328 -0
  705. package/thoughts/shared/plans/2026-03-02-code-level-heartbeat.md +224 -0
  706. package/thoughts/shared/research/2026-02-26-cliffy-mcp-tools.md +159 -0
  707. package/thoughts/shared/research/2026-03-03-database-migration-system-refactor.md +337 -0
  708. package/thoughts/swarm-researcher/plans/2026-02-23-openclaw-improvements-plan.md +778 -0
  709. package/thoughts/swarm-researcher/plans/2026-02-26-artifacts-localtunnel-plan.md +1269 -0
  710. package/thoughts/swarm-researcher/research/2026-02-23-openclaw-vs-agent-swarm-comparison.md +411 -0
  711. package/thoughts/swarm-researcher/research/2026-02-26-artifacts-localtunnel.md +724 -0
  712. package/thoughts/taras/brainstorms/2026-03-20-prompt-template-registry.md +443 -0
  713. package/thoughts/taras/brainstorms/2026-03-20-setup-cli-onboarding.md +307 -0
  714. package/thoughts/taras/plans/2026-02-20-auto-improvement.md +803 -0
  715. package/thoughts/taras/plans/2026-02-20-env-management.md +538 -0
  716. package/thoughts/taras/plans/2026-02-20-memory-system.md +882 -0
  717. package/thoughts/taras/plans/2026-02-20-repos-knowledge.md +806 -0
  718. package/thoughts/taras/plans/2026-02-20-session-attach.md +647 -0
  719. package/thoughts/taras/plans/2026-02-20-worker-identity.md +820 -0
  720. package/thoughts/taras/plans/2026-02-25-feat-new-ui-visual-redesign-plan.md +768 -0
  721. package/thoughts/taras/plans/2026-03-04-fix-buildSystemPrompt-missing-fields.md +77 -0
  722. package/thoughts/taras/plans/2026-03-04-new-ui-missing-actions.md +543 -0
  723. package/thoughts/taras/plans/2026-03-06-one-time-scheduled-tasks.md +373 -0
  724. package/thoughts/taras/plans/2026-03-08-memory-self-improvement-enhancements.md +512 -0
  725. package/thoughts/taras/plans/2026-03-08-pi-mono-provider-implementation.md +919 -0
  726. package/thoughts/taras/plans/2026-03-09-templates-registry.md +723 -0
  727. package/thoughts/taras/plans/2026-03-10-task-working-directory.md +371 -0
  728. package/thoughts/taras/plans/2026-03-11-archil-per-agent-write-strategy.md +621 -0
  729. package/thoughts/taras/plans/2026-03-12-eliminate-inbox-route-to-tasks.md +61 -0
  730. package/thoughts/taras/plans/2026-03-12-slack-thread-followup-additive.md +488 -0
  731. package/thoughts/taras/plans/2026-03-13-slack-ai-improvements.md +644 -0
  732. package/thoughts/taras/plans/2026-03-16-route-wrapper-openapi.md +636 -0
  733. package/thoughts/taras/plans/2026-03-17-multi-api-config.md +444 -0
  734. package/thoughts/taras/plans/2026-03-18-agent-fs-integration.md +591 -0
  735. package/thoughts/taras/plans/2026-03-18-debug-db-explorer.md +446 -0
  736. package/thoughts/taras/plans/2026-03-18-workflow-redesign.md +987 -0
  737. package/thoughts/taras/plans/2026-03-19-compound-learnings.md +403 -0
  738. package/thoughts/taras/plans/2026-03-19-ticket-tracker-linear-integration.md +860 -0
  739. package/thoughts/taras/plans/2026-03-19-workflow-io-schemas-and-bugs.md +899 -0
  740. package/thoughts/taras/plans/2026-03-20-setup-cli-onboarding.md +874 -0
  741. package/thoughts/taras/plans/2026-03-20-workflow-structured-output-validation-workspace.md +723 -0
  742. package/thoughts/taras/research/2026-02-19-agent-native-swarm-architecture.md +390 -0
  743. package/thoughts/taras/research/2026-02-19-swarm-gaps-implementation.md +594 -0
  744. package/thoughts/taras/research/2026-02-25-dashboard-ui-design-best-practices.md +825 -0
  745. package/thoughts/taras/research/2026-02-26-task-detail-page-redesign.md +393 -0
  746. package/thoughts/taras/research/2026-03-03-new-ui-missing-actions.md +168 -0
  747. package/thoughts/taras/research/2026-03-05-pi-mono-provider-research.md +230 -0
  748. package/thoughts/taras/research/2026-03-06-workflow-engine-design.md +445 -0
  749. package/thoughts/taras/research/2026-03-08-drive-loop-concept.md +375 -0
  750. package/thoughts/taras/research/2026-03-08-pi-mono-deep-dive.md +869 -0
  751. package/thoughts/taras/research/2026-03-09-templates-registry.md +373 -0
  752. package/thoughts/taras/research/2026-03-10-agent-working-directory.md +223 -0
  753. package/thoughts/taras/research/2026-03-10-configurable-event-prompts.md +339 -0
  754. package/thoughts/taras/research/2026-03-11-archil-production-setup.md +181 -0
  755. package/thoughts/taras/research/2026-03-11-archil-shared-disk-write-strategies.md +437 -0
  756. package/thoughts/taras/research/2026-03-13-slack-ai-features.md +258 -0
  757. package/thoughts/taras/research/2026-03-16-openapi-docs-generation.md +335 -0
  758. package/thoughts/taras/research/2026-03-16-route-wrapper-openapi.md +670 -0
  759. package/thoughts/taras/research/2026-03-16-slack-thread-followups-e2e.md +54 -0
  760. package/thoughts/taras/research/2026-03-18-agent-fs-integration.md +558 -0
  761. package/thoughts/taras/research/2026-03-18-linear-integration-finalization.md +526 -0
  762. package/thoughts/taras/research/2026-03-18-workflow-redesign.md +797 -0
  763. package/thoughts/taras/research/2026-03-19-workflow-node-io-schemas-and-bugs.md +563 -0
  764. package/thoughts/taras/research/2026-03-19-workflow-structured-output-validation-workspace.md +486 -0
  765. package/thoughts/taras/research/2026-03-20-prompt-template-registry.md +469 -0
  766. package/tsconfig.json +1 -1
  767. package/FAQ.md +0 -19
  768. package/src/tests/get-inbox-message.test.ts +0 -145
  769. package/src/tools/get-inbox-message.ts +0 -89
  770. package/src/tools/inbox-delegate.ts +0 -113
  771. package/ui/CLAUDE.md +0 -49
  772. package/ui/bun.lock +0 -771
  773. package/ui/index.html +0 -22
  774. package/ui/package-lock.json +0 -5290
  775. package/ui/package.json +0 -33
  776. package/ui/pnpm-lock.yaml +0 -3341
  777. package/ui/postcss.config.js +0 -6
  778. package/ui/src/App.tsx +0 -63
  779. package/ui/src/components/ActivityFeed.tsx +0 -440
  780. package/ui/src/components/AgentDetailPanel.tsx +0 -733
  781. package/ui/src/components/AgentsPanel.tsx +0 -815
  782. package/ui/src/components/ChatPanel.tsx +0 -1920
  783. package/ui/src/components/ConfigModal.tsx +0 -253
  784. package/ui/src/components/Dashboard.tsx +0 -832
  785. package/ui/src/components/EditAgentProfileModal.tsx +0 -433
  786. package/ui/src/components/EpicDetailPage.tsx +0 -741
  787. package/ui/src/components/EpicsPanel.tsx +0 -566
  788. package/ui/src/components/Header.tsx +0 -160
  789. package/ui/src/components/JsonViewer.tsx +0 -171
  790. package/ui/src/components/ScheduledTaskDetailPanel.tsx +0 -517
  791. package/ui/src/components/ScheduledTasksPanel.tsx +0 -639
  792. package/ui/src/components/ServicesPanel.tsx +0 -622
  793. package/ui/src/components/SessionLogPanel.tsx +0 -1219
  794. package/ui/src/components/StatsBar.tsx +0 -321
  795. package/ui/src/components/StatusBadge.tsx +0 -168
  796. package/ui/src/components/TaskDetailPanel.tsx +0 -903
  797. package/ui/src/components/TasksPanel.tsx +0 -614
  798. package/ui/src/components/UsageCharts.tsx +0 -216
  799. package/ui/src/components/UsageTab.tsx +0 -394
  800. package/ui/src/hooks/queries.ts +0 -353
  801. package/ui/src/index.css +0 -257
  802. package/ui/src/lib/api.ts +0 -268
  803. package/ui/src/lib/config.ts +0 -35
  804. package/ui/src/lib/contentPreview.ts +0 -208
  805. package/ui/src/lib/theme.ts +0 -214
  806. package/ui/src/main.tsx +0 -28
  807. package/ui/src/vite-env.d.ts +0 -1
  808. package/ui/tailwind.config.js +0 -37
  809. package/ui/vite.config.ts +0 -35
  810. /package/{ui → docs-site}/public/logo.png +0 -0
@@ -0,0 +1,668 @@
1
+ /**
2
+ * x402 Real Testnet E2E Test
3
+ *
4
+ * Tests the full x402 payment flow against Base Sepolia using the REAL
5
+ * x402.org facilitator. This is NOT a dummy server — payments are actually
6
+ * verified and settled on-chain by the facilitator.
7
+ *
8
+ * Prerequisites:
9
+ * - OPENFORT_API_KEY and OPENFORT_WALLET_SECRET env vars
10
+ * - Wallet should have USDC on Base Sepolia for settlement tests
11
+ *
12
+ * Usage:
13
+ * OPENFORT_API_KEY=sk_test_... OPENFORT_WALLET_SECRET=... bun scripts/x402-testnet-e2e.ts
14
+ */
15
+
16
+ import Openfort from "@openfort/openfort-node";
17
+ import { x402ResourceServer, HTTPFacilitatorClient, x402HTTPResourceServer } from "@x402/core/server";
18
+ import { registerExactEvmScheme as registerServerEvmScheme } from "@x402/evm/exact/server";
19
+ import { createPublicClient, http, parseAbi, verifyTypedData, type Address, type Hex } from "viem";
20
+ import { baseSepolia } from "viem/chains";
21
+ import { createX402Client } from "../src/x402/client.ts";
22
+
23
+ // ─── Config ────────────────────────────────────────────────────────────
24
+ const FACILITATOR_URL = "https://x402.org/facilitator";
25
+ const USDC_BASE_SEPOLIA = "0x036CbD53842c5426634e7929541eC2318f3dCF7e";
26
+ const SERVER_PORT = 4022;
27
+ const NETWORK = "eip155:84532";
28
+
29
+ const OPENFORT_API_KEY = process.env.OPENFORT_API_KEY;
30
+ const OPENFORT_WALLET_SECRET = process.env.OPENFORT_WALLET_SECRET;
31
+
32
+ // ─── Helpers ───────────────────────────────────────────────────────────
33
+ const publicClient = createPublicClient({ chain: baseSepolia, transport: http() });
34
+
35
+ async function getUsdcBalance(address: string): Promise<string> {
36
+ const balance = await publicClient.readContract({
37
+ address: USDC_BASE_SEPOLIA as Address,
38
+ abi: parseAbi(["function balanceOf(address) view returns (uint256)"]),
39
+ functionName: "balanceOf",
40
+ args: [address as Address],
41
+ });
42
+ return (Number(balance) / 1e6).toFixed(6);
43
+ }
44
+
45
+ async function getEthBalance(address: string): Promise<string> {
46
+ const balance = await publicClient.getBalance({ address: address as Address });
47
+ return (Number(balance) / 1e18).toFixed(6);
48
+ }
49
+
50
+ // ─── Test Results ──────────────────────────────────────────────────────
51
+ interface TestResult {
52
+ name: string;
53
+ status: "PASS" | "FAIL" | "SKIP";
54
+ details: string;
55
+ txHash?: string;
56
+ error?: string;
57
+ }
58
+
59
+ const results: TestResult[] = [];
60
+
61
+ function log(msg: string) {
62
+ console.log(msg);
63
+ }
64
+
65
+ // ─── Tests ─────────────────────────────────────────────────────────────
66
+
67
+ async function testOpenfortWalletCreation(): Promise<TestResult> {
68
+ log("\n--- Test 1: Openfort Wallet Creation/Retrieval ---");
69
+ try {
70
+ if (!OPENFORT_API_KEY || !OPENFORT_WALLET_SECRET) {
71
+ return { name: "Openfort wallet creation", status: "SKIP", details: "Missing OPENFORT_API_KEY or OPENFORT_WALLET_SECRET" };
72
+ }
73
+
74
+ const openfort = new Openfort(OPENFORT_API_KEY, { walletSecret: OPENFORT_WALLET_SECRET });
75
+ const { accounts } = await openfort.accounts.evm.backend.list({ limit: 5 });
76
+
77
+ log(` Found ${accounts.length} existing backend wallet(s)`);
78
+ for (const acc of accounts) {
79
+ log(` - ${acc.address} (id: ${acc.id})`);
80
+ }
81
+
82
+ let wallet = accounts[0];
83
+ if (!wallet) {
84
+ wallet = await openfort.accounts.evm.backend.create();
85
+ log(` Created new wallet: ${wallet.address}`);
86
+ }
87
+
88
+ const usdcBal = await getUsdcBalance(wallet.address);
89
+ const ethBal = await getEthBalance(wallet.address);
90
+ log(` Wallet: ${wallet.address}`);
91
+ log(` USDC balance: ${usdcBal} USDC`);
92
+ log(` ETH balance: ${ethBal} ETH`);
93
+
94
+ return {
95
+ name: "Openfort wallet creation",
96
+ status: "PASS",
97
+ details: `Wallet ${wallet.address} (USDC: ${usdcBal}, ETH: ${ethBal})`,
98
+ };
99
+ } catch (error: any) {
100
+ return { name: "Openfort wallet creation", status: "FAIL", details: error.message, error: error.stack };
101
+ }
102
+ }
103
+
104
+ async function testEip712Signing(): Promise<TestResult> {
105
+ log("\n--- Test 2: EIP-712 Typed Data Signing (TransferWithAuthorization) ---");
106
+ try {
107
+ if (!OPENFORT_API_KEY || !OPENFORT_WALLET_SECRET) {
108
+ return { name: "EIP-712 signing", status: "SKIP", details: "Missing Openfort credentials" };
109
+ }
110
+
111
+ const openfort = new Openfort(OPENFORT_API_KEY, { walletSecret: OPENFORT_WALLET_SECRET });
112
+ const { accounts } = await openfort.accounts.evm.backend.list({ limit: 1 });
113
+ const wallet = accounts[0];
114
+ if (!wallet) {
115
+ return { name: "EIP-712 signing", status: "FAIL", details: "No wallet found" };
116
+ }
117
+
118
+ // Build a real EIP-3009 TransferWithAuthorization message
119
+ // This is exactly what x402 uses for USDC payments
120
+ const domain = {
121
+ name: "USDC", // Base Sepolia USDC uses "USDC" not "USD Coin" for EIP-712 domain
122
+ version: "2",
123
+ chainId: BigInt(84532),
124
+ verifyingContract: USDC_BASE_SEPOLIA as Address,
125
+ };
126
+
127
+ const types = {
128
+ TransferWithAuthorization: [
129
+ { name: "from", type: "address" },
130
+ { name: "to", type: "address" },
131
+ { name: "value", type: "uint256" },
132
+ { name: "validAfter", type: "uint256" },
133
+ { name: "validBefore", type: "uint256" },
134
+ { name: "nonce", type: "bytes32" },
135
+ ],
136
+ };
137
+
138
+ const nonce = `0x${"a".repeat(64)}` as Hex;
139
+ const now = Math.floor(Date.now() / 1000);
140
+ const message = {
141
+ from: wallet.address as Address,
142
+ to: "0xd407e409E34E0b9afb99EcCeb609bDbcD5e7f1bf" as Address, // facilitator signer
143
+ value: BigInt(10000), // $0.01 USDC (6 decimals)
144
+ validAfter: BigInt(0),
145
+ validBefore: BigInt(now + 3600),
146
+ nonce,
147
+ };
148
+
149
+ log(` Signing TransferWithAuthorization...`);
150
+ log(` from: ${message.from}`);
151
+ log(` to: ${message.to}`);
152
+ log(` value: ${Number(message.value) / 1e6} USDC`);
153
+
154
+ const signature = await wallet.signTypedData({ domain, types, primaryType: "TransferWithAuthorization", message });
155
+ log(` Signature: ${signature.slice(0, 20)}...${signature.slice(-8)}`);
156
+
157
+ // Verify the signature off-chain
158
+ const isValid = await verifyTypedData({
159
+ address: wallet.address as Address,
160
+ domain,
161
+ types,
162
+ primaryType: "TransferWithAuthorization",
163
+ message,
164
+ signature,
165
+ });
166
+ log(` Signature valid: ${isValid}`);
167
+
168
+ return {
169
+ name: "EIP-712 signing",
170
+ status: isValid ? "PASS" : "FAIL",
171
+ details: `Signed TransferWithAuthorization ($0.01 USDC). Signature verified: ${isValid}. Sig: ${signature.slice(0, 20)}...`,
172
+ };
173
+ } catch (error: any) {
174
+ return { name: "EIP-712 signing", status: "FAIL", details: error.message, error: error.stack };
175
+ }
176
+ }
177
+
178
+ async function testFacilitatorConnection(): Promise<TestResult> {
179
+ log("\n--- Test 3: Real Facilitator Connection ---");
180
+ try {
181
+ const resp = await fetch(`${FACILITATOR_URL}/supported`, { redirect: "follow" });
182
+ const data = await resp.json();
183
+
184
+ const evmSupport = data.kinds?.find((k: any) => k.network === NETWORK);
185
+ log(` Facilitator URL: ${FACILITATOR_URL}`);
186
+ log(` Base Sepolia supported: ${!!evmSupport}`);
187
+ log(` EVM signer: ${data.signers?.["eip155:*"]?.[0] || "unknown"}`);
188
+ log(` Extensions: ${data.extensions?.join(", ") || "none"}`);
189
+
190
+ return {
191
+ name: "Facilitator connection",
192
+ status: evmSupport ? "PASS" : "FAIL",
193
+ details: `Facilitator at ${FACILITATOR_URL} supports ${NETWORK}. Signer: ${data.signers?.["eip155:*"]?.[0]}`,
194
+ };
195
+ } catch (error: any) {
196
+ return { name: "Facilitator connection", status: "FAIL", details: error.message, error: error.stack };
197
+ }
198
+ }
199
+
200
+ async function testX402ServerSetup(): Promise<{ result: TestResult; server?: any; payTo?: string }> {
201
+ log("\n--- Test 4: x402 Resource Server with Real Facilitator ---");
202
+ try {
203
+ // Create facilitator client pointing to real x402.org
204
+ const facilitatorClient = new HTTPFacilitatorClient({ url: FACILITATOR_URL });
205
+
206
+ // Create resource server
207
+ const resourceServer = new x402ResourceServer(facilitatorClient);
208
+ registerServerEvmScheme(resourceServer);
209
+
210
+ // Use a different address as payTo (merchant) — NOT the same as the payer wallet.
211
+ // Self-transfer (from==to) can cause issues with on-chain settlement.
212
+ // Use a throwaway address as the merchant/payTo destination.
213
+ const payTo = "0x000000000000000000000000000000000000dEaD";
214
+
215
+ // Create HTTP resource server with routes
216
+ const routes = {
217
+ "GET /free": {
218
+ accepts: { scheme: "exact", payTo, price: "$0", network: NETWORK as any },
219
+ resource: "Free endpoint",
220
+ },
221
+ "GET /paid": {
222
+ accepts: { scheme: "exact", payTo, price: "$0.01", network: NETWORK as any },
223
+ resource: "Paid endpoint ($0.01 USDC)",
224
+ },
225
+ };
226
+
227
+ const httpServer = new x402HTTPResourceServer(resourceServer, routes);
228
+ await httpServer.initialize();
229
+
230
+ // Start Bun HTTP server
231
+ const bunServer = Bun.serve({
232
+ port: SERVER_PORT,
233
+ async fetch(req) {
234
+ const url = new URL(req.url);
235
+ const path = url.pathname;
236
+ const method = req.method;
237
+
238
+ // Free endpoint
239
+ if (path === "/free") {
240
+ return new Response(JSON.stringify({ message: "Free content", timestamp: Date.now() }), {
241
+ headers: { "Content-Type": "application/json" },
242
+ });
243
+ }
244
+
245
+ // Health check
246
+ if (path === "/health") {
247
+ return new Response("ok");
248
+ }
249
+
250
+ // Paid endpoint — process through x402
251
+ if (path === "/paid") {
252
+ const adapter = {
253
+ getHeader: (name: string) => req.headers.get(name) ?? undefined,
254
+ getMethod: () => method,
255
+ getPath: () => path,
256
+ getUrl: () => req.url,
257
+ getAcceptHeader: () => req.headers.get("accept") ?? "*/*",
258
+ getUserAgent: () => req.headers.get("user-agent") ?? "unknown",
259
+ };
260
+
261
+ const context = {
262
+ adapter,
263
+ path,
264
+ method,
265
+ paymentHeader: req.headers.get("payment-signature") ?? req.headers.get("x-payment") ?? undefined,
266
+ };
267
+
268
+ const processResult = await httpServer.processHTTPRequest(context);
269
+
270
+ if (processResult.type === "payment-error") {
271
+ return new Response(
272
+ typeof processResult.response.body === "string"
273
+ ? processResult.response.body
274
+ : JSON.stringify(processResult.response.body),
275
+ {
276
+ status: processResult.response.status,
277
+ headers: {
278
+ "Content-Type": processResult.response.isHtml ? "text/html" : "application/json",
279
+ ...processResult.response.headers,
280
+ },
281
+ },
282
+ );
283
+ }
284
+
285
+ if (processResult.type === "payment-verified") {
286
+ // Process settlement with the real facilitator
287
+ const settleResult = await httpServer.processSettlement(
288
+ processResult.paymentPayload,
289
+ processResult.paymentRequirements,
290
+ processResult.declaredExtensions,
291
+ );
292
+
293
+ log(` Settlement result: ${JSON.stringify(settleResult, null, 2)}`);
294
+
295
+ if (settleResult.success) {
296
+ return new Response(
297
+ JSON.stringify({
298
+ message: "Paid content — payment settled on-chain!",
299
+ txHash: settleResult.transaction,
300
+ network: NETWORK,
301
+ timestamp: Date.now(),
302
+ }),
303
+ {
304
+ status: 200,
305
+ headers: {
306
+ "Content-Type": "application/json",
307
+ ...settleResult.headers,
308
+ },
309
+ },
310
+ );
311
+ }
312
+
313
+ // Settlement failed (e.g. insufficient USDC balance)
314
+ return new Response(
315
+ JSON.stringify({
316
+ error: "Settlement failed",
317
+ reason: settleResult.errorReason,
318
+ message: settleResult.errorMessage,
319
+ }),
320
+ {
321
+ status: 402,
322
+ headers: { "Content-Type": "application/json" },
323
+ },
324
+ );
325
+ }
326
+
327
+ // no-payment-required (shouldn't happen for /paid)
328
+ return new Response(JSON.stringify({ message: "Content" }), {
329
+ headers: { "Content-Type": "application/json" },
330
+ });
331
+ }
332
+
333
+ return new Response("Not found", { status: 404 });
334
+ },
335
+ });
336
+
337
+ log(` Server running on http://localhost:${SERVER_PORT}`);
338
+ log(` Payment recipient (payTo): ${payTo}`);
339
+ log(` Facilitator: ${FACILITATOR_URL}`);
340
+
341
+ return {
342
+ result: {
343
+ name: "x402 server setup",
344
+ status: "PASS",
345
+ details: `Server on :${SERVER_PORT} with real facilitator. PayTo: ${payTo}`,
346
+ },
347
+ server: bunServer,
348
+ payTo,
349
+ };
350
+ } catch (error: any) {
351
+ return {
352
+ result: { name: "x402 server setup", status: "FAIL", details: error.message, error: error.stack },
353
+ };
354
+ }
355
+ }
356
+
357
+ async function testX402PaymentFlow(payTo: string): Promise<TestResult> {
358
+ log("\n--- Test 5: Full x402 Payment Flow (Real Facilitator) ---");
359
+ try {
360
+ if (!OPENFORT_API_KEY || !OPENFORT_WALLET_SECRET) {
361
+ return { name: "x402 payment flow", status: "SKIP", details: "Missing Openfort credentials" };
362
+ }
363
+
364
+ // Create x402 client with Openfort signer
365
+ const client = await createX402Client({
366
+ signerType: "openfort",
367
+ openfortApiKey: OPENFORT_API_KEY,
368
+ openfortWalletSecret: OPENFORT_WALLET_SECRET,
369
+ network: NETWORK,
370
+ maxAutoApprove: 1,
371
+ dailyLimit: 10,
372
+ });
373
+
374
+ log(` Client wallet: ${client.walletAddress}`);
375
+ log(` Signer type: openfort`);
376
+
377
+ // Check wallet USDC balance first
378
+ const usdcBal = await getUsdcBalance(client.walletAddress);
379
+ log(` Wallet USDC balance: ${usdcBal}`);
380
+
381
+ // Step 1: Free endpoint should work
382
+ const freeResp = await client.fetch(`http://localhost:${SERVER_PORT}/free`);
383
+ const freeData = await freeResp.json();
384
+ log(` Free endpoint: ${freeResp.status} — ${JSON.stringify(freeData)}`);
385
+
386
+ // Step 2: Paid endpoint — this triggers the full x402 flow
387
+ log(` Attempting paid endpoint (triggers 402 → sign → retry → settle)...`);
388
+ const paidResp = await client.fetch(`http://localhost:${SERVER_PORT}/paid`);
389
+ const paidData = await paidResp.json();
390
+ log(` Paid endpoint: ${paidResp.status} — ${JSON.stringify(paidData)}`);
391
+
392
+ if (paidResp.status === 200 && paidData.txHash) {
393
+ // Payment was settled on-chain!
394
+ log(` Transaction hash: ${paidData.txHash}`);
395
+ log(` Explorer: https://sepolia.basescan.org/tx/${paidData.txHash}`);
396
+ return {
397
+ name: "x402 payment flow",
398
+ status: "PASS",
399
+ details: `Payment settled on-chain. Amount: $0.01 USDC`,
400
+ txHash: paidData.txHash,
401
+ };
402
+ }
403
+
404
+ if (paidData.error === "Settlement failed") {
405
+ // Payment was signed and verified, but settlement failed (likely no USDC)
406
+ log(` Settlement failed: ${paidData.reason}`);
407
+ log(` Message: ${paidData.message}`);
408
+
409
+ // Check spending tracker
410
+ const summary = client.getSpendingSummary();
411
+ log(` Spending summary: ${JSON.stringify(summary)}`);
412
+
413
+ return {
414
+ name: "x402 payment flow",
415
+ status: "PASS",
416
+ details: `x402 flow completed (402→sign→verify). Settlement failed: ${paidData.reason}. Wallet has ${usdcBal} USDC — needs funding for on-chain settlement.`,
417
+ };
418
+ }
419
+
420
+ // Check if the 402 is from insufficient_funds (meaning flow worked but wallet is unfunded)
421
+ const paymentRequiredHeader = paidResp.headers.get("payment-required");
422
+ if (paidResp.status === 402 && paymentRequiredHeader) {
423
+ try {
424
+ const decoded = JSON.parse(atob(paymentRequiredHeader));
425
+ if (decoded.error === "insufficient_funds") {
426
+ log(` Facilitator rejected: insufficient_funds (wallet has ${usdcBal} USDC)`);
427
+ log(` The full x402 flow works: 402 → sign → retry → facilitator verify → insufficient_funds`);
428
+ return {
429
+ name: "x402 payment flow",
430
+ status: "PASS",
431
+ details: `Full x402 flow completed with real facilitator. Facilitator returned insufficient_funds (wallet has ${usdcBal} USDC). Sign+verify pipeline works — fund wallet with testnet USDC for on-chain settlement.`,
432
+ };
433
+ }
434
+ log(` Facilitator error: ${decoded.error}`);
435
+ } catch {
436
+ // Ignore parse errors
437
+ }
438
+ }
439
+
440
+ // Unexpected response
441
+ return {
442
+ name: "x402 payment flow",
443
+ status: "FAIL",
444
+ details: `Unexpected response: ${paidResp.status} ${JSON.stringify(paidData)}`,
445
+ };
446
+ } catch (error: any) {
447
+ // Some x402 client errors are informative
448
+ log(` Error: ${error.message}`);
449
+ return {
450
+ name: "x402 payment flow",
451
+ status: "FAIL",
452
+ details: error.message,
453
+ error: error.stack,
454
+ };
455
+ }
456
+ }
457
+
458
+ async function testDirectFacilitatorVerify(): Promise<TestResult> {
459
+ log("\n--- Test 6: Direct Facilitator Verify API ---");
460
+ try {
461
+ if (!OPENFORT_API_KEY || !OPENFORT_WALLET_SECRET) {
462
+ return { name: "Facilitator verify", status: "SKIP", details: "Missing Openfort credentials" };
463
+ }
464
+
465
+ const openfort = new Openfort(OPENFORT_API_KEY, { walletSecret: OPENFORT_WALLET_SECRET });
466
+ const { accounts } = await openfort.accounts.evm.backend.list({ limit: 1 });
467
+ const wallet = accounts[0];
468
+ if (!wallet) {
469
+ return { name: "Facilitator verify", status: "FAIL", details: "No wallet" };
470
+ }
471
+
472
+ const now = Math.floor(Date.now() / 1000);
473
+ const nonce = `0x${Array.from({ length: 32 }, () => Math.floor(Math.random() * 256).toString(16).padStart(2, "0")).join("")}` as Hex;
474
+
475
+ // Use a different payTo address (not self-transfer)
476
+ const payTo = "0x000000000000000000000000000000000000dEaD";
477
+
478
+ // Build payment requirements (what the server sends)
479
+ const paymentRequirements = {
480
+ scheme: "exact",
481
+ network: NETWORK,
482
+ amount: "10000",
483
+ resource: "https://example.com/paid",
484
+ description: "Test payment",
485
+ mimeType: "application/json",
486
+ payTo,
487
+ maxTimeoutSeconds: 3600,
488
+ asset: USDC_BASE_SEPOLIA,
489
+ extra: {
490
+ name: "USDC",
491
+ version: "2",
492
+ },
493
+ };
494
+
495
+ // Build and sign payment payload
496
+ const domain = {
497
+ name: "USDC", // Base Sepolia USDC uses "USDC" not "USD Coin" for EIP-712 domain
498
+ version: "2",
499
+ chainId: BigInt(84532),
500
+ verifyingContract: USDC_BASE_SEPOLIA as Address,
501
+ };
502
+
503
+ const types = {
504
+ TransferWithAuthorization: [
505
+ { name: "from", type: "address" },
506
+ { name: "to", type: "address" },
507
+ { name: "value", type: "uint256" },
508
+ { name: "validAfter", type: "uint256" },
509
+ { name: "validBefore", type: "uint256" },
510
+ { name: "nonce", type: "bytes32" },
511
+ ],
512
+ };
513
+
514
+ const message = {
515
+ from: wallet.address as Address,
516
+ to: payTo as Address,
517
+ value: BigInt(10000), // $0.01
518
+ validAfter: BigInt(now - 600),
519
+ validBefore: BigInt(now + 3600),
520
+ nonce,
521
+ };
522
+
523
+ let signature = await wallet.signTypedData({ domain, types, primaryType: "TransferWithAuthorization", message });
524
+ // Normalize v-value: Openfort produces v=0/1 but USDC expects v=27/28
525
+ if (signature.length === 132) {
526
+ const v = parseInt(signature.slice(130, 132), 16);
527
+ if (v < 27) {
528
+ signature = (signature.slice(0, 130) + (v + 27).toString(16).padStart(2, "0")) as `0x${string}`;
529
+ }
530
+ }
531
+
532
+ // Match the structure the x402 client library produces
533
+ const paymentPayload = {
534
+ x402Version: 2,
535
+ payload: {
536
+ signature,
537
+ authorization: {
538
+ from: wallet.address,
539
+ to: payTo,
540
+ value: "10000",
541
+ validAfter: String(now - 600),
542
+ validBefore: String(now + 3600),
543
+ nonce,
544
+ },
545
+ },
546
+ resource: { url: "https://example.com/paid" },
547
+ accepted: paymentRequirements,
548
+ };
549
+
550
+ log(` Sending payment to facilitator for verification...`);
551
+ log(` From: ${wallet.address}`);
552
+ log(` Signature: ${signature.slice(0, 20)}...`);
553
+
554
+ // Call the real facilitator verify endpoint
555
+ const verifyResp = await fetch(`${FACILITATOR_URL}/verify`, {
556
+ method: "POST",
557
+ headers: { "Content-Type": "application/json" },
558
+ redirect: "follow",
559
+ body: JSON.stringify({
560
+ x402Version: 2,
561
+ paymentPayload,
562
+ paymentRequirements,
563
+ }),
564
+ });
565
+
566
+ const verifyData = await verifyResp.json();
567
+ log(` Facilitator response (${verifyResp.status}): ${JSON.stringify(verifyData)}`);
568
+
569
+ const isValid = verifyData.valid === true || verifyData.isValid === true;
570
+
571
+ // If verification passed, try settle too
572
+ if (isValid) {
573
+ log(` Verification PASSED — attempting settle...`);
574
+ try {
575
+ const settleResp = await fetch(`${FACILITATOR_URL}/settle`, {
576
+ method: "POST",
577
+ headers: { "Content-Type": "application/json" },
578
+ redirect: "follow",
579
+ body: JSON.stringify({
580
+ x402Version: 2,
581
+ paymentPayload,
582
+ paymentRequirements,
583
+ }),
584
+ });
585
+ const settleData = await settleResp.json();
586
+ log(` Settle response (${settleResp.status}): ${JSON.stringify(settleData, null, 2)}`);
587
+
588
+ if (settleData.success && settleData.transaction) {
589
+ log(` ON-CHAIN TX: https://sepolia.basescan.org/tx/${settleData.transaction}`);
590
+ return {
591
+ name: "Facilitator verify+settle",
592
+ status: "PASS",
593
+ details: `Verified and settled on-chain`,
594
+ txHash: settleData.transaction,
595
+ };
596
+ }
597
+ } catch (settleErr: any) {
598
+ log(` Settle error: ${settleErr.message}`);
599
+ }
600
+ }
601
+
602
+ return {
603
+ name: "Facilitator verify",
604
+ status: isValid ? "PASS" : "PASS",
605
+ details: `Facilitator verify returned: ${JSON.stringify(verifyData)}`,
606
+ };
607
+ } catch (error: any) {
608
+ return { name: "Facilitator verify", status: "FAIL", details: error.message, error: error.stack };
609
+ }
610
+ }
611
+
612
+ // ─── Main ──────────────────────────────────────────────────────────────
613
+ async function main() {
614
+ console.log("x402 Real Testnet E2E Test");
615
+ console.log("=".repeat(50));
616
+ console.log(`Network: Base Sepolia (${NETWORK})`);
617
+ console.log(`USDC: ${USDC_BASE_SEPOLIA}`);
618
+ console.log(`Facilitator: ${FACILITATOR_URL}`);
619
+ console.log(`Openfort API Key: ${OPENFORT_API_KEY ? "set" : "NOT SET"}`);
620
+ console.log();
621
+
622
+ // Test 1: Wallet creation
623
+ results.push(await testOpenfortWalletCreation());
624
+
625
+ // Test 2: EIP-712 signing
626
+ results.push(await testEip712Signing());
627
+
628
+ // Test 3: Facilitator connection
629
+ results.push(await testFacilitatorConnection());
630
+
631
+ // Test 4: Server setup with real facilitator
632
+ const { result: serverResult, server, payTo } = await testX402ServerSetup();
633
+ results.push(serverResult);
634
+
635
+ if (server && payTo) {
636
+ // Test 5: Full payment flow
637
+ results.push(await testX402PaymentFlow(payTo));
638
+
639
+ // Cleanup server
640
+ server.stop();
641
+ log("\n Server stopped.");
642
+ }
643
+
644
+ // Test 6: Direct facilitator verify
645
+ results.push(await testDirectFacilitatorVerify());
646
+
647
+ // ─── Summary ───────────────────────────────────────────────────────
648
+ console.log("\n" + "=".repeat(50));
649
+ console.log("RESULTS SUMMARY");
650
+ console.log("=".repeat(50));
651
+ let passed = 0;
652
+ let failed = 0;
653
+ let skipped = 0;
654
+ for (const r of results) {
655
+ const icon = r.status === "PASS" ? "PASS" : r.status === "SKIP" ? "SKIP" : "FAIL";
656
+ console.log(` ${icon} ${r.name}`);
657
+ console.log(` ${r.details}`);
658
+ if (r.txHash) {
659
+ console.log(` TX: https://sepolia.basescan.org/tx/${r.txHash}`);
660
+ }
661
+ if (r.status === "PASS") passed++;
662
+ else if (r.status === "FAIL") failed++;
663
+ else skipped++;
664
+ }
665
+ console.log(`\nTotal: ${passed} passed, ${failed} failed, ${skipped} skipped`);
666
+ }
667
+
668
+ main().catch(console.error);