@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
|
@@ -1,538 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
date: 2026-02-20
|
|
3
|
-
planner: Claude
|
|
4
|
-
branch: claw-env-management
|
|
5
|
-
repository: agent-swarm
|
|
6
|
-
topic: "Env Management API — Gap 6 Implementation"
|
|
7
|
-
tags: [plan, env-management, config, gap-6, agent-native]
|
|
8
|
-
status: implemented
|
|
9
|
-
autonomy: autopilot
|
|
10
|
-
research: thoughts/taras/research/2026-02-19-swarm-gaps-implementation.md
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
# Env Management API — Implementation Plan
|
|
14
|
-
|
|
15
|
-
## Overview
|
|
16
|
-
|
|
17
|
-
Implement a centralized environment/config management system for the agent swarm. This is Gap 6 from the swarm-gaps research and the first phase in the agent-native architecture rollout (order: 6 → 1 → 2 → 3 → 4 → 5).
|
|
18
|
-
|
|
19
|
-
Today, env vars are scattered across flat `.env` files (`.env`, `.env.docker`, `.env.docker-lead`) with no centralized store, no per-agent config, no per-repo config, and no UI for management. The only env-like storage is `services.env` (a JSON column for PM2 service env vars).
|
|
20
|
-
|
|
21
|
-
This plan adds: a `swarm_config` DB table with scoped key-value storage, REST API endpoints, Docker entrypoint integration (exporting config as env vars), and a UI management page.
|
|
22
|
-
|
|
23
|
-
## Current State Analysis
|
|
24
|
-
|
|
25
|
-
### What Exists
|
|
26
|
-
|
|
27
|
-
- **Flat `.env` files**: `.env` (API server), `.env.docker` (worker), `.env.docker-lead` (lead). Workers receive env vars via Docker `--env-file` or docker-compose `environment:` blocks.
|
|
28
|
-
- **No config DB table**: The only env-like DB storage is `services.env` JSON column (`src/be/db.ts:157`).
|
|
29
|
-
- **No config API**: No REST endpoints for config CRUD. The UI's `ConfigModal.tsx` only stores API URL and API key in localStorage.
|
|
30
|
-
- **Docker entrypoint**: Validates only `CLAUDE_CODE_OAUTH_TOKEN` and `API_KEY` (`docker-entrypoint.sh:4-13`). Has one `curl` call pattern (ecosystem fetch at lines 49-51) that we can model after.
|
|
31
|
-
- **Per-agent config**: Only `maxTasks`, `claudeMd`, `role`, `capabilities` on the `agents` table.
|
|
32
|
-
|
|
33
|
-
### Key Discoveries
|
|
34
|
-
|
|
35
|
-
- DB table creation goes inside `initSchema` transaction in `src/be/db.ts` (before line 325)
|
|
36
|
-
- DB CRUD follows: Row type → `rowToEntity` converter → exported functions using `getDb().prepare()` with `RETURNING *`
|
|
37
|
-
- REST routes use manual `if` checks on `pathSegments` in `src/http.ts`; query params via `parseQueryParams()`; body parsing inline with `for await`
|
|
38
|
-
- UI uses MUI Joy Tabs in `Dashboard.tsx`; API calls via `ApiClient` class + React Query hooks; beehive theme with local `colors` objects
|
|
39
|
-
- Docker entrypoint curl pattern: `-s -f -H "Authorization: Bearer ${API_KEY}" -H "X-Agent-ID: ${AGENT_ID}"` with temp file output
|
|
40
|
-
|
|
41
|
-
## Desired End State
|
|
42
|
-
|
|
43
|
-
1. A `swarm_config` table stores key-value pairs scoped to `global`, `agent`, or `repo`
|
|
44
|
-
2. REST API at `/api/config` supports CRUD with scope filtering and resolved (merged) config
|
|
45
|
-
3. Docker entrypoint fetches resolved config and exports as env vars before launching the agent — this is the primary mechanism agents use to access config (via `process.env`)
|
|
46
|
-
4. UI has a "CONFIG" tab with sub-tabs for Global, Per-Agent, and Per-Repo config management
|
|
47
|
-
5. Secrets are masked in API responses by default; an `?includeSecrets=true` param reveals them
|
|
48
|
-
6. The `envPath` feature auto-writes `KEY=VALUE` to `.env` files on the filesystem when config is created/updated
|
|
49
|
-
|
|
50
|
-
### Verification of End State
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
# API works (port from MCP_PORT env var or default 3013)
|
|
54
|
-
curl -H "Authorization: Bearer $API_KEY" http://localhost:${MCP_PORT:-3013}/api/config?scope=global
|
|
55
|
-
curl -H "Authorization: Bearer $API_KEY" http://localhost:${MCP_PORT:-3013}/api/config/resolved?agentId=<uuid>
|
|
56
|
-
|
|
57
|
-
# Type check passes
|
|
58
|
-
bun run tsc:check
|
|
59
|
-
|
|
60
|
-
# Lint passes
|
|
61
|
-
bun run lint:fix
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
## Quick Verification Reference
|
|
65
|
-
|
|
66
|
-
Common commands:
|
|
67
|
-
- `bun run tsc:check` — TypeScript type checking
|
|
68
|
-
- `bun run lint:fix` — Biome lint + format
|
|
69
|
-
- `bun run start:http` — Start HTTP server (port 3013)
|
|
70
|
-
- `bun run dev:http` — Dev with hot reload
|
|
71
|
-
|
|
72
|
-
Key files to check:
|
|
73
|
-
- `src/be/db.ts` — Table + CRUD functions
|
|
74
|
-
- `src/http.ts` — REST API endpoints
|
|
75
|
-
- `src/types.ts` — Zod schemas
|
|
76
|
-
- `docker-entrypoint.sh` — Config injection
|
|
77
|
-
- `ui/src/components/ConfigPanel.tsx` — UI management
|
|
78
|
-
|
|
79
|
-
## What We're NOT Doing
|
|
80
|
-
|
|
81
|
-
- **Encryption at rest** — secrets stored as plain text in SQLite (per research decision #5)
|
|
82
|
-
- **Config versioning/history** — no audit trail for config changes
|
|
83
|
-
- **Config validation** — no schema validation on values (free-form text)
|
|
84
|
-
- **Real-time config push** — config is pulled at container start, not pushed via WebSocket
|
|
85
|
-
- **MCP tool for config** — agents access config via `process.env` (injected at container start), no dedicated MCP tool needed
|
|
86
|
-
- **Nested/hierarchical keys** — flat key-value only, no dotted key paths
|
|
87
|
-
- **Config from file import/export** — no bulk import from `.env` files into DB
|
|
88
|
-
|
|
89
|
-
## Implementation Approach
|
|
90
|
-
|
|
91
|
-
Four phases, each independently verifiable:
|
|
92
|
-
|
|
93
|
-
1. **DB + Types**: Schema, CRUD functions, Zod types
|
|
94
|
-
2. **REST API**: HTTP endpoints for CRUD + resolved config
|
|
95
|
-
3. **Docker Entrypoint**: Fetch resolved config and export as env vars at container start
|
|
96
|
-
4. **UI**: Config management tab in the dashboard
|
|
97
|
-
|
|
98
|
-
---
|
|
99
|
-
|
|
100
|
-
## Phase 1: Database Schema + CRUD Functions + Types
|
|
101
|
-
|
|
102
|
-
### Overview
|
|
103
|
-
|
|
104
|
-
Add the `swarm_config` table to SQLite, define the TypeScript types/Zod schemas, and implement all CRUD + resolution functions in `db.ts`.
|
|
105
|
-
|
|
106
|
-
### Changes Required:
|
|
107
|
-
|
|
108
|
-
#### 1. Zod Schema
|
|
109
|
-
**File**: `src/types.ts`
|
|
110
|
-
**Changes**: Add `SwarmConfigSchema` and related types after the existing schemas (~line 135):
|
|
111
|
-
|
|
112
|
-
```typescript
|
|
113
|
-
export const SwarmConfigSchema = z.object({
|
|
114
|
-
id: z.string().uuid(),
|
|
115
|
-
scope: z.enum(["global", "agent", "repo"]),
|
|
116
|
-
scopeId: z.string().nullable(), // agentId or repoId, null for global
|
|
117
|
-
key: z.string().min(1).max(255),
|
|
118
|
-
value: z.string(),
|
|
119
|
-
isSecret: z.boolean(),
|
|
120
|
-
envPath: z.string().nullable(),
|
|
121
|
-
description: z.string().nullable(),
|
|
122
|
-
createdAt: z.string(),
|
|
123
|
-
lastUpdatedAt: z.string(),
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
export type SwarmConfig = z.infer<typeof SwarmConfigSchema>;
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
#### 2. Database Table
|
|
130
|
-
**File**: `src/be/db.ts`
|
|
131
|
-
**Changes**: Add `CREATE TABLE IF NOT EXISTS swarm_config` inside the `initSchema` transaction (before the closing `}` at ~line 325). Add indexes for common queries.
|
|
132
|
-
|
|
133
|
-
```sql
|
|
134
|
-
CREATE TABLE IF NOT EXISTS swarm_config (
|
|
135
|
-
id TEXT PRIMARY KEY,
|
|
136
|
-
scope TEXT NOT NULL CHECK(scope IN ('global', 'agent', 'repo')),
|
|
137
|
-
scopeId TEXT,
|
|
138
|
-
key TEXT NOT NULL,
|
|
139
|
-
value TEXT NOT NULL,
|
|
140
|
-
isSecret INTEGER NOT NULL DEFAULT 0,
|
|
141
|
-
envPath TEXT,
|
|
142
|
-
description TEXT,
|
|
143
|
-
createdAt TEXT NOT NULL,
|
|
144
|
-
lastUpdatedAt TEXT NOT NULL,
|
|
145
|
-
UNIQUE(scope, scopeId, key)
|
|
146
|
-
)
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
Indexes:
|
|
150
|
-
```sql
|
|
151
|
-
CREATE INDEX IF NOT EXISTS idx_swarm_config_scope ON swarm_config(scope)
|
|
152
|
-
CREATE INDEX IF NOT EXISTS idx_swarm_config_scope_id ON swarm_config(scope, scopeId)
|
|
153
|
-
CREATE INDEX IF NOT EXISTS idx_swarm_config_key ON swarm_config(key)
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
#### 3. Row Type + Converter
|
|
157
|
-
**File**: `src/be/db.ts`
|
|
158
|
-
**Changes**: Add after existing row types (after the epics section):
|
|
159
|
-
|
|
160
|
-
```typescript
|
|
161
|
-
type SwarmConfigRow = {
|
|
162
|
-
id: string;
|
|
163
|
-
scope: string;
|
|
164
|
-
scopeId: string | null;
|
|
165
|
-
key: string;
|
|
166
|
-
value: string;
|
|
167
|
-
isSecret: number; // SQLite boolean
|
|
168
|
-
envPath: string | null;
|
|
169
|
-
description: string | null;
|
|
170
|
-
createdAt: string;
|
|
171
|
-
lastUpdatedAt: string;
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
function rowToSwarmConfig(row: SwarmConfigRow): SwarmConfig {
|
|
175
|
-
return {
|
|
176
|
-
id: row.id,
|
|
177
|
-
scope: row.scope as "global" | "agent" | "repo",
|
|
178
|
-
scopeId: row.scopeId ?? null,
|
|
179
|
-
key: row.key,
|
|
180
|
-
value: row.value,
|
|
181
|
-
isSecret: row.isSecret === 1,
|
|
182
|
-
envPath: row.envPath ?? null,
|
|
183
|
-
description: row.description ?? null,
|
|
184
|
-
createdAt: row.createdAt,
|
|
185
|
-
lastUpdatedAt: row.lastUpdatedAt,
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
#### 4. CRUD Functions
|
|
191
|
-
**File**: `src/be/db.ts`
|
|
192
|
-
**Changes**: Add exported functions following the existing pattern:
|
|
193
|
-
|
|
194
|
-
- `getSwarmConfigs(filters?: { scope?, scopeId?, key? }): SwarmConfig[]` — list with optional filters
|
|
195
|
-
- `getSwarmConfigById(id: string): SwarmConfig | null` — single by ID
|
|
196
|
-
- `upsertSwarmConfig(data: { scope, scopeId?, key, value, isSecret?, envPath?, description? }): SwarmConfig` — insert or update by (scope, scopeId, key) unique constraint
|
|
197
|
-
- `deleteSwarmConfig(id: string): boolean` — delete by ID
|
|
198
|
-
- `getResolvedConfig(agentId?: string, repoId?: string): SwarmConfig[]` — returns merged config with scope resolution (repo > agent > global). Returns one entry per key with the most-specific scope winning.
|
|
199
|
-
|
|
200
|
-
The `getResolvedConfig` function logic:
|
|
201
|
-
1. Fetch all `global` configs
|
|
202
|
-
2. If `agentId` provided, fetch all `agent` configs for that agent, overlay on global (same key = agent wins)
|
|
203
|
-
3. If `repoId` provided, fetch all `repo` configs for that repo, overlay on agent+global (same key = repo wins)
|
|
204
|
-
4. Return the merged set
|
|
205
|
-
|
|
206
|
-
#### 5. Secret Masking Helper
|
|
207
|
-
**File**: `src/be/db.ts`
|
|
208
|
-
**Changes**: Add a helper that masks secret values:
|
|
209
|
-
|
|
210
|
-
```typescript
|
|
211
|
-
export function maskSecrets(configs: SwarmConfig[]): SwarmConfig[] {
|
|
212
|
-
return configs.map(c => c.isSecret ? { ...c, value: "********" } : c);
|
|
213
|
-
}
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
#### 6. envPath Writer Helper
|
|
217
|
-
**File**: `src/be/db.ts`
|
|
218
|
-
**Changes**: Add a helper that writes config values to `.env` files when `envPath` is set. This is called by `upsertSwarmConfig` after successful DB write.
|
|
219
|
-
|
|
220
|
-
```typescript
|
|
221
|
-
function writeEnvFile(configs: SwarmConfig[]): void {
|
|
222
|
-
// Group configs by envPath
|
|
223
|
-
// For each envPath, read existing file, update/add matching keys, write back
|
|
224
|
-
// Skip if envPath is null
|
|
225
|
-
}
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
Note: The `envPath` writer only runs on the API server (where the DB lives). For Docker workers, the entrypoint fetches config and exports as env vars — the `envPath` feature is for the API server's own filesystem or shared volumes.
|
|
229
|
-
|
|
230
|
-
### Success Criteria:
|
|
231
|
-
|
|
232
|
-
#### Automated Verification:
|
|
233
|
-
- [x] Type check passes: `bun run tsc:check`
|
|
234
|
-
- [x] Lint passes: `bun run lint:fix`
|
|
235
|
-
- [x] Server starts without errors: `bun run start:http` (ctrl+c after startup)
|
|
236
|
-
- [x] Table exists: `sqlite3 agent-swarm-db.sqlite ".schema swarm_config"`
|
|
237
|
-
|
|
238
|
-
#### Manual Verification:
|
|
239
|
-
- [x] Start server, confirm no migration errors in console output
|
|
240
|
-
- [x] Verify the unique constraint works (try inserting duplicate scope+scopeId+key via DB directly)
|
|
241
|
-
|
|
242
|
-
**Implementation Note**: After completing this phase, pause for manual confirmation before proceeding.
|
|
243
|
-
|
|
244
|
-
---
|
|
245
|
-
|
|
246
|
-
## Phase 2: REST API Endpoints
|
|
247
|
-
|
|
248
|
-
### Overview
|
|
249
|
-
|
|
250
|
-
Add CRUD and resolved-config endpoints under `/api/config` in `http.ts`, following the existing routing and response patterns.
|
|
251
|
-
|
|
252
|
-
### Changes Required:
|
|
253
|
-
|
|
254
|
-
#### 1. Config Endpoints
|
|
255
|
-
**File**: `src/http.ts`
|
|
256
|
-
**Changes**: Add route blocks in the REST API section (after the scheduled-tasks endpoints, before the 404 fallback). Import new DB functions at the top of the file.
|
|
257
|
-
|
|
258
|
-
**Endpoints:**
|
|
259
|
-
|
|
260
|
-
| Method | Path | Query Params | Body | Response |
|
|
261
|
-
|--------|------|-------------|------|----------|
|
|
262
|
-
| GET | `/api/config` | `scope`, `scopeId`, `includeSecrets` | — | `{ configs: SwarmConfig[] }` |
|
|
263
|
-
| GET | `/api/config/resolved` | `agentId`, `repoId`, `includeSecrets` | — | `{ configs: SwarmConfig[] }` |
|
|
264
|
-
| GET | `/api/config/:id` | `includeSecrets` | — | `SwarmConfig` (unwrapped) |
|
|
265
|
-
| PUT | `/api/config` | — | `{ scope, scopeId?, key, value, isSecret?, envPath?, description? }` | `SwarmConfig` (upserted, 200/201) |
|
|
266
|
-
| DELETE | `/api/config/:id` | — | — | `{ success: true }` |
|
|
267
|
-
|
|
268
|
-
**Normal vs Resolved:**
|
|
269
|
-
- `GET /api/config?scope=global` — returns **raw entries** for a specific scope. No merging. Exactly what's stored in the DB. Used by the UI for CRUD management.
|
|
270
|
-
- `GET /api/config/resolved?agentId=X` — returns the **merged result** across all scopes (global + agent + repo), with scope resolution applied (most-specific wins). One entry per unique key. Used by the Docker entrypoint to get the final set of env vars for an agent.
|
|
271
|
-
|
|
272
|
-
**Route matching patterns:**
|
|
273
|
-
|
|
274
|
-
```
|
|
275
|
-
GET /api/config/resolved → pathSegments = ["api", "config", "resolved"] && !pathSegments[3]
|
|
276
|
-
GET /api/config/:id → pathSegments = ["api", "config", pathSegments[2]] && !pathSegments[3] && pathSegments[2] !== "resolved"
|
|
277
|
-
GET /api/config → pathSegments = ["api", "config"] && !pathSegments[2]
|
|
278
|
-
PUT /api/config → method === "PUT" && pathSegments = ["api", "config"] && !pathSegments[2]
|
|
279
|
-
DELETE /api/config/:id → method === "DELETE" && pathSegments = ["api", "config", pathSegments[2]] && !pathSegments[3]
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
**Important ordering**: The `GET /api/config/resolved` route MUST come before `GET /api/config/:id` since "resolved" would otherwise match as an `:id` parameter.
|
|
283
|
-
|
|
284
|
-
**Secret handling**: By default, `maskSecrets()` is applied to all responses. If `includeSecrets=true` query param is present, raw values are returned.
|
|
285
|
-
|
|
286
|
-
**PUT upsert logic**:
|
|
287
|
-
1. Parse body, validate required fields (`scope`, `key`, `value`)
|
|
288
|
-
2. Validate scope is one of `global`, `agent`, `repo`
|
|
289
|
-
3. If scope is `global`, ensure `scopeId` is null
|
|
290
|
-
4. If scope is `agent` or `repo`, require `scopeId`
|
|
291
|
-
5. Call `upsertSwarmConfig()` — returns the created/updated config
|
|
292
|
-
6. If `envPath` is set, trigger env file write
|
|
293
|
-
7. Return the config (masked if secret, unless `includeSecrets=true`)
|
|
294
|
-
|
|
295
|
-
### Success Criteria:
|
|
296
|
-
|
|
297
|
-
#### Automated Verification:
|
|
298
|
-
- [x] Type check passes: `bun run tsc:check`
|
|
299
|
-
- [x] Lint passes: `bun run lint:fix`
|
|
300
|
-
- [x] Create global config: `curl -s -X PUT -H "Authorization: Bearer 123123" -H "Content-Type: application/json" -d '{"scope":"global","key":"TEST_KEY","value":"test_value","description":"A test config"}' http://localhost:3013/api/config | jq .`
|
|
301
|
-
- [x] List global config: `curl -s -H "Authorization: Bearer 123123" "http://localhost:3013/api/config?scope=global" | jq .`
|
|
302
|
-
- [x] Create secret: `curl -s -X PUT -H "Authorization: Bearer 123123" -H "Content-Type: application/json" -d '{"scope":"global","key":"SECRET_KEY","value":"s3cret","isSecret":true}' http://localhost:3013/api/config | jq .`
|
|
303
|
-
- [x] Verify masking: `curl -s -H "Authorization: Bearer 123123" "http://localhost:3013/api/config?scope=global" | jq '.configs[] | select(.key == "SECRET_KEY") | .value'` — should return `"********"`
|
|
304
|
-
- [x] Verify reveal: `curl -s -H "Authorization: Bearer 123123" "http://localhost:3013/api/config?scope=global&includeSecrets=true" | jq '.configs[] | select(.key == "SECRET_KEY") | .value'` — should return `"s3cret"`
|
|
305
|
-
- [x] Get resolved config: `curl -s -H "Authorization: Bearer 123123" "http://localhost:3013/api/config/resolved" | jq .`
|
|
306
|
-
- [x] Delete config: `curl -s -X DELETE -H "Authorization: Bearer 123123" http://localhost:3013/api/config/<id> | jq .`
|
|
307
|
-
|
|
308
|
-
#### Manual Verification:
|
|
309
|
-
- [x] Test scope override: create a global key, then an agent-scoped key with the same name, verify resolved endpoint returns the agent-scoped value
|
|
310
|
-
- [x] Test upsert: PUT the same scope+scopeId+key twice with different values, verify only one entry exists with the updated value
|
|
311
|
-
- [x] Test validation: PUT with missing `key` field, verify 400 error
|
|
312
|
-
|
|
313
|
-
**Implementation Note**: After completing this phase, pause for manual confirmation before proceeding.
|
|
314
|
-
|
|
315
|
-
---
|
|
316
|
-
|
|
317
|
-
## Phase 3: Docker Entrypoint Integration
|
|
318
|
-
|
|
319
|
-
### Overview
|
|
320
|
-
|
|
321
|
-
Update the Docker entrypoint to fetch resolved config from the API and export as env vars at container start. This is the primary mechanism agents use to access config — via `process.env` in their Claude sessions.
|
|
322
|
-
|
|
323
|
-
### Changes Required:
|
|
324
|
-
|
|
325
|
-
#### 1. Docker Entrypoint Config Fetch
|
|
326
|
-
**File**: `docker-entrypoint.sh`
|
|
327
|
-
**Changes**: Add a config fetch step between the PM2 restoration (line 78) and MCP config creation (line 88). This position:
|
|
328
|
-
- Is after `MCP_URL` is computed (line 17)
|
|
329
|
-
- Is after `AGENT_ID` is available
|
|
330
|
-
- Is before the startup script (line 203), so config vars are available to startup scripts
|
|
331
|
-
- Is before the agent binary launch (line 352)
|
|
332
|
-
|
|
333
|
-
```bash
|
|
334
|
-
# ---- Fetch swarm config from API ----
|
|
335
|
-
if [ -n "$AGENT_ID" ]; then
|
|
336
|
-
echo "Fetching swarm config from API..."
|
|
337
|
-
if curl -s -f -H "Authorization: Bearer ${API_KEY}" \
|
|
338
|
-
-H "X-Agent-ID: ${AGENT_ID}" \
|
|
339
|
-
"${MCP_URL}/api/config/resolved?agentId=${AGENT_ID}&includeSecrets=true" \
|
|
340
|
-
> /tmp/swarm_config.json 2>/dev/null; then
|
|
341
|
-
|
|
342
|
-
CONFIG_COUNT=$(jq ‘.configs | length’ /tmp/swarm_config.json 2>/dev/null || echo "0")
|
|
343
|
-
if [ "$CONFIG_COUNT" -gt 0 ]; then
|
|
344
|
-
echo "Found $CONFIG_COUNT config entries, exporting as env vars..."
|
|
345
|
-
# Write key=value pairs to a temp env file (jq handles JSON escaping,
|
|
346
|
-
# we write raw values one per line). Then source it with set -a.
|
|
347
|
-
jq -r ‘.configs[] | "\(.key)=\(.value)"’ /tmp/swarm_config.json > /tmp/swarm_config.env 2>/dev/null || true
|
|
348
|
-
if [ -f /tmp/swarm_config.env ]; then
|
|
349
|
-
set -a
|
|
350
|
-
. /tmp/swarm_config.env
|
|
351
|
-
set +a
|
|
352
|
-
rm -f /tmp/swarm_config.env
|
|
353
|
-
fi
|
|
354
|
-
fi
|
|
355
|
-
rm -f /tmp/swarm_config.json
|
|
356
|
-
else
|
|
357
|
-
echo "Warning: Could not fetch swarm config (API may not be ready)"
|
|
358
|
-
fi
|
|
359
|
-
fi
|
|
360
|
-
# ---- End swarm config fetch ----
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
**Why `set -a` + `source` instead of `eval`**: The `eval` approach is vulnerable to shell injection — a config value containing shell metacharacters (e.g., `"; rm -rf /; "`) would execute arbitrary commands. The `source` approach with `set -a` (auto-export) treats each line as a literal `KEY=VALUE` assignment without shell interpretation of the value.
|
|
364
|
-
|
|
365
|
-
**Caveat**: Values containing newlines won’t work with this approach (the `.env` file format is one entry per line). If multi-line values are needed in the future, we’d need a different mechanism (e.g., base64-encode values or write a proper shell script with quoting). For now, single-line values cover all practical env var use cases.
|
|
366
|
-
|
|
367
|
-
DB config unconditionally overwrites any existing env vars. This is intentional — DB-managed config is the source of truth. If a Docker env var and a DB config key collide, the DB value wins.
|
|
368
|
-
|
|
369
|
-
### Success Criteria:
|
|
370
|
-
|
|
371
|
-
#### Automated Verification:
|
|
372
|
-
- [x] Entrypoint syntax is valid: `bash -n docker-entrypoint.sh`
|
|
373
|
-
- [x] Lint passes: `bun run lint:fix`
|
|
374
|
-
|
|
375
|
-
#### Manual Verification:
|
|
376
|
-
- [ ] If Docker environment available: build worker image, start container with some config in DB, verify env vars are exported (check with `env | grep <KEY>` inside the container)
|
|
377
|
-
- [ ] Verify that config entries with secrets are exported with their actual values (not masked)
|
|
378
|
-
|
|
379
|
-
**Implementation Note**: After completing this phase, pause for manual confirmation before proceeding. Docker testing may require `bun run docker:build:worker` if available.
|
|
380
|
-
|
|
381
|
-
---
|
|
382
|
-
|
|
383
|
-
## Phase 4: UI Config Management Page
|
|
384
|
-
|
|
385
|
-
### Overview
|
|
386
|
-
|
|
387
|
-
Add a "CONFIG" tab to the dashboard with sub-tabs for Global, Per-Agent, and Per-Repo config management. Each sub-tab shows a table of config entries with add/edit/delete capabilities.
|
|
388
|
-
|
|
389
|
-
### Changes Required:
|
|
390
|
-
|
|
391
|
-
#### 1. API Client Methods
|
|
392
|
-
**File**: `ui/src/lib/api.ts`
|
|
393
|
-
**Changes**: Add methods to `ApiClient`:
|
|
394
|
-
|
|
395
|
-
```typescript
|
|
396
|
-
// Config API methods
|
|
397
|
-
async getConfigs(filters?: { scope?: string; scopeId?: string; includeSecrets?: boolean }): Promise<{ configs: SwarmConfig[] }>
|
|
398
|
-
async getResolvedConfig(params?: { agentId?: string; repoId?: string; includeSecrets?: boolean }): Promise<{ configs: SwarmConfig[] }>
|
|
399
|
-
async upsertConfig(data: { scope: string; scopeId?: string; key: string; value: string; isSecret?: boolean; envPath?: string; description?: string }): Promise<SwarmConfig>
|
|
400
|
-
async deleteConfig(id: string): Promise<{ success: boolean }>
|
|
401
|
-
```
|
|
402
|
-
|
|
403
|
-
#### 2. TypeScript Types
|
|
404
|
-
**File**: `ui/src/types/api.ts`
|
|
405
|
-
**Changes**: Add `SwarmConfig` interface matching the API response shape.
|
|
406
|
-
|
|
407
|
-
#### 3. React Query Hooks
|
|
408
|
-
**File**: `ui/src/hooks/queries.ts`
|
|
409
|
-
**Changes**: Add hooks:
|
|
410
|
-
|
|
411
|
-
```typescript
|
|
412
|
-
export function useConfigs(filters?: { scope?: string; scopeId?: string })
|
|
413
|
-
export function useResolvedConfig(params?: { agentId?: string; repoId?: string })
|
|
414
|
-
export function useUpsertConfig() // useMutation
|
|
415
|
-
export function useDeleteConfig() // useMutation
|
|
416
|
-
```
|
|
417
|
-
|
|
418
|
-
#### 4. Config Panel Component
|
|
419
|
-
**File**: `ui/src/components/ConfigPanel.tsx` (new file)
|
|
420
|
-
**Changes**: Create a panel with:
|
|
421
|
-
|
|
422
|
-
- **Sub-tabs**: Global | Per-Agent | Per-Repo (using nested MUI Joy `Tabs`)
|
|
423
|
-
- **Global tab**: Table of all global configs. Add button opens an inline form or modal.
|
|
424
|
-
- **Per-Agent tab**: Dropdown to select an agent, then table of that agent's configs.
|
|
425
|
-
- **Per-Repo tab**: Text input for repo ID (or dropdown if repos are tracked), then table.
|
|
426
|
-
- **Table columns**: Key, Value (masked for secrets with reveal toggle), Description, envPath, Actions (edit/delete)
|
|
427
|
-
- **Add/Edit form**: Key (text), Value (text/password for secrets), isSecret (checkbox), envPath (optional text), Description (optional text)
|
|
428
|
-
- **Delete**: Confirmation before delete
|
|
429
|
-
|
|
430
|
-
Follow existing panel patterns:
|
|
431
|
-
- `Card variant="outlined"` wrapper
|
|
432
|
-
- Hex accent icon in header
|
|
433
|
-
- Beehive theme colors via local `colors` object
|
|
434
|
-
- MUI Joy components: `Table`, `Input`, `Button`, `IconButton`, `Checkbox`, `Select`, `Option`
|
|
435
|
-
|
|
436
|
-
#### 5. Dashboard Integration
|
|
437
|
-
**File**: `ui/src/components/Dashboard.tsx`
|
|
438
|
-
**Changes**:
|
|
439
|
-
|
|
440
|
-
1. Add `"config"` to the `activeTab` type and URL param handling
|
|
441
|
-
2. Add `<Tab value="config">CONFIG</Tab>` in the TabList
|
|
442
|
-
3. Add `<TabPanel value="config">` with the `ConfigPanel` component
|
|
443
|
-
4. Add a case in `handleTabChange` for `"config"` that clears unrelated selections
|
|
444
|
-
5. Optionally: change the Header settings gear to navigate to the config tab instead of (or in addition to) opening the ConfigModal
|
|
445
|
-
|
|
446
|
-
#### 6. Redirect Settings Gear (optional)
|
|
447
|
-
**File**: `ui/src/components/Header.tsx`
|
|
448
|
-
**Changes**: The gear icon currently opens the ConfigModal (for API URL/key). We could:
|
|
449
|
-
- Keep ConfigModal as-is (it configures the dashboard's own connection)
|
|
450
|
-
- Add a separate "Swarm Config" button or link that navigates to the config tab
|
|
451
|
-
- Or: move the API connection settings into the config tab as well
|
|
452
|
-
|
|
453
|
-
Recommendation: Keep the gear icon opening ConfigModal (it's dashboard-specific local config). The new CONFIG tab is for swarm-wide env config. They serve different purposes.
|
|
454
|
-
|
|
455
|
-
### Success Criteria:
|
|
456
|
-
|
|
457
|
-
#### Automated Verification:
|
|
458
|
-
- [x] UI type check passes: `cd ui && bun run tsc` (or equivalent)
|
|
459
|
-
- [x] UI builds without errors: `cd ui && bun run build`
|
|
460
|
-
- [x] Lint passes: `bun run lint:fix`
|
|
461
|
-
|
|
462
|
-
#### Manual Verification:
|
|
463
|
-
- [ ] Navigate to CONFIG tab in the dashboard
|
|
464
|
-
- [ ] Global sub-tab: add a config entry, verify it appears in the table
|
|
465
|
-
- [ ] Add a secret: verify value is masked, click reveal to see it
|
|
466
|
-
- [ ] Per-Agent sub-tab: select an agent, add agent-scoped config
|
|
467
|
-
- [ ] Edit an existing config entry (change value), verify update
|
|
468
|
-
- [ ] Delete a config entry, verify removal
|
|
469
|
-
- [ ] Verify responsive layout on mobile (table should scroll or collapse)
|
|
470
|
-
|
|
471
|
-
**Implementation Note**: After completing this phase, pause for manual confirmation.
|
|
472
|
-
|
|
473
|
-
---
|
|
474
|
-
|
|
475
|
-
## Manual E2E Verification
|
|
476
|
-
|
|
477
|
-
After all phases are complete, run these commands to verify the full feature end-to-end:
|
|
478
|
-
|
|
479
|
-
```bash
|
|
480
|
-
# 1. Start the server
|
|
481
|
-
bun run start:http
|
|
482
|
-
|
|
483
|
-
# 2. Create global config entries
|
|
484
|
-
curl -s -X PUT -H "Authorization: Bearer 123123" \
|
|
485
|
-
-H "Content-Type: application/json" \
|
|
486
|
-
-d '{"scope":"global","key":"OPENAI_API_KEY","value":"sk-test-123","isSecret":true,"description":"OpenAI API key for embeddings"}' \
|
|
487
|
-
http://localhost:3013/api/config | jq .
|
|
488
|
-
|
|
489
|
-
curl -s -X PUT -H "Authorization: Bearer 123123" \
|
|
490
|
-
-H "Content-Type: application/json" \
|
|
491
|
-
-d '{"scope":"global","key":"DEFAULT_BRANCH","value":"main","description":"Default git branch"}' \
|
|
492
|
-
http://localhost:3013/api/config | jq .
|
|
493
|
-
|
|
494
|
-
# 3. Create agent-scoped config (use a real agent ID from your swarm)
|
|
495
|
-
AGENT_ID="<your-agent-id>"
|
|
496
|
-
curl -s -X PUT -H "Authorization: Bearer 123123" \
|
|
497
|
-
-H "Content-Type: application/json" \
|
|
498
|
-
-d "{\"scope\":\"agent\",\"scopeId\":\"${AGENT_ID}\",\"key\":\"DEFAULT_BRANCH\",\"value\":\"develop\",\"description\":\"Agent prefers develop branch\"}" \
|
|
499
|
-
http://localhost:3013/api/config | jq .
|
|
500
|
-
|
|
501
|
-
# 4. Verify scope resolution (agent overrides global for DEFAULT_BRANCH)
|
|
502
|
-
curl -s -H "Authorization: Bearer 123123" \
|
|
503
|
-
"http://localhost:3013/api/config/resolved?agentId=${AGENT_ID}" | jq .
|
|
504
|
-
# Expected: DEFAULT_BRANCH=develop (agent), OPENAI_API_KEY=******** (global, masked)
|
|
505
|
-
|
|
506
|
-
# 5. Verify secret reveal
|
|
507
|
-
curl -s -H "Authorization: Bearer 123123" \
|
|
508
|
-
"http://localhost:3013/api/config/resolved?agentId=${AGENT_ID}&includeSecrets=true" | jq .
|
|
509
|
-
# Expected: OPENAI_API_KEY=sk-test-123 (revealed)
|
|
510
|
-
|
|
511
|
-
# 6. List all global config
|
|
512
|
-
curl -s -H "Authorization: Bearer 123123" \
|
|
513
|
-
"http://localhost:3013/api/config?scope=global" | jq .
|
|
514
|
-
|
|
515
|
-
# 7. Delete a config entry
|
|
516
|
-
CONFIG_ID="<id-from-step-2>"
|
|
517
|
-
curl -s -X DELETE -H "Authorization: Bearer 123123" \
|
|
518
|
-
"http://localhost:3013/api/config/${CONFIG_ID}" | jq .
|
|
519
|
-
|
|
520
|
-
# 8. Open UI dashboard, navigate to CONFIG tab, verify entries are visible
|
|
521
|
-
open http://localhost:5274 # or wherever the UI is served
|
|
522
|
-
|
|
523
|
-
# 9. (If Docker available) Test entrypoint integration
|
|
524
|
-
# Build worker image, start with AGENT_ID set, verify env vars appear
|
|
525
|
-
```
|
|
526
|
-
|
|
527
|
-
## Testing Strategy
|
|
528
|
-
|
|
529
|
-
- **No unit tests in this phase**: The codebase does not have an established test suite pattern. Focus on manual verification via curl commands and UI interaction.
|
|
530
|
-
- **Type safety**: `bun run tsc:check` catches schema mismatches between DB functions and API handlers.
|
|
531
|
-
- **Lint**: `bun run lint:fix` ensures code style consistency.
|
|
532
|
-
- **Integration testing**: The curl commands in each phase's verification section serve as integration tests.
|
|
533
|
-
|
|
534
|
-
## References
|
|
535
|
-
|
|
536
|
-
- Research: `thoughts/taras/research/2026-02-19-swarm-gaps-implementation.md` (Gap 6 section, lines 333-383)
|
|
537
|
-
- Architecture: `thoughts/taras/research/2026-02-19-agent-native-swarm-architecture.md`
|
|
538
|
-
- Previous CLAUDE.md work: `thoughts/taras/research/2026-01-28-per-worker-claude-md.md`
|