@desplega.ai/agent-swarm 1.49.0 → 1.52.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.
- package/README.md +1 -1
- package/openapi.json +2070 -728
- package/package.json +10 -1
- package/src/agentmail/handlers.ts +65 -10
- package/src/agentmail/templates.ts +111 -0
- package/src/be/db.ts +1233 -7
- package/src/be/migrations/014_prompt_templates.sql +33 -0
- package/src/be/migrations/015_workflow_workspace.sql +3 -0
- package/src/be/migrations/016_active_session_runner_session.sql +4 -0
- package/src/be/migrations/017_channel_activity_cursors.sql +6 -0
- package/src/be/migrations/018_fix_seed_double_version.sql +30 -0
- package/src/be/migrations/019_skills.sql +65 -0
- package/src/be/migrations/020_approval_requests.sql +41 -0
- package/src/be/seed.ts +62 -0
- package/src/be/skill-parser.ts +70 -0
- package/src/be/skill-sync.ts +106 -0
- package/src/commands/runner.ts +320 -132
- package/src/commands/templates.ts +172 -0
- package/src/github/handlers.ts +292 -77
- package/src/github/mentions-aliases.test.ts +73 -0
- package/src/github/mentions.test.ts +3 -3
- package/src/github/mentions.ts +32 -6
- package/src/github/templates.ts +398 -0
- package/src/gitlab/handlers.ts +63 -22
- package/src/gitlab/templates.ts +140 -0
- package/src/heartbeat/heartbeat.ts +19 -10
- package/src/heartbeat/templates.ts +30 -0
- package/src/http/active-sessions.ts +27 -0
- package/src/http/approval-requests.ts +247 -0
- package/src/http/config.ts +3 -3
- package/src/http/index.ts +9 -2
- package/src/http/poll.ts +135 -14
- package/src/http/prompt-templates.ts +412 -0
- package/src/http/schedules.ts +35 -0
- package/src/http/skills.ts +479 -0
- package/src/http/workflows.ts +8 -0
- package/src/linear/sync.ts +28 -4
- package/src/linear/templates.ts +47 -0
- package/src/prompts/base-prompt.ts +41 -490
- package/src/prompts/registry.ts +57 -0
- package/src/prompts/resolver.ts +296 -0
- package/src/prompts/session-templates.ts +604 -0
- package/src/providers/claude-adapter.ts +15 -2
- package/src/providers/pi-mono-extension.ts +5 -1
- package/src/scheduler/scheduler.ts +125 -91
- package/src/server.ts +44 -0
- package/src/slack/assistant.ts +7 -4
- package/src/slack/channel-activity.ts +177 -0
- package/src/slack/handlers.ts +21 -6
- package/src/slack/templates.ts +55 -0
- package/src/tests/approval-requests.test.ts +735 -0
- package/src/tests/artifact-sdk.test.ts +12 -12
- package/src/tests/base-prompt.test.ts +49 -49
- package/src/tests/channel-activity.test.ts +363 -0
- package/src/tests/heartbeat.test.ts +1 -0
- package/src/tests/linear-webhook.test.ts +7 -3
- package/src/tests/pool-session-logs.test.ts +199 -0
- package/src/tests/prompt-template-github.test.ts +682 -0
- package/src/tests/prompt-template-remaining.test.ts +504 -0
- package/src/tests/prompt-template-resolver.test.ts +621 -0
- package/src/tests/prompt-template-session.test.ts +363 -0
- package/src/tests/prompt-templates-db.test.ts +616 -0
- package/src/tests/self-improvement.test.ts +8 -7
- package/src/tests/skill-parser.test.ts +178 -0
- package/src/tests/skill-sync.test.ts +171 -0
- package/src/tests/slack-metadata-inheritance.test.ts +1 -1
- package/src/tests/slack-thread-followups.test.ts +1 -1
- package/src/tests/structured-output.test.ts +0 -4
- package/src/tests/tool-annotations.test.ts +2 -1
- package/src/tests/update-profile-agentid.test.ts +248 -0
- package/src/tests/update-profile-auth.test.ts +195 -0
- package/src/tests/workflow-async-v2.test.ts +126 -4
- package/src/tests/workflow-definition-validation.test.ts +76 -0
- package/src/tests/workflow-executors.test.ts +4 -2
- package/src/tests/workflow-retry-v2.test.ts +1 -1
- package/src/tests/workflow-schedule-trigger.test.ts +104 -0
- package/src/tests/workflow-workspace.test.ts +272 -0
- package/src/tools/prompt-templates/delete.ts +86 -0
- package/src/tools/prompt-templates/get.ts +89 -0
- package/src/tools/prompt-templates/index.ts +5 -0
- package/src/tools/prompt-templates/list.ts +95 -0
- package/src/tools/prompt-templates/preview.ts +84 -0
- package/src/tools/prompt-templates/set.ts +117 -0
- package/src/tools/request-human-input.ts +106 -0
- package/src/tools/skills/index.ts +11 -0
- package/src/tools/skills/skill-create.ts +105 -0
- package/src/tools/skills/skill-delete.ts +67 -0
- package/src/tools/skills/skill-get.ts +75 -0
- package/src/tools/skills/skill-install-remote.ts +152 -0
- package/src/tools/skills/skill-install.ts +101 -0
- package/src/tools/skills/skill-list.ts +77 -0
- package/src/tools/skills/skill-publish.ts +123 -0
- package/src/tools/skills/skill-search.ts +43 -0
- package/src/tools/skills/skill-sync-remote.ts +128 -0
- package/src/tools/skills/skill-uninstall.ts +60 -0
- package/src/tools/skills/skill-update.ts +128 -0
- package/src/tools/store-progress.ts +22 -4
- package/src/tools/task-action.ts +20 -0
- package/src/tools/templates.ts +53 -0
- package/src/tools/tool-config.ts +23 -0
- package/src/tools/update-profile.ts +106 -34
- package/src/tools/workflows/create-workflow.ts +19 -1
- package/src/tools/workflows/update-workflow.ts +16 -1
- package/src/types.ts +109 -2
- package/src/workflows/definition.ts +30 -12
- package/src/workflows/engine.ts +40 -14
- package/src/workflows/executors/agent-task.ts +14 -3
- package/src/workflows/executors/human-in-the-loop.ts +160 -0
- package/src/workflows/executors/registry.ts +2 -0
- package/src/workflows/index.ts +1 -1
- package/src/workflows/recovery.ts +72 -0
- package/src/workflows/resume.ts +162 -12
- package/src/workflows/triggers.ts +31 -2
- package/src/workflows/version.ts +2 -0
- package/.claude/settings.json +0 -84
- package/.claude/settings.local.json +0 -117
- package/.dockerignore +0 -61
- package/.editorconfig +0 -15
- package/.entire/settings.json +0 -4
- package/.env.docker.example +0 -56
- package/.env.example +0 -78
- package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -78
- package/.github/ISSUE_TEMPLATE/community-template.yml +0 -77
- package/.github/ISSUE_TEMPLATE/config.yml +0 -8
- package/.github/ISSUE_TEMPLATE/feature_request.yml +0 -60
- package/.github/PULL_REQUEST_TEMPLATE/community-template.md +0 -29
- package/.github/workflows/ci.yml +0 -52
- package/.github/workflows/docker-and-deploy.yml +0 -132
- package/.github/workflows/merge-gate.yml +0 -233
- package/.opencode/plugins/entire.ts +0 -133
- package/.superset/config.json +0 -6
- package/.wts-config.json +0 -4
- package/.wts-setup.ts +0 -171
- package/CHANGELOG.md +0 -447
- package/CLAUDE.md +0 -521
- package/CONTRIBUTING.md +0 -315
- package/DEPLOYMENT.md +0 -622
- package/Dockerfile +0 -65
- package/Dockerfile.worker +0 -189
- package/MCP.md +0 -841
- package/UI.md +0 -40
- package/api-entrypoint.sh +0 -56
- package/assets/agent-swarm-logo-orange.png +0 -0
- package/assets/agent-swarm-logo.png +0 -0
- package/assets/agent-swarm.mp4 +0 -0
- package/assets/agent-swarm.png +0 -0
- package/biome.json +0 -39
- package/deploy/DEPLOY.md +0 -60
- package/deploy/agent-swarm.service +0 -17
- package/deploy/docker-push.ts +0 -30
- package/deploy/install.ts +0 -85
- package/deploy/prod-db.ts +0 -42
- package/deploy/uninstall.ts +0 -12
- package/deploy/update.ts +0 -21
- package/depot.json +0 -1
- package/docker-compose.example.yml +0 -350
- package/docker-compose.local.yml +0 -119
- package/docker-entrypoint.sh +0 -632
- package/docs-site/app/api/search/route.ts +0 -4
- package/docs-site/app/docs/[[...slug]]/page.tsx +0 -87
- package/docs-site/app/docs/layout.tsx +0 -12
- package/docs-site/app/globals.css +0 -24
- package/docs-site/app/layout.config.tsx +0 -34
- package/docs-site/app/layout.tsx +0 -119
- package/docs-site/app/llms-full.txt/route.ts +0 -11
- package/docs-site/app/llms.mdx/docs/[[...slug]]/route.ts +0 -24
- package/docs-site/app/llms.txt/route.ts +0 -8
- package/docs-site/app/page.tsx +0 -5
- package/docs-site/app/robots.ts +0 -13
- package/docs-site/app/sitemap.ts +0 -37
- package/docs-site/components/api-page.client.tsx +0 -4
- package/docs-site/components/api-page.tsx +0 -7
- package/docs-site/components/mdx/mermaid.tsx +0 -55
- package/docs-site/content/docs/(documentation)/architecture/agents.mdx +0 -117
- package/docs-site/content/docs/(documentation)/architecture/hooks.mdx +0 -77
- package/docs-site/content/docs/(documentation)/architecture/memory.mdx +0 -96
- package/docs-site/content/docs/(documentation)/architecture/meta.json +0 -4
- package/docs-site/content/docs/(documentation)/architecture/overview.mdx +0 -172
- package/docs-site/content/docs/(documentation)/concepts/epics.mdx +0 -98
- package/docs-site/content/docs/(documentation)/concepts/meta.json +0 -4
- package/docs-site/content/docs/(documentation)/concepts/scheduling.mdx +0 -136
- package/docs-site/content/docs/(documentation)/concepts/services.mdx +0 -104
- package/docs-site/content/docs/(documentation)/concepts/task-lifecycle.mdx +0 -148
- package/docs-site/content/docs/(documentation)/concepts/workflows.mdx +0 -209
- package/docs-site/content/docs/(documentation)/contributing.mdx +0 -158
- package/docs-site/content/docs/(documentation)/getting-started.mdx +0 -157
- package/docs-site/content/docs/(documentation)/guides/agentmail-integration.mdx +0 -79
- package/docs-site/content/docs/(documentation)/guides/deployment.mdx +0 -171
- package/docs-site/content/docs/(documentation)/guides/github-integration.mdx +0 -81
- package/docs-site/content/docs/(documentation)/guides/gitlab-integration.mdx +0 -93
- package/docs-site/content/docs/(documentation)/guides/linear-integration.mdx +0 -98
- package/docs-site/content/docs/(documentation)/guides/meta.json +0 -13
- package/docs-site/content/docs/(documentation)/guides/sentry-integration.mdx +0 -52
- package/docs-site/content/docs/(documentation)/guides/slack-integration.mdx +0 -179
- package/docs-site/content/docs/(documentation)/guides/x402-payments.mdx +0 -154
- package/docs-site/content/docs/(documentation)/index.mdx +0 -65
- package/docs-site/content/docs/(documentation)/meta.json +0 -19
- package/docs-site/content/docs/(documentation)/reference/cli.mdx +0 -241
- package/docs-site/content/docs/(documentation)/reference/environment-variables.mdx +0 -205
- package/docs-site/content/docs/(documentation)/reference/mcp-tools.mdx +0 -449
- package/docs-site/content/docs/(documentation)/reference/meta.json +0 -4
- package/docs-site/content/docs/api-reference/active-sessions.mdx +0 -9
- package/docs-site/content/docs/api-reference/agents.mdx +0 -9
- package/docs-site/content/docs/api-reference/channels.mdx +0 -9
- package/docs-site/content/docs/api-reference/config.mdx +0 -9
- package/docs-site/content/docs/api-reference/debug.mdx +0 -9
- package/docs-site/content/docs/api-reference/ecosystem.mdx +0 -9
- package/docs-site/content/docs/api-reference/epics.mdx +0 -9
- package/docs-site/content/docs/api-reference/index.mdx +0 -32
- package/docs-site/content/docs/api-reference/memory.mdx +0 -9
- package/docs-site/content/docs/api-reference/meta.json +0 -25
- package/docs-site/content/docs/api-reference/poll.mdx +0 -9
- package/docs-site/content/docs/api-reference/repos.mdx +0 -9
- package/docs-site/content/docs/api-reference/schedules.mdx +0 -9
- package/docs-site/content/docs/api-reference/session-data.mdx +0 -9
- package/docs-site/content/docs/api-reference/stats.mdx +0 -9
- package/docs-site/content/docs/api-reference/tasks.mdx +0 -9
- package/docs-site/content/docs/api-reference/trackers.mdx +0 -9
- package/docs-site/content/docs/api-reference/webhooks.mdx +0 -9
- package/docs-site/content/docs/api-reference/workflows.mdx +0 -9
- package/docs-site/content/docs/meta.json +0 -3
- package/docs-site/lib/get-llm-text.ts +0 -10
- package/docs-site/lib/openapi.ts +0 -23
- package/docs-site/lib/source.ts +0 -8
- package/docs-site/mdx-components.tsx +0 -13
- package/docs-site/next.config.mjs +0 -29
- package/docs-site/package.json +0 -35
- package/docs-site/pnpm-lock.yaml +0 -5407
- package/docs-site/postcss.config.mjs +0 -8
- package/docs-site/public/logo.png +0 -0
- package/docs-site/scripts/generate-docs.ts +0 -171
- package/docs-site/source.config.ts +0 -17
- package/docs-site/tsconfig.json +0 -46
- package/ecosystem.config.cjs +0 -66
- package/landing/next.config.ts +0 -14
- package/landing/package.json +0 -31
- package/landing/pnpm-lock.yaml +0 -1091
- package/landing/postcss.config.mjs +0 -8
- package/landing/public/apple-touch-icon.png +0 -0
- package/landing/public/favicon.ico +0 -0
- package/landing/public/logo.png +0 -0
- package/landing/public/og-image.png +0 -0
- package/landing/public/omghost-desplega.svg +0 -30
- package/landing/public/omghost-openfort.svg +0 -9
- package/landing/src/app/actions/waitlist.ts +0 -25
- package/landing/src/app/blog/openfort-hackathon/page.tsx +0 -863
- package/landing/src/app/blog/page.tsx +0 -162
- package/landing/src/app/blog/swarm-metrics/page.tsx +0 -685
- package/landing/src/app/examples/page.tsx +0 -174
- package/landing/src/app/examples/x402/page.tsx +0 -456
- package/landing/src/app/globals.css +0 -122
- package/landing/src/app/layout.tsx +0 -134
- package/landing/src/app/page.tsx +0 -27
- package/landing/src/app/robots.ts +0 -13
- package/landing/src/app/sitemap.ts +0 -44
- package/landing/src/components/architecture.tsx +0 -163
- package/landing/src/components/cta.tsx +0 -52
- package/landing/src/components/features.tsx +0 -160
- package/landing/src/components/footer.tsx +0 -100
- package/landing/src/components/hero.tsx +0 -217
- package/landing/src/components/how-it-works.tsx +0 -165
- package/landing/src/components/navbar.tsx +0 -147
- package/landing/src/components/waitlist.tsx +0 -110
- package/landing/src/components/why-choose.tsx +0 -149
- package/landing/src/components/workshops.tsx +0 -328
- package/landing/src/lib/utils.ts +0 -6
- package/landing/tsconfig.json +0 -41
- package/misc/transcripts/2026-03-09-pi-mono-e2e-verification.md +0 -154
- package/new-ui/CLAUDE.md +0 -92
- package/new-ui/README.md +0 -73
- package/new-ui/biome.json +0 -42
- package/new-ui/components.json +0 -21
- package/new-ui/index.html +0 -25
- package/new-ui/package.json +0 -49
- package/new-ui/pnpm-lock.yaml +0 -4845
- package/new-ui/public/logo.png +0 -0
- package/new-ui/src/api/client.ts +0 -814
- package/new-ui/src/api/hooks/index.ts +0 -64
- package/new-ui/src/api/hooks/use-agents.ts +0 -58
- package/new-ui/src/api/hooks/use-channels.ts +0 -115
- package/new-ui/src/api/hooks/use-config-api.ts +0 -46
- package/new-ui/src/api/hooks/use-costs.ts +0 -122
- package/new-ui/src/api/hooks/use-db-query.ts +0 -29
- package/new-ui/src/api/hooks/use-epics.ts +0 -75
- package/new-ui/src/api/hooks/use-repos.ts +0 -61
- package/new-ui/src/api/hooks/use-schedules.ts +0 -81
- package/new-ui/src/api/hooks/use-services.ts +0 -16
- package/new-ui/src/api/hooks/use-stats.ts +0 -27
- package/new-ui/src/api/hooks/use-tasks.ts +0 -89
- package/new-ui/src/api/hooks/use-workflows.ts +0 -109
- package/new-ui/src/api/types.ts +0 -549
- package/new-ui/src/app/App.tsx +0 -13
- package/new-ui/src/app/providers.tsx +0 -32
- package/new-ui/src/app/router.tsx +0 -52
- package/new-ui/src/components/layout/app-header.tsx +0 -47
- package/new-ui/src/components/layout/app-sidebar.tsx +0 -128
- package/new-ui/src/components/layout/breadcrumbs.tsx +0 -57
- package/new-ui/src/components/layout/config-guard.tsx +0 -22
- package/new-ui/src/components/layout/root-layout.tsx +0 -40
- package/new-ui/src/components/layout/swarm-switcher.tsx +0 -85
- package/new-ui/src/components/shared/command-menu.tsx +0 -131
- package/new-ui/src/components/shared/data-grid.tsx +0 -141
- package/new-ui/src/components/shared/empty-state.tsx +0 -24
- package/new-ui/src/components/shared/error-boundary.tsx +0 -72
- package/new-ui/src/components/shared/json-viewer.tsx +0 -47
- package/new-ui/src/components/shared/name-connection-modal.tsx +0 -99
- package/new-ui/src/components/shared/page-skeleton.tsx +0 -16
- package/new-ui/src/components/shared/session-log-viewer.tsx +0 -364
- package/new-ui/src/components/shared/stats-bar.tsx +0 -132
- package/new-ui/src/components/shared/status-badge.tsx +0 -131
- package/new-ui/src/components/shared/usage-summary.tsx +0 -179
- package/new-ui/src/components/ui/alert-dialog.tsx +0 -176
- package/new-ui/src/components/ui/alert.tsx +0 -60
- package/new-ui/src/components/ui/avatar.tsx +0 -96
- package/new-ui/src/components/ui/badge.tsx +0 -46
- package/new-ui/src/components/ui/button.tsx +0 -62
- package/new-ui/src/components/ui/card.tsx +0 -75
- package/new-ui/src/components/ui/command.tsx +0 -160
- package/new-ui/src/components/ui/dialog.tsx +0 -143
- package/new-ui/src/components/ui/dropdown-menu.tsx +0 -226
- package/new-ui/src/components/ui/input.tsx +0 -21
- package/new-ui/src/components/ui/label.tsx +0 -19
- package/new-ui/src/components/ui/progress.tsx +0 -26
- package/new-ui/src/components/ui/scroll-area.tsx +0 -54
- package/new-ui/src/components/ui/select.tsx +0 -175
- package/new-ui/src/components/ui/separator.tsx +0 -28
- package/new-ui/src/components/ui/sheet.tsx +0 -132
- package/new-ui/src/components/ui/sidebar.tsx +0 -691
- package/new-ui/src/components/ui/skeleton.tsx +0 -13
- package/new-ui/src/components/ui/sonner.tsx +0 -35
- package/new-ui/src/components/ui/switch.tsx +0 -33
- package/new-ui/src/components/ui/table.tsx +0 -92
- package/new-ui/src/components/ui/tabs.tsx +0 -79
- package/new-ui/src/components/ui/textarea.tsx +0 -18
- package/new-ui/src/components/ui/tooltip.tsx +0 -51
- package/new-ui/src/components/workflows/action-node.tsx +0 -53
- package/new-ui/src/components/workflows/condition-node.tsx +0 -50
- package/new-ui/src/components/workflows/graph-utils.ts +0 -124
- package/new-ui/src/components/workflows/json-tree.tsx +0 -189
- package/new-ui/src/components/workflows/node-styles.ts +0 -10
- package/new-ui/src/components/workflows/step-detail-sheet.tsx +0 -87
- package/new-ui/src/components/workflows/trigger-node.tsx +0 -41
- package/new-ui/src/components/workflows/workflow-graph.tsx +0 -65
- package/new-ui/src/hooks/use-auto-scroll.ts +0 -82
- package/new-ui/src/hooks/use-config.ts +0 -203
- package/new-ui/src/hooks/use-keyboard-shortcuts.ts +0 -41
- package/new-ui/src/hooks/use-mobile.ts +0 -19
- package/new-ui/src/hooks/use-theme.ts +0 -60
- package/new-ui/src/lib/config.ts +0 -188
- package/new-ui/src/lib/slugs.ts +0 -71
- package/new-ui/src/lib/utils.ts +0 -120
- package/new-ui/src/main.tsx +0 -11
- package/new-ui/src/pages/agents/[id]/page.tsx +0 -492
- package/new-ui/src/pages/agents/page.tsx +0 -134
- package/new-ui/src/pages/chat/page.tsx +0 -674
- package/new-ui/src/pages/config/page.tsx +0 -1109
- package/new-ui/src/pages/dashboard/page.tsx +0 -454
- package/new-ui/src/pages/debug/page.tsx +0 -275
- package/new-ui/src/pages/epics/[id]/page.tsx +0 -809
- package/new-ui/src/pages/epics/page.tsx +0 -321
- package/new-ui/src/pages/not-found/page.tsx +0 -18
- package/new-ui/src/pages/repos/page.tsx +0 -369
- package/new-ui/src/pages/schedules/[id]/page.tsx +0 -664
- package/new-ui/src/pages/schedules/page.tsx +0 -477
- package/new-ui/src/pages/services/page.tsx +0 -128
- package/new-ui/src/pages/tasks/[id]/page.tsx +0 -670
- package/new-ui/src/pages/tasks/page.tsx +0 -592
- package/new-ui/src/pages/usage/page.tsx +0 -195
- package/new-ui/src/pages/workflow-runs/[id]/page.tsx +0 -363
- package/new-ui/src/pages/workflows/[id]/page.tsx +0 -417
- package/new-ui/src/pages/workflows/page.tsx +0 -266
- package/new-ui/src/styles/ag-grid.css +0 -36
- package/new-ui/src/styles/globals.css +0 -213
- package/new-ui/test-results/.last-run.json +0 -4
- package/new-ui/tsconfig.app.json +0 -34
- package/new-ui/tsconfig.json +0 -4
- package/new-ui/tsconfig.node.json +0 -26
- package/new-ui/vercel.json +0 -4
- package/new-ui/vite.config.ts +0 -28
- package/plugin/README.md +0 -1
- package/plugin/build-pi-skills.ts +0 -233
- package/plugin/hooks/hooks.json +0 -71
- package/prek.toml +0 -75
- package/pyproject.toml +0 -9
- package/scripts/check-db-boundary.sh +0 -60
- package/scripts/e2e-docker-provider.ts +0 -820
- package/scripts/e2e-io-schemas-test.ts +0 -807
- package/scripts/e2e-provider-test.ts +0 -220
- package/scripts/e2e-workflow-redesign.sh +0 -229
- package/scripts/e2e-workflow-test.sh +0 -285
- package/scripts/e2e-workflow-test.ts +0 -857
- package/scripts/generate-mcp-docs.ts +0 -415
- package/scripts/generate-openapi.ts +0 -26
- package/scripts/measure-tool-tokens.ts +0 -118
- package/scripts/x402-e2e-test.ts +0 -195
- package/scripts/x402-test-server.ts +0 -236
- package/scripts/x402-testnet-e2e.ts +0 -668
- package/slack-manifest.json +0 -88
- package/templates-ui/README.md +0 -46
- package/templates-ui/components.json +0 -17
- package/templates-ui/eslint.config.mjs +0 -18
- package/templates-ui/next.config.ts +0 -7
- package/templates-ui/package.json +0 -35
- package/templates-ui/pnpm-lock.yaml +0 -4571
- package/templates-ui/postcss.config.mjs +0 -7
- package/templates-ui/public/file.svg +0 -1
- package/templates-ui/public/globe.svg +0 -1
- package/templates-ui/public/logo.png +0 -0
- package/templates-ui/public/next.svg +0 -1
- package/templates-ui/public/vercel.svg +0 -1
- package/templates-ui/public/window.svg +0 -1
- package/templates-ui/src/app/[category]/[name]/page.tsx +0 -89
- package/templates-ui/src/app/api/templates/[...slug]/route.ts +0 -52
- package/templates-ui/src/app/api/templates/route.ts +0 -18
- package/templates-ui/src/app/builder/page.tsx +0 -37
- package/templates-ui/src/app/globals.css +0 -94
- package/templates-ui/src/app/layout.tsx +0 -79
- package/templates-ui/src/app/page.tsx +0 -38
- package/templates-ui/src/app/robots.ts +0 -11
- package/templates-ui/src/app/sitemap.ts +0 -31
- package/templates-ui/src/components/compose-builder.tsx +0 -442
- package/templates-ui/src/components/compose-preview.tsx +0 -117
- package/templates-ui/src/components/file-preview.tsx +0 -77
- package/templates-ui/src/components/footer.tsx +0 -40
- package/templates-ui/src/components/header.tsx +0 -41
- package/templates-ui/src/components/template-card.tsx +0 -87
- package/templates-ui/src/components/template-detail.tsx +0 -125
- package/templates-ui/src/components/template-gallery.tsx +0 -263
- package/templates-ui/src/components/ui/badge.tsx +0 -36
- package/templates-ui/src/components/ui/button.tsx +0 -57
- package/templates-ui/src/components/ui/card.tsx +0 -76
- package/templates-ui/src/components/ui/separator.tsx +0 -31
- package/templates-ui/src/components/ui/tooltip.tsx +0 -32
- package/templates-ui/src/lib/compose-generator.ts +0 -241
- package/templates-ui/src/lib/templates.ts +0 -137
- package/templates-ui/src/lib/utils.ts +0 -6
- package/templates-ui/tsconfig.json +0 -34
- package/thoughts/research/2026-02-28-openfort-viem-x402-research.md +0 -679
- package/thoughts/research/2026-02-28-x402-payments-research.md +0 -686
- package/thoughts/researcher/plans/2026-02-20-agent-self-improvement-plan.md +0 -282
- package/thoughts/researcher/research/2026-02-20-agent-self-improvement.md +0 -492
- package/thoughts/shared/plans/.gitkeep +0 -0
- package/thoughts/shared/plans/2025-12-18-slack-integration.md +0 -1195
- package/thoughts/shared/plans/2025-12-19-agent-log-streaming.md +0 -732
- package/thoughts/shared/plans/2025-12-19-role-based-swarm-plugin.md +0 -361
- package/thoughts/shared/plans/2025-12-20-mobile-responsive-ui.md +0 -501
- package/thoughts/shared/plans/2025-12-20-startup-team-swarm.md +0 -560
- package/thoughts/shared/plans/2025-12-23-runner-level-polling.md +0 -934
- package/thoughts/shared/plans/2025-12-23-runner-session-logs.md +0 -1000
- package/thoughts/shared/plans/2025-12-23-worker-lead-spawn-triggers.md +0 -568
- package/thoughts/shared/plans/2026-01-09-inverse-teleport.md +0 -1516
- package/thoughts/shared/plans/2026-01-12-agent-rename-pm2-control.md +0 -1133
- package/thoughts/shared/plans/2026-01-12-github-app-integration.md +0 -380
- package/thoughts/shared/plans/2026-01-12-lead-inbox-model.md +0 -876
- package/thoughts/shared/plans/2026-01-12-ralph-wiggum-integration.md +0 -463
- package/thoughts/shared/plans/2026-01-13-agent-concurrency.md +0 -691
- package/thoughts/shared/plans/2026-01-13-github-assignment-handling.md +0 -690
- package/thoughts/shared/plans/2026-01-13-prevent-duplicate-trigger-processing.md +0 -1071
- package/thoughts/shared/plans/2026-01-14-fix-slack-thread-context.md +0 -507
- package/thoughts/shared/plans/2026-01-15-scheduled-tasks-implementation.md +0 -565
- package/thoughts/shared/plans/2026-01-15-usage-cost-tracking-ui.md +0 -1479
- package/thoughts/shared/plans/2026-01-16-epics-feature-implementation.md +0 -1230
- package/thoughts/shared/plans/2026-02-26-mcp-tool-context-reduction.md +0 -282
- package/thoughts/shared/plans/2026-03-02-claude-context-mode-integration.md +0 -328
- package/thoughts/shared/plans/2026-03-02-code-level-heartbeat.md +0 -224
- package/thoughts/shared/research/.gitkeep +0 -0
- package/thoughts/shared/research/2025-01-09-inverse-teleport-plan-review.md +0 -420
- package/thoughts/shared/research/2025-12-18-slack-integration.md +0 -442
- package/thoughts/shared/research/2025-12-19-agent-log-streaming.md +0 -339
- package/thoughts/shared/research/2025-12-19-agent-secrets-cli-research.md +0 -390
- package/thoughts/shared/research/2025-12-21-gemini-cli-integration.md +0 -376
- package/thoughts/shared/research/2025-12-22-runner-loop-architecture.md +0 -582
- package/thoughts/shared/research/2025-12-22-setup-experience-improvements.md +0 -264
- package/thoughts/shared/research/2026-01-13-lead-duplicate-trigger-processing.md +0 -223
- package/thoughts/shared/research/2026-01-14-lead-slack-thread-context.md +0 -277
- package/thoughts/shared/research/2026-01-15-ai-tracker-agent-swarm-integration.md +0 -376
- package/thoughts/shared/research/2026-01-15-auto-starting-processes-in-worker-containers.md +0 -787
- package/thoughts/shared/research/2026-01-15-scheduled-tasks.md +0 -390
- package/thoughts/shared/research/2026-01-16-epics-feature-research.md +0 -437
- package/thoughts/shared/research/2026-02-26-cliffy-mcp-tools.md +0 -159
- package/thoughts/shared/research/2026-03-03-database-migration-system-refactor.md +0 -337
- package/thoughts/swarm-researcher/plans/2026-02-23-openclaw-improvements-plan.md +0 -778
- package/thoughts/swarm-researcher/plans/2026-02-26-artifacts-localtunnel-plan.md +0 -1269
- package/thoughts/swarm-researcher/research/2026-02-23-openclaw-vs-agent-swarm-comparison.md +0 -411
- package/thoughts/swarm-researcher/research/2026-02-26-artifacts-localtunnel.md +0 -724
- package/thoughts/taras/brainstorms/2026-03-20-prompt-template-registry.md +0 -443
- package/thoughts/taras/brainstorms/2026-03-20-setup-cli-onboarding.md +0 -307
- package/thoughts/taras/plans/2026-01-22-agent-swarm-schemas.md +0 -98
- package/thoughts/taras/plans/2026-01-28-per-worker-claude-md.md +0 -617
- package/thoughts/taras/plans/2026-01-28-sentry-cli-integration.md +0 -214
- package/thoughts/taras/plans/2026-02-20-auto-improvement.md +0 -803
- package/thoughts/taras/plans/2026-02-20-env-management.md +0 -538
- package/thoughts/taras/plans/2026-02-20-memory-system.md +0 -882
- package/thoughts/taras/plans/2026-02-20-repos-knowledge.md +0 -806
- package/thoughts/taras/plans/2026-02-20-session-attach.md +0 -647
- package/thoughts/taras/plans/2026-02-20-worker-identity.md +0 -820
- package/thoughts/taras/plans/2026-02-25-feat-new-ui-visual-redesign-plan.md +0 -768
- package/thoughts/taras/plans/2026-03-04-fix-buildSystemPrompt-missing-fields.md +0 -77
- package/thoughts/taras/plans/2026-03-04-new-ui-missing-actions.md +0 -543
- package/thoughts/taras/plans/2026-03-06-one-time-scheduled-tasks.md +0 -373
- package/thoughts/taras/plans/2026-03-08-memory-self-improvement-enhancements.md +0 -512
- package/thoughts/taras/plans/2026-03-08-pi-mono-provider-implementation.md +0 -919
- package/thoughts/taras/plans/2026-03-09-templates-registry.md +0 -723
- package/thoughts/taras/plans/2026-03-10-task-working-directory.md +0 -371
- package/thoughts/taras/plans/2026-03-11-archil-per-agent-write-strategy.md +0 -621
- package/thoughts/taras/plans/2026-03-12-eliminate-inbox-route-to-tasks.md +0 -61
- package/thoughts/taras/plans/2026-03-12-slack-thread-followup-additive.md +0 -488
- package/thoughts/taras/plans/2026-03-13-slack-ai-improvements.md +0 -644
- package/thoughts/taras/plans/2026-03-16-route-wrapper-openapi.md +0 -636
- package/thoughts/taras/plans/2026-03-17-multi-api-config.md +0 -444
- package/thoughts/taras/plans/2026-03-18-agent-fs-integration.md +0 -591
- package/thoughts/taras/plans/2026-03-18-debug-db-explorer.md +0 -446
- package/thoughts/taras/plans/2026-03-18-workflow-redesign.md +0 -987
- package/thoughts/taras/plans/2026-03-19-compound-learnings.md +0 -403
- package/thoughts/taras/plans/2026-03-19-ticket-tracker-linear-integration.md +0 -860
- package/thoughts/taras/plans/2026-03-19-workflow-io-schemas-and-bugs.md +0 -899
- package/thoughts/taras/plans/2026-03-20-setup-cli-onboarding.md +0 -874
- package/thoughts/taras/plans/2026-03-20-workflow-structured-output-validation-workspace.md +0 -723
- package/thoughts/taras/research/2026-01-22-vercel-cli-integration.md +0 -287
- package/thoughts/taras/research/2026-01-27-excessive-polling-issue.md +0 -311
- package/thoughts/taras/research/2026-01-28-per-worker-claude-md.md +0 -383
- package/thoughts/taras/research/2026-01-28-sentry-cli-integration.md +0 -240
- package/thoughts/taras/research/2026-02-19-agent-native-swarm-architecture.md +0 -390
- package/thoughts/taras/research/2026-02-19-swarm-gaps-implementation.md +0 -594
- package/thoughts/taras/research/2026-02-25-dashboard-ui-design-best-practices.md +0 -825
- package/thoughts/taras/research/2026-02-26-task-detail-page-redesign.md +0 -393
- package/thoughts/taras/research/2026-03-03-new-ui-missing-actions.md +0 -168
- package/thoughts/taras/research/2026-03-05-pi-mono-provider-research.md +0 -230
- package/thoughts/taras/research/2026-03-06-workflow-engine-design.md +0 -445
- package/thoughts/taras/research/2026-03-08-drive-loop-concept.md +0 -375
- package/thoughts/taras/research/2026-03-08-pi-mono-deep-dive.md +0 -869
- package/thoughts/taras/research/2026-03-09-templates-registry.md +0 -373
- package/thoughts/taras/research/2026-03-10-agent-working-directory.md +0 -223
- package/thoughts/taras/research/2026-03-10-configurable-event-prompts.md +0 -339
- package/thoughts/taras/research/2026-03-11-archil-production-setup.md +0 -181
- package/thoughts/taras/research/2026-03-11-archil-shared-disk-write-strategies.md +0 -437
- package/thoughts/taras/research/2026-03-13-slack-ai-features.md +0 -258
- package/thoughts/taras/research/2026-03-16-openapi-docs-generation.md +0 -335
- package/thoughts/taras/research/2026-03-16-route-wrapper-openapi.md +0 -670
- package/thoughts/taras/research/2026-03-16-slack-thread-followups-e2e.md +0 -54
- package/thoughts/taras/research/2026-03-18-agent-fs-integration.md +0 -558
- package/thoughts/taras/research/2026-03-18-linear-integration-finalization.md +0 -526
- package/thoughts/taras/research/2026-03-18-workflow-redesign.md +0 -797
- package/thoughts/taras/research/2026-03-19-workflow-node-io-schemas-and-bugs.md +0 -563
- package/thoughts/taras/research/2026-03-19-workflow-structured-output-validation-workspace.md +0 -486
- package/thoughts/taras/research/2026-03-20-prompt-template-registry.md +0 -469
- package/tsconfig.json +0 -37
package/scripts/x402-e2e-test.ts
DELETED
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
/**
|
|
3
|
-
* x402 End-to-End Test
|
|
4
|
-
*
|
|
5
|
-
* Tests the full x402 payment flow:
|
|
6
|
-
* 1. Starts the dummy x402 test server
|
|
7
|
-
* 2. Creates an x402 client (with viem signer using a test key)
|
|
8
|
-
* 3. Makes a request to the paid endpoint
|
|
9
|
-
* 4. Verifies the 402 → sign → retry → 200 flow works
|
|
10
|
-
*
|
|
11
|
-
* Usage:
|
|
12
|
-
* bun scripts/x402-e2e-test.ts
|
|
13
|
-
*
|
|
14
|
-
* Environment:
|
|
15
|
-
* Set EVM_PRIVATE_KEY or OPENFORT_API_KEY + OPENFORT_WALLET_SECRET
|
|
16
|
-
* If none set, uses a hardcoded test key (viem signer).
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
import { createX402Client } from "../src/x402/client.ts";
|
|
20
|
-
import type { Subprocess } from "bun";
|
|
21
|
-
|
|
22
|
-
const TEST_PRIVATE_KEY = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80";
|
|
23
|
-
const SERVER_PORT = 4021;
|
|
24
|
-
const BASE_URL = `http://localhost:${SERVER_PORT}`;
|
|
25
|
-
|
|
26
|
-
let serverProcess: Subprocess | null = null;
|
|
27
|
-
|
|
28
|
-
async function startServer(): Promise<void> {
|
|
29
|
-
serverProcess = Bun.spawn(["bun", "scripts/x402-test-server.ts", String(SERVER_PORT)], {
|
|
30
|
-
stdout: "pipe",
|
|
31
|
-
stderr: "pipe",
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
// Wait for server to be ready
|
|
35
|
-
for (let i = 0; i < 30; i++) {
|
|
36
|
-
try {
|
|
37
|
-
const res = await fetch(`${BASE_URL}/health`);
|
|
38
|
-
if (res.ok) return;
|
|
39
|
-
} catch {
|
|
40
|
-
// Server not ready yet
|
|
41
|
-
}
|
|
42
|
-
await Bun.sleep(100);
|
|
43
|
-
}
|
|
44
|
-
throw new Error("Server failed to start within 3 seconds");
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function stopServer(): void {
|
|
48
|
-
if (serverProcess) {
|
|
49
|
-
serverProcess.kill();
|
|
50
|
-
serverProcess = null;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function log(msg: string): void {
|
|
55
|
-
console.log(` ${msg}`);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function pass(name: string): void {
|
|
59
|
-
console.log(` PASS ${name}`);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function fail(name: string, error: unknown): void {
|
|
63
|
-
console.log(` FAIL ${name}: ${error instanceof Error ? error.message : String(error)}`);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
async function runTests(): Promise<{ passed: number; failed: number }> {
|
|
67
|
-
let passed = 0;
|
|
68
|
-
let failed = 0;
|
|
69
|
-
|
|
70
|
-
// Determine signer type
|
|
71
|
-
const hasOpenfort = !!process.env.OPENFORT_API_KEY;
|
|
72
|
-
const hasViem = !!process.env.EVM_PRIVATE_KEY;
|
|
73
|
-
|
|
74
|
-
if (!hasOpenfort && !hasViem) {
|
|
75
|
-
log(`No signer env vars set. Using test private key (viem signer).`);
|
|
76
|
-
process.env.EVM_PRIVATE_KEY = TEST_PRIVATE_KEY;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Test 1: Free endpoint works
|
|
80
|
-
try {
|
|
81
|
-
const res = await fetch(`${BASE_URL}/`);
|
|
82
|
-
const body = await res.json();
|
|
83
|
-
if (res.status !== 200 || body.status !== "ok") throw new Error(`Expected 200 ok, got ${res.status}`);
|
|
84
|
-
pass("Free endpoint returns 200");
|
|
85
|
-
passed++;
|
|
86
|
-
} catch (e) {
|
|
87
|
-
fail("Free endpoint returns 200", e);
|
|
88
|
-
failed++;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Test 2: Paid endpoint returns 402 without payment
|
|
92
|
-
try {
|
|
93
|
-
const res = await fetch(`${BASE_URL}/paid`);
|
|
94
|
-
if (res.status !== 402) throw new Error(`Expected 402, got ${res.status}`);
|
|
95
|
-
const body = await res.json();
|
|
96
|
-
if (!body.accepts || body.x402Version !== 2) throw new Error("Missing x402 payment requirements");
|
|
97
|
-
pass("Paid endpoint returns 402 without payment");
|
|
98
|
-
passed++;
|
|
99
|
-
} catch (e) {
|
|
100
|
-
fail("Paid endpoint returns 402 without payment", e);
|
|
101
|
-
failed++;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Test 3: Full x402 flow with viem/openfort signer
|
|
105
|
-
try {
|
|
106
|
-
const client = await createX402Client();
|
|
107
|
-
log(`Using ${client.config.signerType} signer, wallet: ${client.walletAddress}`);
|
|
108
|
-
|
|
109
|
-
const res = await client.fetch(`${BASE_URL}/paid`);
|
|
110
|
-
const body = await res.json();
|
|
111
|
-
|
|
112
|
-
if (res.status !== 200) {
|
|
113
|
-
throw new Error(`Expected 200 after payment, got ${res.status}: ${JSON.stringify(body)}`);
|
|
114
|
-
}
|
|
115
|
-
if (!body.paymentAccepted) {
|
|
116
|
-
throw new Error("Server did not acknowledge payment acceptance");
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
pass(`Full x402 flow (${client.config.signerType} signer) → 200 with payment accepted`);
|
|
120
|
-
log(` Payer: ${body.payer}`);
|
|
121
|
-
log(` Amount: ${body.amount}`);
|
|
122
|
-
passed++;
|
|
123
|
-
} catch (e) {
|
|
124
|
-
fail("Full x402 flow", e);
|
|
125
|
-
failed++;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Test 4: Spending tracker records payment
|
|
129
|
-
try {
|
|
130
|
-
const client = await createX402Client();
|
|
131
|
-
const summaryBefore = client.getSpendingSummary();
|
|
132
|
-
const countBefore = summaryBefore.todayCount;
|
|
133
|
-
|
|
134
|
-
await client.fetch(`${BASE_URL}/paid`);
|
|
135
|
-
|
|
136
|
-
const summaryAfter = client.getSpendingSummary();
|
|
137
|
-
if (summaryAfter.todayCount !== countBefore + 1) {
|
|
138
|
-
throw new Error(`Expected ${countBefore + 1} payments, got ${summaryAfter.todayCount}`);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
pass("Spending tracker records payment");
|
|
142
|
-
log(` Spent today: $${summaryAfter.todaySpent.toFixed(4)}`);
|
|
143
|
-
passed++;
|
|
144
|
-
} catch (e) {
|
|
145
|
-
fail("Spending tracker records payment", e);
|
|
146
|
-
failed++;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// Test 5: Expensive endpoint blocked by spending limit (default $1.00/request)
|
|
150
|
-
try {
|
|
151
|
-
const client = await createX402Client();
|
|
152
|
-
|
|
153
|
-
const res = await client.fetch(`${BASE_URL}/paid/expensive`);
|
|
154
|
-
// The spending tracker should block this since $5 > $1 per-request limit
|
|
155
|
-
// The x402 client will throw or return an error
|
|
156
|
-
// Actually, the abort happens in the hook which throws
|
|
157
|
-
fail("Expensive endpoint should be blocked by spending limit", "No error thrown");
|
|
158
|
-
failed++;
|
|
159
|
-
} catch (e) {
|
|
160
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
161
|
-
if (msg.includes("exceeds per-request limit") || msg.includes("abort") || msg.includes("Failed to create payment")) {
|
|
162
|
-
pass("Expensive endpoint blocked by spending limit ($5 > $1 max)");
|
|
163
|
-
passed++;
|
|
164
|
-
} else {
|
|
165
|
-
fail("Expensive endpoint blocked by spending limit", e);
|
|
166
|
-
failed++;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
return { passed, failed };
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
async function main() {
|
|
174
|
-
console.log("x402 End-to-End Test");
|
|
175
|
-
console.log("====================\n");
|
|
176
|
-
|
|
177
|
-
console.log("Starting test server...");
|
|
178
|
-
await startServer();
|
|
179
|
-
console.log(`Server running on ${BASE_URL}\n`);
|
|
180
|
-
|
|
181
|
-
try {
|
|
182
|
-
const { passed, failed } = await runTests();
|
|
183
|
-
console.log(`\nResults: ${passed} passed, ${failed} failed`);
|
|
184
|
-
process.exitCode = failed > 0 ? 1 : 0;
|
|
185
|
-
} finally {
|
|
186
|
-
stopServer();
|
|
187
|
-
console.log("Server stopped.");
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
main().catch((error) => {
|
|
192
|
-
console.error("Fatal:", error instanceof Error ? error.message : String(error));
|
|
193
|
-
stopServer();
|
|
194
|
-
process.exit(1);
|
|
195
|
-
});
|
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
/**
|
|
3
|
-
* Dummy x402 Test Server
|
|
4
|
-
*
|
|
5
|
-
* A minimal HTTP server with an x402-protected endpoint for testing the payment flow.
|
|
6
|
-
* Does NOT settle on-chain — just verifies the EIP-712 signature from the payment header.
|
|
7
|
-
*
|
|
8
|
-
* Endpoints:
|
|
9
|
-
* GET / — Free endpoint (returns 200)
|
|
10
|
-
* GET /paid — x402-protected endpoint (returns 402, then 200 with valid payment)
|
|
11
|
-
* GET /paid/expensive — x402-protected with higher price ($5 USDC)
|
|
12
|
-
*
|
|
13
|
-
* Usage:
|
|
14
|
-
* bun scripts/x402-test-server.ts [port]
|
|
15
|
-
*
|
|
16
|
-
* Default port: 4020
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
import { getAddress, verifyTypedData } from "viem";
|
|
20
|
-
import { encodePaymentRequiredHeader } from "@x402/core/http";
|
|
21
|
-
|
|
22
|
-
const PORT = Number.parseInt(process.argv[2] || "4020", 10);
|
|
23
|
-
|
|
24
|
-
// A well-known test address to use as payTo (doesn't need to be real for testing)
|
|
25
|
-
const PAY_TO = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"; // vitalik.eth
|
|
26
|
-
|
|
27
|
-
// USDC on Base Sepolia — EIP-712 domain params
|
|
28
|
-
const USDC_ADDRESS = "0x036CbD53842c5426634e7929541eC2318f3dCF7e";
|
|
29
|
-
const USDC_NAME = "USD Coin";
|
|
30
|
-
const USDC_VERSION = "2";
|
|
31
|
-
const CHAIN_ID = 84532; // Base Sepolia
|
|
32
|
-
|
|
33
|
-
// EIP-3009 TransferWithAuthorization types
|
|
34
|
-
const authorizationTypes = {
|
|
35
|
-
TransferWithAuthorization: [
|
|
36
|
-
{ name: "from", type: "address" },
|
|
37
|
-
{ name: "to", type: "address" },
|
|
38
|
-
{ name: "value", type: "uint256" },
|
|
39
|
-
{ name: "validAfter", type: "uint256" },
|
|
40
|
-
{ name: "validBefore", type: "uint256" },
|
|
41
|
-
{ name: "nonce", type: "bytes32" },
|
|
42
|
-
],
|
|
43
|
-
} as const;
|
|
44
|
-
|
|
45
|
-
interface PaymentRequired {
|
|
46
|
-
x402Version: number;
|
|
47
|
-
resource: { url: string; description: string; mimeType: string };
|
|
48
|
-
accepts: Array<{
|
|
49
|
-
scheme: string;
|
|
50
|
-
network: string;
|
|
51
|
-
asset: string;
|
|
52
|
-
amount: string;
|
|
53
|
-
payTo: string;
|
|
54
|
-
maxTimeoutSeconds: number;
|
|
55
|
-
extra: Record<string, unknown>;
|
|
56
|
-
}>;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function buildPaymentRequired(url: string, amount: string): PaymentRequired {
|
|
60
|
-
return {
|
|
61
|
-
x402Version: 2,
|
|
62
|
-
resource: {
|
|
63
|
-
url,
|
|
64
|
-
description: "Premium test content",
|
|
65
|
-
mimeType: "application/json",
|
|
66
|
-
},
|
|
67
|
-
accepts: [
|
|
68
|
-
{
|
|
69
|
-
scheme: "exact",
|
|
70
|
-
network: "eip155:84532", // Base Sepolia
|
|
71
|
-
asset: USDC_ADDRESS,
|
|
72
|
-
amount,
|
|
73
|
-
payTo: PAY_TO,
|
|
74
|
-
maxTimeoutSeconds: 86400,
|
|
75
|
-
extra: {
|
|
76
|
-
// EIP-712 domain params required by the x402 exact EVM scheme
|
|
77
|
-
name: USDC_NAME,
|
|
78
|
-
version: USDC_VERSION,
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
],
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Decode a base64-encoded payment payload from the PAYMENT-SIGNATURE header.
|
|
87
|
-
*/
|
|
88
|
-
function decodePaymentHeader(headerValue: string): Record<string, unknown> | null {
|
|
89
|
-
try {
|
|
90
|
-
const json = atob(headerValue);
|
|
91
|
-
return JSON.parse(json);
|
|
92
|
-
} catch {
|
|
93
|
-
return null;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Verify the EIP-3009 TransferWithAuthorization signature in the payment payload.
|
|
99
|
-
*
|
|
100
|
-
* The x402 exact EVM scheme creates a payload like:
|
|
101
|
-
* { authorization: { from, to, value, validAfter, validBefore, nonce }, signature: "0x..." }
|
|
102
|
-
*/
|
|
103
|
-
async function verifyPayment(paymentPayload: Record<string, unknown>): Promise<{
|
|
104
|
-
valid: boolean;
|
|
105
|
-
payer?: string;
|
|
106
|
-
reason?: string;
|
|
107
|
-
}> {
|
|
108
|
-
try {
|
|
109
|
-
const payload = paymentPayload.payload as Record<string, unknown>;
|
|
110
|
-
if (!payload) {
|
|
111
|
-
return { valid: false, reason: "missing payload" };
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const signature = payload.signature as `0x${string}`;
|
|
115
|
-
const authorization = payload.authorization as Record<string, unknown>;
|
|
116
|
-
|
|
117
|
-
if (!signature) {
|
|
118
|
-
return { valid: false, reason: "missing signature in payload" };
|
|
119
|
-
}
|
|
120
|
-
if (!authorization) {
|
|
121
|
-
// No authorization data — accept the payment header as-is (basic test mode)
|
|
122
|
-
return { valid: true, payer: "unknown (signature present, no authorization data)" };
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Reconstruct the EIP-712 typed data and verify the signature
|
|
126
|
-
const domain = {
|
|
127
|
-
name: USDC_NAME,
|
|
128
|
-
version: USDC_VERSION,
|
|
129
|
-
chainId: BigInt(CHAIN_ID),
|
|
130
|
-
verifyingContract: getAddress(USDC_ADDRESS),
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
const message = {
|
|
134
|
-
from: getAddress(authorization.from as string),
|
|
135
|
-
to: getAddress(authorization.to as string),
|
|
136
|
-
value: BigInt(authorization.value as string),
|
|
137
|
-
validAfter: BigInt(authorization.validAfter as string),
|
|
138
|
-
validBefore: BigInt(authorization.validBefore as string),
|
|
139
|
-
nonce: authorization.nonce as `0x${string}`,
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
const valid = await verifyTypedData({
|
|
143
|
-
address: message.from,
|
|
144
|
-
domain,
|
|
145
|
-
types: authorizationTypes,
|
|
146
|
-
primaryType: "TransferWithAuthorization",
|
|
147
|
-
message,
|
|
148
|
-
signature,
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
return { valid, payer: message.from };
|
|
152
|
-
} catch (error) {
|
|
153
|
-
return {
|
|
154
|
-
valid: false,
|
|
155
|
-
reason: `verification error: ${error instanceof Error ? error.message : String(error)}`,
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
const server = Bun.serve({
|
|
161
|
-
port: PORT,
|
|
162
|
-
async fetch(req) {
|
|
163
|
-
const url = new URL(req.url);
|
|
164
|
-
|
|
165
|
-
// Free endpoint
|
|
166
|
-
if (url.pathname === "/" || url.pathname === "/health") {
|
|
167
|
-
return Response.json({ status: "ok", message: "x402 test server running" });
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// Paid endpoints
|
|
171
|
-
if (url.pathname.startsWith("/paid")) {
|
|
172
|
-
const isExpensive = url.pathname === "/paid/expensive";
|
|
173
|
-
const amount = isExpensive ? "5000000" : "10000"; // $5.00 or $0.01 USDC (6 decimals)
|
|
174
|
-
|
|
175
|
-
// Check for payment header
|
|
176
|
-
const paymentHeader =
|
|
177
|
-
req.headers.get("PAYMENT-SIGNATURE") || req.headers.get("X-PAYMENT");
|
|
178
|
-
|
|
179
|
-
if (!paymentHeader) {
|
|
180
|
-
// No payment — return 402 with payment requirements
|
|
181
|
-
const paymentRequired = buildPaymentRequired(
|
|
182
|
-
`${url.origin}${url.pathname}`,
|
|
183
|
-
amount,
|
|
184
|
-
);
|
|
185
|
-
|
|
186
|
-
// x402 v2 requires the PAYMENT-REQUIRED header (base64-encoded PaymentRequired)
|
|
187
|
-
const encoded = encodePaymentRequiredHeader(
|
|
188
|
-
paymentRequired as Parameters<typeof encodePaymentRequiredHeader>[0],
|
|
189
|
-
);
|
|
190
|
-
|
|
191
|
-
return new Response(JSON.stringify(paymentRequired), {
|
|
192
|
-
status: 402,
|
|
193
|
-
headers: {
|
|
194
|
-
"Content-Type": "application/json",
|
|
195
|
-
"PAYMENT-REQUIRED": encoded,
|
|
196
|
-
},
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Has payment header — decode and verify
|
|
201
|
-
const paymentPayload = decodePaymentHeader(paymentHeader);
|
|
202
|
-
if (!paymentPayload) {
|
|
203
|
-
return Response.json(
|
|
204
|
-
{ error: "Invalid payment header (could not decode base64/JSON)" },
|
|
205
|
-
{ status: 400 },
|
|
206
|
-
);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
const verification = await verifyPayment(paymentPayload);
|
|
210
|
-
|
|
211
|
-
if (!verification.valid) {
|
|
212
|
-
return Response.json(
|
|
213
|
-
{ error: `Payment verification failed: ${verification.reason}` },
|
|
214
|
-
{ status: 402 },
|
|
215
|
-
);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// Payment accepted — return the premium content
|
|
219
|
-
return Response.json({
|
|
220
|
-
content: isExpensive ? "This is expensive premium content!" : "This is paid content!",
|
|
221
|
-
paymentAccepted: true,
|
|
222
|
-
payer: verification.payer,
|
|
223
|
-
amount: isExpensive ? "$5.00" : "$0.01",
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
return Response.json({ error: "Not found" }, { status: 404 });
|
|
228
|
-
},
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
console.log(`x402 test server running on http://localhost:${server.port}`);
|
|
232
|
-
console.log("Endpoints:");
|
|
233
|
-
console.log(" GET / Free endpoint");
|
|
234
|
-
console.log(" GET /paid x402-protected ($0.01 USDC)");
|
|
235
|
-
console.log(" GET /paid/expensive x402-protected ($5.00 USDC)");
|
|
236
|
-
console.log("\nPress Ctrl+C to stop.");
|