@desplega.ai/agent-swarm 1.20.0 → 1.51.2
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 +271 -169
- package/openapi.json +5015 -0
- package/package.json +40 -7
- package/plugin/commands/close-issue.md +7 -3
- package/plugin/commands/create-pr.md +18 -12
- package/plugin/commands/implement-issue.md +7 -3
- package/plugin/commands/respond-github.md +8 -4
- package/plugin/commands/review-pr.md +44 -10
- package/plugin/commands/start-leader.md +1 -3
- package/plugin/commands/start-worker.md +1 -3
- package/plugin/commands/work-on-task.md +22 -3
- package/plugin/pi-skills/close-issue/SKILL.md +90 -0
- package/plugin/pi-skills/create-pr/SKILL.md +99 -0
- package/plugin/pi-skills/implement-issue/SKILL.md +135 -0
- package/plugin/pi-skills/investigate-sentry-issue/SKILL.md +138 -0
- package/plugin/pi-skills/respond-github/SKILL.md +98 -0
- package/plugin/pi-skills/review-offered-task/SKILL.md +45 -0
- package/plugin/pi-skills/review-pr/SKILL.md +261 -0
- package/plugin/pi-skills/start-leader/SKILL.md +121 -0
- package/plugin/pi-skills/start-worker/SKILL.md +60 -0
- package/plugin/pi-skills/swarm-chat/SKILL.md +82 -0
- package/plugin/pi-skills/todos/SKILL.md +66 -0
- package/plugin/pi-skills/work-on-task/SKILL.md +65 -0
- package/plugin/skills/artifacts/examples/approval-flow.ts +34 -0
- package/plugin/skills/artifacts/examples/hono-dashboard.ts +31 -0
- package/plugin/skills/artifacts/examples/multi-artifact.ts +20 -0
- package/plugin/skills/artifacts/examples/static-report.sh +17 -0
- package/plugin/skills/artifacts/skill.md +71 -0
- package/src/agentmail/app.ts +65 -0
- package/src/agentmail/handlers.ts +262 -0
- package/src/agentmail/index.ts +9 -0
- package/src/agentmail/templates.ts +111 -0
- package/src/agentmail/types.ts +51 -0
- package/src/artifact-sdk/browser-sdk.ts +30 -0
- package/src/artifact-sdk/index.ts +2 -0
- package/src/artifact-sdk/localtunnel.d.ts +20 -0
- package/src/artifact-sdk/port.ts +12 -0
- package/src/artifact-sdk/server.ts +156 -0
- package/src/artifact-sdk/tunnel.ts +19 -0
- package/src/be/chunking.ts +193 -0
- package/src/be/db-queries/oauth.ts +90 -0
- package/src/be/db-queries/tracker.ts +182 -0
- package/src/be/db.ts +3327 -784
- package/src/be/embedding.ts +80 -0
- package/src/be/migrations/001_initial.sql +409 -0
- package/src/be/migrations/002_one_time_schedules.sql +59 -0
- package/src/be/migrations/003_workflows.sql +51 -0
- package/src/be/migrations/004_workflow_source.sql +81 -0
- package/src/be/migrations/005_epic_next_steps.sql +2 -0
- package/src/be/migrations/006_vcs_provider.sql +94 -0
- package/src/be/migrations/007_task_dir.sql +2 -0
- package/src/be/migrations/008_workflow_redesign.sql +85 -0
- package/src/be/migrations/009_tracker_integration.sql +144 -0
- package/src/be/migrations/010_step_diagnostics.sql +1 -0
- package/src/be/migrations/011_step_next_port.sql +1 -0
- package/src/be/migrations/012_trigger_schema.sql +1 -0
- package/src/be/migrations/013_task_output_schema.sql +2 -0
- 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/runner.ts +188 -0
- package/src/be/seed.ts +62 -0
- package/src/cli.tsx +231 -299
- package/src/commands/artifact.ts +241 -0
- package/src/commands/onboard/compose-generator.ts +169 -0
- package/src/commands/onboard/env-generator.ts +79 -0
- package/src/commands/onboard/manifest.ts +37 -0
- package/src/commands/onboard/presets.ts +85 -0
- package/src/commands/onboard/service-names.ts +47 -0
- package/src/commands/onboard/steps/core-credentials.tsx +111 -0
- package/src/commands/onboard/steps/custom-templates.tsx +168 -0
- package/src/commands/onboard/steps/generate.tsx +154 -0
- package/src/commands/onboard/steps/harness-credentials.tsx +195 -0
- package/src/commands/onboard/steps/harness.tsx +21 -0
- package/src/commands/onboard/steps/health-check.tsx +171 -0
- package/src/commands/onboard/steps/integration-github.tsx +105 -0
- package/src/commands/onboard/steps/integration-gitlab.tsx +79 -0
- package/src/commands/onboard/steps/integration-menu.tsx +58 -0
- package/src/commands/onboard/steps/integration-sentry.tsx +79 -0
- package/src/commands/onboard/steps/integration-slack.tsx +165 -0
- package/src/commands/onboard/steps/post-connect.tsx +145 -0
- package/src/commands/onboard/steps/post-dashboard.tsx +34 -0
- package/src/commands/onboard/steps/post-task.tsx +103 -0
- package/src/commands/onboard/steps/prereq-check.tsx +178 -0
- package/src/commands/onboard/steps/review.tsx +82 -0
- package/src/commands/onboard/steps/start.tsx +97 -0
- package/src/commands/onboard/templates.ts +34 -0
- package/src/commands/onboard/types.ts +259 -0
- package/src/commands/onboard.tsx +425 -0
- package/src/commands/runner.ts +1540 -630
- package/src/commands/setup.tsx +23 -38
- package/src/commands/shared/client-config.ts +41 -0
- package/src/commands/templates.ts +172 -0
- package/src/github/app.ts +8 -0
- package/src/github/handlers.ts +384 -151
- package/src/github/index.ts +1 -0
- 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/github/types.ts +1 -0
- package/src/gitlab/auth.ts +63 -0
- package/src/gitlab/handlers.ts +368 -0
- package/src/gitlab/index.ts +19 -0
- package/src/gitlab/reactions.ts +104 -0
- package/src/gitlab/templates.ts +140 -0
- package/src/gitlab/types.ts +130 -0
- package/src/heartbeat/heartbeat.ts +434 -0
- package/src/heartbeat/index.ts +1 -0
- package/src/heartbeat/templates.ts +30 -0
- package/src/hooks/hook.ts +555 -4
- package/src/hooks/tool-loop-detection.test.ts +158 -0
- package/src/hooks/tool-loop-detection.ts +167 -0
- package/src/http/active-sessions.ts +199 -0
- package/src/http/agents.ts +328 -0
- package/src/http/config.ts +191 -0
- package/src/http/core.ts +309 -0
- package/src/http/db-query.ts +91 -0
- package/src/http/ecosystem.ts +63 -0
- package/src/http/epics.ts +460 -0
- package/src/http/index.ts +216 -0
- package/src/http/mcp.ts +77 -0
- package/src/http/memory.ts +168 -0
- package/src/http/openapi.ts +109 -0
- package/src/http/poll.ts +299 -0
- package/src/http/prompt-templates.ts +412 -0
- package/src/http/repos.ts +195 -0
- package/src/http/route-def.ts +123 -0
- package/src/http/schedules.ts +426 -0
- package/src/http/session-data.ts +241 -0
- package/src/http/stats.ts +174 -0
- package/src/http/tasks.ts +468 -0
- package/src/http/trackers/index.ts +10 -0
- package/src/http/trackers/linear.ts +187 -0
- package/src/http/types.ts +12 -0
- package/src/http/utils.ts +87 -0
- package/src/http/webhooks.ts +432 -0
- package/src/http/workflows.ts +530 -0
- package/src/http.ts +1 -1890
- package/src/linear/README.md +65 -0
- package/src/linear/app.ts +48 -0
- package/src/linear/client.ts +18 -0
- package/src/linear/index.ts +1 -0
- package/src/linear/oauth.ts +35 -0
- package/src/linear/outbound.ts +212 -0
- package/src/linear/sync.ts +567 -0
- package/src/linear/templates.ts +47 -0
- package/src/linear/types.ts +7 -0
- package/src/linear/webhook.ts +104 -0
- package/src/oauth/README.md +66 -0
- package/src/oauth/index.ts +6 -0
- package/src/oauth/wrapper.ts +204 -0
- package/src/prompts/base-prompt.ts +150 -265
- package/src/prompts/defaults.ts +196 -0
- 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 +442 -0
- package/src/providers/index.ts +24 -0
- package/src/providers/pi-mono-adapter.ts +442 -0
- package/src/providers/pi-mono-extension.ts +624 -0
- package/src/providers/pi-mono-mcp-client.ts +124 -0
- package/src/providers/types.ts +75 -0
- package/src/scheduler/scheduler.test.ts +2 -0
- package/src/scheduler/scheduler.ts +231 -40
- package/src/server.ts +97 -6
- package/src/slack/HEURISTICS.md +105 -0
- package/src/slack/actions.ts +133 -0
- package/src/slack/app.ts +7 -0
- package/src/slack/assistant.ts +118 -0
- package/src/slack/blocks.ts +233 -0
- package/src/slack/channel-activity.ts +177 -0
- package/src/slack/commands.ts +31 -17
- package/src/slack/files.ts +1 -1
- package/src/slack/handlers.test.ts +114 -1
- package/src/slack/handlers.ts +230 -55
- package/src/slack/responses.ts +120 -67
- package/src/slack/router.ts +17 -99
- package/src/slack/templates.ts +55 -0
- package/src/slack/thread-buffer.ts +213 -0
- package/src/slack/watcher.ts +119 -4
- package/src/tests/agent-activity.test.ts +247 -0
- package/src/tests/agentmail-filters.test.ts +97 -0
- package/src/tests/artifact-sdk.test.ts +800 -0
- package/src/tests/base-prompt.test.ts +264 -0
- package/src/tests/build-pi-skills.test.ts +127 -0
- package/src/tests/channel-activity.test.ts +363 -0
- package/src/tests/claude-adapter.test.ts +126 -0
- package/src/tests/context-versioning.test.ts +425 -0
- package/src/tests/db-queries-oauth.test.ts +197 -0
- package/src/tests/db-queries-tracker.test.ts +230 -0
- package/src/tests/epics.test.ts +3 -3
- package/src/tests/error-tracker.test.ts +368 -0
- package/src/tests/fetch-resolved-env.test.ts +167 -0
- package/src/tests/generate-default-claude-md.test.ts +9 -1
- package/src/tests/generate-identity-templates.test.ts +124 -0
- package/src/tests/gitlab-auth.test.ts +109 -0
- package/src/tests/gitlab-handlers.test.ts +691 -0
- package/src/tests/gitlab-vcs-db.test.ts +177 -0
- package/src/tests/heartbeat.test.ts +364 -0
- package/src/tests/http-api-integration.test.ts +1698 -0
- package/src/tests/linear-outbound-sync.test.ts +200 -0
- package/src/tests/linear-webhook.test.ts +406 -0
- package/src/tests/match-route.test.ts +187 -0
- package/src/tests/memory.test.ts +737 -0
- package/src/tests/migration-runner-regressions.test.ts +86 -0
- package/src/tests/model-control.test.ts +338 -0
- package/src/tests/oauth-wrapper.test.ts +147 -0
- package/src/tests/onboard-compose.test.ts +138 -0
- package/src/tests/onboard-env.test.ts +174 -0
- package/src/tests/onboard-manifest.test.ts +137 -0
- package/src/tests/pi-mono-adapter.test.ts +234 -0
- package/src/tests/pool-session-logs.test.ts +199 -0
- package/src/tests/progress-dedup.test.ts +98 -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/provider-adapter.test.ts +122 -0
- package/src/tests/provider-command-format.test.ts +98 -0
- package/src/tests/reload-config.test.ts +170 -0
- package/src/tests/runner-polling-api.test.ts +25 -20
- package/src/tests/scheduled-tasks.test.ts +104 -0
- package/src/tests/scheduler-backoff.test.ts +166 -0
- package/src/tests/self-improvement.test.ts +541 -0
- package/src/tests/session-attach.test.ts +536 -0
- package/src/tests/session-costs.test.ts +267 -1
- package/src/tests/slack-actions.test.ts +133 -0
- package/src/tests/slack-assistant.test.ts +136 -0
- package/src/tests/slack-blocks.test.ts +246 -0
- package/src/tests/slack-metadata-inheritance.test.ts +243 -0
- package/src/tests/slack-queue-offline.test.ts +174 -0
- package/src/tests/slack-router.test.ts +181 -0
- package/src/tests/slack-thread-buffer.test.ts +305 -0
- package/src/tests/slack-thread-followups.test.ts +298 -0
- package/src/tests/slack-watcher.test.ts +101 -0
- package/src/tests/structured-output.test.ts +307 -0
- package/src/tests/swarm-repos.test.ts +198 -0
- package/src/tests/task-cancellation.test.ts +6 -4
- package/src/tests/task-working-dir.test.ts +176 -0
- package/src/tests/template-fetch.test.ts +490 -0
- package/src/tests/tool-annotations.test.ts +371 -0
- package/src/tests/tracker-tools.test.ts +184 -0
- package/src/tests/update-profile-agentid.test.ts +248 -0
- package/src/tests/update-profile-api.test.ts +143 -3
- package/src/tests/update-profile-auth.test.ts +195 -0
- package/src/tests/validation-adapters.test.ts +86 -0
- package/src/tests/vcs-provider.test.ts +27 -0
- package/src/tests/workflow-agent-task.test.ts +196 -0
- package/src/tests/workflow-async-v2.test.ts +508 -0
- package/src/tests/workflow-convergence.test.ts +541 -0
- package/src/tests/workflow-definition-validation.test.ts +366 -0
- package/src/tests/workflow-engine-v2.test.ts +691 -0
- package/src/tests/workflow-executors.test.ts +736 -0
- package/src/tests/workflow-http-v2.test.ts +599 -0
- package/src/tests/workflow-integration-io.test.ts +902 -0
- package/src/tests/workflow-io-schemas.test.ts +624 -0
- package/src/tests/workflow-registry.test.ts +592 -0
- package/src/tests/workflow-retry-v2.test.ts +401 -0
- package/src/tests/workflow-retry-validation.test.ts +282 -0
- package/src/tests/workflow-schedule-trigger.test.ts +104 -0
- package/src/tests/workflow-template.test.ts +288 -0
- package/src/tests/workflow-trigger-schema.test.ts +359 -0
- package/src/tests/workflow-triggers-v2.test.ts +264 -0
- package/src/tests/workflow-versions.test.ts +208 -0
- package/src/tests/workflow-workspace.test.ts +272 -0
- package/src/tests/x402-client.test.ts +117 -0
- package/src/tests/x402-config.test.ts +182 -0
- package/src/tests/x402-spending-tracker.test.ts +185 -0
- package/src/tools/cancel-task.ts +2 -0
- package/src/tools/context-diff.ts +171 -0
- package/src/tools/context-history.ts +138 -0
- package/src/tools/create-channel.ts +1 -0
- package/src/tools/db-query.ts +78 -0
- package/src/tools/delete-channel.ts +132 -0
- package/src/tools/epics/assign-task-to-epic.ts +1 -0
- package/src/tools/epics/create-epic.ts +3 -2
- package/src/tools/epics/delete-epic.ts +2 -0
- package/src/tools/epics/get-epic-details.ts +2 -0
- package/src/tools/epics/list-epics.ts +2 -0
- package/src/tools/epics/unassign-task-from-epic.ts +1 -0
- package/src/tools/epics/update-epic.ts +7 -4
- package/src/tools/get-swarm.ts +2 -0
- package/src/tools/get-task-details.ts +2 -0
- package/src/tools/get-tasks.ts +27 -1
- package/src/tools/inject-learning.ts +106 -0
- package/src/tools/join-swarm.ts +17 -7
- package/src/tools/list-channels.ts +2 -0
- package/src/tools/list-services.ts +2 -0
- package/src/tools/memory-get.ts +56 -0
- package/src/tools/memory-search.ts +131 -0
- package/src/tools/my-agent-info.ts +2 -0
- package/src/tools/poll-task.ts +2 -20
- package/src/tools/post-message.ts +1 -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/read-messages.ts +2 -0
- package/src/tools/register-agentmail-inbox.ts +166 -0
- package/src/tools/register-service.ts +2 -0
- package/src/tools/schedules/create-schedule.ts +134 -24
- package/src/tools/schedules/delete-schedule.ts +2 -0
- package/src/tools/schedules/list-schedules.ts +20 -4
- package/src/tools/schedules/run-schedule-now.ts +1 -0
- package/src/tools/schedules/update-schedule.ts +49 -17
- package/src/tools/send-task.ts +132 -10
- package/src/tools/slack-download-file.ts +4 -2
- package/src/tools/slack-list-channels.ts +2 -0
- package/src/tools/slack-post.ts +2 -0
- package/src/tools/slack-read.ts +2 -0
- package/src/tools/slack-reply.ts +2 -0
- package/src/tools/slack-upload-file.ts +2 -0
- package/src/tools/store-progress.ts +205 -4
- package/src/tools/swarm-config/delete-config.ts +87 -0
- package/src/tools/swarm-config/get-config.ts +108 -0
- package/src/tools/swarm-config/index.ts +4 -0
- package/src/tools/swarm-config/list-config.ts +99 -0
- package/src/tools/swarm-config/set-config.ts +118 -0
- package/src/tools/task-action.ts +50 -5
- package/src/tools/task-dedup.ts +97 -0
- package/src/tools/templates.ts +53 -0
- package/src/tools/tool-config.ts +124 -0
- package/src/tools/tracker/index.ts +6 -0
- package/src/tools/tracker/tracker-link-epic.ts +64 -0
- package/src/tools/tracker/tracker-link-task.ts +64 -0
- package/src/tools/tracker/tracker-map-agent.ts +57 -0
- package/src/tools/tracker/tracker-status.ts +56 -0
- package/src/tools/tracker/tracker-sync-status.ts +42 -0
- package/src/tools/tracker/tracker-unlink.ts +41 -0
- package/src/tools/unregister-service.ts +2 -0
- package/src/tools/update-profile.ts +172 -17
- package/src/tools/update-service-status.ts +2 -0
- package/src/tools/utils.ts +10 -1
- package/src/tools/workflows/create-workflow.ts +129 -0
- package/src/tools/workflows/delete-workflow.ts +42 -0
- package/src/tools/workflows/get-workflow-run.ts +59 -0
- package/src/tools/workflows/get-workflow.ts +53 -0
- package/src/tools/workflows/index.ts +9 -0
- package/src/tools/workflows/list-workflow-runs.ts +48 -0
- package/src/tools/workflows/list-workflows.ts +42 -0
- package/src/tools/workflows/retry-workflow-run.ts +40 -0
- package/src/tools/workflows/trigger-workflow.ts +96 -0
- package/src/tools/workflows/update-workflow.ts +133 -0
- package/src/tracker/types.ts +51 -0
- package/src/types.ts +530 -14
- package/src/utils/credentials.test.ts +156 -0
- package/src/utils/credentials.ts +50 -0
- package/src/utils/error-tracker.ts +190 -0
- package/src/vcs/index.ts +15 -0
- package/src/vcs/types.ts +5 -0
- package/src/workflows/checkpoint.ts +121 -0
- package/src/workflows/cooldown.ts +28 -0
- package/src/workflows/definition.ts +235 -0
- package/src/workflows/engine.ts +580 -0
- package/src/workflows/event-bus.ts +29 -0
- package/src/workflows/executors/agent-task.ts +103 -0
- package/src/workflows/executors/base.ts +86 -0
- package/src/workflows/executors/code-match.ts +88 -0
- package/src/workflows/executors/index.ts +16 -0
- package/src/workflows/executors/notify.ts +93 -0
- package/src/workflows/executors/property-match.ts +104 -0
- package/src/workflows/executors/raw-llm.ts +83 -0
- package/src/workflows/executors/registry.ts +76 -0
- package/src/workflows/executors/script.ts +103 -0
- package/src/workflows/executors/validate.ts +215 -0
- package/src/workflows/executors/vcs.ts +58 -0
- package/src/workflows/index.ts +61 -0
- package/src/workflows/input.ts +46 -0
- package/src/workflows/json-schema-validator.ts +118 -0
- package/src/workflows/recovery.ts +139 -0
- package/src/workflows/resume.ts +229 -0
- package/src/workflows/retry-poller.ts +216 -0
- package/src/workflows/template.ts +74 -0
- package/src/workflows/templates.ts +86 -0
- package/src/workflows/triggers.ts +124 -0
- package/src/workflows/validation.ts +104 -0
- package/src/workflows/version.ts +44 -0
- package/src/x402/cli.ts +140 -0
- package/src/x402/client.ts +192 -0
- package/src/x402/config.ts +131 -0
- package/src/x402/index.ts +37 -0
- package/src/x402/openfort-signer.ts +83 -0
- package/src/x402/spending-tracker.ts +109 -0
- package/templates/official/coder/CLAUDE.md +49 -0
- package/templates/official/coder/IDENTITY.md +28 -0
- package/templates/official/coder/SOUL.md +43 -0
- package/templates/official/coder/TOOLS.md +40 -0
- package/templates/official/coder/config.json +23 -0
- package/templates/official/coder/start-up.sh +23 -0
- package/templates/official/content-reviewer/CLAUDE.md +68 -0
- package/templates/official/content-reviewer/IDENTITY.md +28 -0
- package/templates/official/content-reviewer/SOUL.md +44 -0
- package/templates/official/content-reviewer/TOOLS.md +37 -0
- package/templates/official/content-reviewer/config.json +23 -0
- package/templates/official/content-reviewer/start-up.sh +23 -0
- package/templates/official/content-strategist/CLAUDE.md +63 -0
- package/templates/official/content-strategist/IDENTITY.md +33 -0
- package/templates/official/content-strategist/SOUL.md +48 -0
- package/templates/official/content-strategist/TOOLS.md +47 -0
- package/templates/official/content-strategist/config.json +23 -0
- package/templates/official/content-strategist/start-up.sh +23 -0
- package/templates/official/content-writer/CLAUDE.md +72 -0
- package/templates/official/content-writer/IDENTITY.md +30 -0
- package/templates/official/content-writer/SOUL.md +46 -0
- package/templates/official/content-writer/TOOLS.md +44 -0
- package/templates/official/content-writer/config.json +23 -0
- package/templates/official/content-writer/start-up.sh +23 -0
- package/templates/official/forward-deployed-engineer/CLAUDE.md +54 -0
- package/templates/official/forward-deployed-engineer/IDENTITY.md +37 -0
- package/templates/official/forward-deployed-engineer/SOUL.md +55 -0
- package/templates/official/forward-deployed-engineer/config.json +21 -0
- package/templates/official/lead/CLAUDE.md +33 -0
- package/templates/official/lead/IDENTITY.md +36 -0
- package/templates/official/lead/SOUL.md +51 -0
- package/templates/official/lead/config.json +22 -0
- package/templates/official/researcher/CLAUDE.md +46 -0
- package/templates/official/researcher/IDENTITY.md +28 -0
- package/templates/official/researcher/SOUL.md +43 -0
- package/templates/official/researcher/config.json +21 -0
- package/templates/official/reviewer/CLAUDE.md +63 -0
- package/templates/official/reviewer/IDENTITY.md +28 -0
- package/templates/official/reviewer/SOUL.md +45 -0
- package/templates/official/reviewer/config.json +21 -0
- package/templates/official/tester/CLAUDE.md +53 -0
- package/templates/official/tester/IDENTITY.md +28 -0
- package/templates/official/tester/SOUL.md +55 -0
- package/templates/official/tester/config.json +21 -0
- package/templates/schema.ts +35 -0
- package/.claude/settings.local.json +0 -115
- package/.dockerignore +0 -61
- package/.editorconfig +0 -15
- package/.env.docker.example +0 -39
- package/.env.example +0 -40
- package/.github/workflows/ci.yml +0 -76
- package/.github/workflows/docker-and-deploy.yml +0 -117
- package/.wts-config.json +0 -4
- package/.wts-setup.ts +0 -102
- package/CLAUDE.md +0 -104
- package/CONTRIBUTING.md +0 -270
- package/DEPLOYMENT.md +0 -605
- package/Dockerfile +0 -57
- package/Dockerfile.worker +0 -157
- package/FAQ.md +0 -19
- package/MCP.md +0 -406
- package/UI.md +0 -40
- 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/docker-compose.example.yml +0 -159
- package/docker-entrypoint.sh +0 -352
- package/ecosystem.config.cjs +0 -66
- package/plugin/README.md +0 -1
- package/plugin/hooks/hooks.json +0 -71
- package/pyproject.toml +0 -9
- package/scripts/generate-mcp-docs.ts +0 -415
- package/slack-manifest.json +0 -71
- package/src/tests/get-inbox-message.test.ts +0 -145
- package/src/tools/get-inbox-message.ts +0 -89
- package/src/tools/inbox-delegate.ts +0 -113
- 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/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/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/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/tsconfig.json +0 -37
- package/ui/CLAUDE.md +0 -49
- package/ui/bun.lock +0 -771
- package/ui/index.html +0 -22
- package/ui/package-lock.json +0 -5290
- package/ui/package.json +0 -33
- package/ui/pnpm-lock.yaml +0 -3341
- package/ui/postcss.config.js +0 -6
- package/ui/public/logo.png +0 -0
- package/ui/src/App.tsx +0 -63
- package/ui/src/components/ActivityFeed.tsx +0 -440
- package/ui/src/components/AgentDetailPanel.tsx +0 -733
- package/ui/src/components/AgentsPanel.tsx +0 -815
- package/ui/src/components/ChatPanel.tsx +0 -1920
- package/ui/src/components/ConfigModal.tsx +0 -253
- package/ui/src/components/Dashboard.tsx +0 -832
- package/ui/src/components/EditAgentProfileModal.tsx +0 -433
- package/ui/src/components/EpicDetailPage.tsx +0 -741
- package/ui/src/components/EpicsPanel.tsx +0 -566
- package/ui/src/components/Header.tsx +0 -160
- package/ui/src/components/JsonViewer.tsx +0 -171
- package/ui/src/components/ScheduledTaskDetailPanel.tsx +0 -517
- package/ui/src/components/ScheduledTasksPanel.tsx +0 -639
- package/ui/src/components/ServicesPanel.tsx +0 -622
- package/ui/src/components/SessionLogPanel.tsx +0 -1219
- package/ui/src/components/StatsBar.tsx +0 -321
- package/ui/src/components/StatusBadge.tsx +0 -168
- package/ui/src/components/TaskDetailPanel.tsx +0 -903
- package/ui/src/components/TasksPanel.tsx +0 -614
- package/ui/src/components/UsageCharts.tsx +0 -216
- package/ui/src/components/UsageTab.tsx +0 -394
- package/ui/src/hooks/queries.ts +0 -353
- package/ui/src/hooks/useAutoScroll.ts +0 -83
- package/ui/src/index.css +0 -257
- package/ui/src/lib/api.ts +0 -268
- package/ui/src/lib/config.ts +0 -35
- package/ui/src/lib/contentPreview.ts +0 -208
- package/ui/src/lib/theme.ts +0 -214
- package/ui/src/lib/utils.ts +0 -88
- package/ui/src/main.tsx +0 -28
- package/ui/src/types/api.ts +0 -323
- package/ui/src/vite-env.d.ts +0 -1
- package/ui/tailwind.config.js +0 -37
- package/ui/tsconfig.json +0 -31
- package/ui/vite.config.ts +0 -35
- /package/{thoughts/shared/plans → templates/community}/.gitkeep +0 -0
|
@@ -1,311 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
date: 2026-01-27T09:30:00Z
|
|
3
|
-
topic: "Excessive Agent Polling Consuming Credits"
|
|
4
|
-
author: Claude
|
|
5
|
-
status: complete
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Research: Excessive Agent Polling Consuming Credits
|
|
9
|
-
|
|
10
|
-
**Issue**: Workers continuously polling for tasks at full capacity, consuming excessive API credits
|
|
11
|
-
|
|
12
|
-
## Problem Description
|
|
13
|
-
|
|
14
|
-
From the production logs, workers are stuck in a tight loop:
|
|
15
|
-
1. All 3 workers are at capacity (3/3)
|
|
16
|
-
2. Each worker keeps calling `poll-task` MCP tool every ~1-2 seconds
|
|
17
|
-
3. Each poll returns `success: false` (no task available)
|
|
18
|
-
4. Workers immediately poll again
|
|
19
|
-
5. This continues indefinitely until SIGTERM
|
|
20
|
-
|
|
21
|
-
## Root Cause Analysis
|
|
22
|
-
|
|
23
|
-
### The Core Problem
|
|
24
|
-
|
|
25
|
-
**File**: `src/tools/poll-task.ts:197`
|
|
26
|
-
|
|
27
|
-
When a Claude instance calls `poll-task` and no task is found after the 60-second timeout, it returns:
|
|
28
|
-
|
|
29
|
-
```typescript
|
|
30
|
-
message: `No task assigned within the polling duration, please keep polling until a task is assigned.`,
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
**This message explicitly instructs Claude to keep polling**, creating an infinite loop where:
|
|
34
|
-
1. Claude calls `poll-task`
|
|
35
|
-
2. Waits up to 60 seconds (line 17: `MAX_POLL_DURATION_MS = 1 * 60 * 1000`)
|
|
36
|
-
3. Gets "no task, please keep polling"
|
|
37
|
-
4. Calls `poll-task` again immediately
|
|
38
|
-
5. Repeat forever
|
|
39
|
-
|
|
40
|
-
Each `poll-task` call is an API request that consumes credits.
|
|
41
|
-
|
|
42
|
-
### Why This Happens
|
|
43
|
-
|
|
44
|
-
Looking at the logs:
|
|
45
|
-
|
|
46
|
-
```
|
|
47
|
-
✓ Result: {"content":"{\"yourAgentId\":\"16990304...\"success\":false,\"message...
|
|
48
|
-
▶ Tool: agent-swarm:poll-task
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
The Claude instances are **inside** the workers, actively running and calling `poll-task` repeatedly. This means:
|
|
52
|
-
|
|
53
|
-
1. A schedule or trigger spawns 3 Claude instances
|
|
54
|
-
2. Each Claude instance is instructed to "poll for tasks"
|
|
55
|
-
3. When no tasks are assigned, they follow the instruction to "keep polling"
|
|
56
|
-
4. All 3 keep polling indefinitely
|
|
57
|
-
|
|
58
|
-
### The Two Polling Layers
|
|
59
|
-
|
|
60
|
-
There are **two separate mechanisms** at play:
|
|
61
|
-
|
|
62
|
-
#### 1. Runner-Level Polling (Not the main problem)
|
|
63
|
-
|
|
64
|
-
**File**: `src/commands/runner.ts:1558-1563`
|
|
65
|
-
|
|
66
|
-
When agents are at capacity, the runner logs every second but doesn't make expensive API calls:
|
|
67
|
-
|
|
68
|
-
```typescript
|
|
69
|
-
} else {
|
|
70
|
-
console.log(`[${role}] At capacity (${state.activeTasks.size}/${state.maxConcurrent}), waiting for completion...`);
|
|
71
|
-
await Bun.sleep(1000); // Fixed 1-second sleep
|
|
72
|
-
}
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
#### 2. Claude Instance Polling (THE PROBLEM)
|
|
76
|
-
|
|
77
|
-
**File**: `src/tools/poll-task.ts`
|
|
78
|
-
|
|
79
|
-
The poll-task MCP tool that Claude instances call repeatedly. Each call:
|
|
80
|
-
- Makes an API request (credits consumed)
|
|
81
|
-
- Waits up to 60 seconds internally polling the DB every 2 seconds
|
|
82
|
-
- Returns "keep polling" message on timeout
|
|
83
|
-
- Claude immediately calls again
|
|
84
|
-
|
|
85
|
-
## The Core Issues
|
|
86
|
-
|
|
87
|
-
### Issue 1: poll-task Encourages Infinite Polling
|
|
88
|
-
|
|
89
|
-
The message "please keep polling until a task is assigned" is problematic. If an agent is spawned without a task, it will poll forever.
|
|
90
|
-
|
|
91
|
-
**Location**: `src/tools/poll-task.ts:197`
|
|
92
|
-
|
|
93
|
-
### Issue 2: No Exit Condition for Idle Agents
|
|
94
|
-
|
|
95
|
-
There's no mechanism for a Claude instance to gracefully exit when:
|
|
96
|
-
- No task is found after N attempts
|
|
97
|
-
- No task is assigned within a reasonable timeout
|
|
98
|
-
- Agent capacity is already saturated
|
|
99
|
-
|
|
100
|
-
### Issue 3: No Backoff on Empty Poll
|
|
101
|
-
|
|
102
|
-
The poll-task tool doesn't implement any backoff when no tasks are available. It polls every 2 seconds for 60 seconds, then immediately restarts.
|
|
103
|
-
|
|
104
|
-
**Location**: `src/tools/poll-task.ts:181` - `DEFAULT_POLL_INTERVAL_MS = 2000`
|
|
105
|
-
|
|
106
|
-
## Proposed Solution: Block Response After Max Empty Polls
|
|
107
|
-
|
|
108
|
-
Use the existing hook "block" mechanism (same as task cancellation) to enforce a strict exit condition.
|
|
109
|
-
|
|
110
|
-
### Implementation Plan
|
|
111
|
-
|
|
112
|
-
#### 1. Add Poll Tracking to Agent Schema
|
|
113
|
-
|
|
114
|
-
**File**: `src/types.ts`
|
|
115
|
-
|
|
116
|
-
Add new field to `AgentSchema`:
|
|
117
|
-
```typescript
|
|
118
|
-
// Poll tracking for exit enforcement (consecutive empty polls)
|
|
119
|
-
emptyPollCount: z.number().int().min(0).default(0),
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
#### 2. Add Database Migration
|
|
123
|
-
|
|
124
|
-
**File**: `src/be/db.ts`
|
|
125
|
-
|
|
126
|
-
Add migration:
|
|
127
|
-
```typescript
|
|
128
|
-
try {
|
|
129
|
-
db.run(`ALTER TABLE agents ADD COLUMN emptyPollCount INTEGER DEFAULT 0`);
|
|
130
|
-
} catch {
|
|
131
|
-
/* exists */
|
|
132
|
-
}
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
#### 3. Add DB Functions for Poll Tracking
|
|
136
|
-
|
|
137
|
-
**File**: `src/be/db.ts`
|
|
138
|
-
|
|
139
|
-
```typescript
|
|
140
|
-
const MAX_EMPTY_POLLS = 2; // After 2 consecutive empty polls, agent should exit
|
|
141
|
-
|
|
142
|
-
export function incrementEmptyPollCount(agentId: string): number {
|
|
143
|
-
const row = getDb()
|
|
144
|
-
.prepare<{ emptyPollCount: number }, [string]>(
|
|
145
|
-
`UPDATE agents
|
|
146
|
-
SET emptyPollCount = emptyPollCount + 1,
|
|
147
|
-
lastUpdatedAt = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
|
148
|
-
WHERE id = ?
|
|
149
|
-
RETURNING emptyPollCount`
|
|
150
|
-
)
|
|
151
|
-
.get(agentId);
|
|
152
|
-
return row?.emptyPollCount ?? 0;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
export function resetEmptyPollCount(agentId: string): void {
|
|
156
|
-
getDb().run(
|
|
157
|
-
`UPDATE agents
|
|
158
|
-
SET emptyPollCount = 0,
|
|
159
|
-
lastUpdatedAt = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
|
160
|
-
WHERE id = ?`,
|
|
161
|
-
[agentId]
|
|
162
|
-
);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
export function shouldBlockPolling(agentId: string): boolean {
|
|
166
|
-
const agent = getAgentById(agentId);
|
|
167
|
-
return (agent?.emptyPollCount ?? 0) >= MAX_EMPTY_POLLS;
|
|
168
|
-
}
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
#### 4. Modify poll-task Tool
|
|
172
|
-
|
|
173
|
-
**File**: `src/tools/poll-task.ts`
|
|
174
|
-
|
|
175
|
-
When no task is found:
|
|
176
|
-
```typescript
|
|
177
|
-
// Increment empty poll count
|
|
178
|
-
const newCount = incrementEmptyPollCount(agentId);
|
|
179
|
-
const shouldExit = newCount >= MAX_EMPTY_POLLS;
|
|
180
|
-
|
|
181
|
-
return {
|
|
182
|
-
content: [
|
|
183
|
-
{
|
|
184
|
-
type: "text",
|
|
185
|
-
text: shouldExit
|
|
186
|
-
? `No task assigned after ${newCount} polling attempts. EXIT NOW - do not poll again.`
|
|
187
|
-
: `No task assigned within the polling duration (${waitedForSeconds}s).`,
|
|
188
|
-
},
|
|
189
|
-
],
|
|
190
|
-
structuredContent: {
|
|
191
|
-
yourAgentId: requestInfo.agentId,
|
|
192
|
-
success: false,
|
|
193
|
-
message: shouldExit
|
|
194
|
-
? `Polling limit reached (${newCount}/${MAX_EMPTY_POLLS}). You must exit now.`
|
|
195
|
-
: `No task assigned within the polling duration.`,
|
|
196
|
-
shouldExit,
|
|
197
|
-
emptyPollCount: newCount,
|
|
198
|
-
offeredTasks: [],
|
|
199
|
-
availableCount: getUnassignedTasksCount(),
|
|
200
|
-
waitedForSeconds,
|
|
201
|
-
},
|
|
202
|
-
};
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
When task IS found, reset the counter:
|
|
206
|
-
```typescript
|
|
207
|
-
if (startedTask) {
|
|
208
|
-
resetEmptyPollCount(agentId); // Reset on successful task assignment
|
|
209
|
-
// ... rest of success response
|
|
210
|
-
}
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
#### 5. Add Server Endpoint for Hook Check
|
|
214
|
-
|
|
215
|
-
**File**: `src/http.ts`
|
|
216
|
-
|
|
217
|
-
Add to `/me` response or create new endpoint:
|
|
218
|
-
```typescript
|
|
219
|
-
// In GET /me handler, add:
|
|
220
|
-
shouldBlockPolling: shouldBlockPolling(agentId),
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
#### 6. Modify Hook to Block poll-task
|
|
224
|
-
|
|
225
|
-
**File**: `src/hooks/hook.ts`
|
|
226
|
-
|
|
227
|
-
In PreToolUse handler:
|
|
228
|
-
```typescript
|
|
229
|
-
case "PreToolUse": {
|
|
230
|
-
// Check for task cancellation (existing code)
|
|
231
|
-
if (agentInfo && !agentInfo.isLead && agentInfo.status === "busy") {
|
|
232
|
-
if (await checkAndBlockIfCancelled(true)) {
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// NEW: Check if agent should stop polling
|
|
238
|
-
if (msg.tool_name?.endsWith("poll-task")) {
|
|
239
|
-
const shouldBlock = await checkShouldBlockPolling();
|
|
240
|
-
if (shouldBlock) {
|
|
241
|
-
outputBlockResponse(
|
|
242
|
-
`🛑 POLLING LIMIT REACHED: You have exceeded the maximum empty poll attempts. ` +
|
|
243
|
-
`EXIT NOW - do not make any more tool calls. ` +
|
|
244
|
-
`If you have a task in progress, complete it first. Otherwise, exit immediately.`
|
|
245
|
-
);
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
break;
|
|
250
|
-
}
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
Add helper function:
|
|
254
|
-
```typescript
|
|
255
|
-
const checkShouldBlockPolling = async (): Promise<boolean> => {
|
|
256
|
-
if (!mcpConfig) return false;
|
|
257
|
-
|
|
258
|
-
try {
|
|
259
|
-
const resp = await fetch(`${getBaseUrl()}/me`, {
|
|
260
|
-
method: "GET",
|
|
261
|
-
headers: mcpConfig.headers,
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
if (!resp.ok) return false;
|
|
265
|
-
|
|
266
|
-
const data = await resp.json();
|
|
267
|
-
return data.shouldBlockPolling === true;
|
|
268
|
-
} catch {
|
|
269
|
-
return false;
|
|
270
|
-
}
|
|
271
|
-
};
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
## Files to Modify
|
|
275
|
-
|
|
276
|
-
| File | Change |
|
|
277
|
-
|------|--------|
|
|
278
|
-
| `src/types.ts` | Add `emptyPollCount` to AgentSchema |
|
|
279
|
-
| `src/be/db.ts` | Add migration + poll tracking functions |
|
|
280
|
-
| `src/tools/poll-task.ts` | Track polls, return `shouldExit` flag |
|
|
281
|
-
| `src/http.ts` | Add `shouldBlockPolling` to /me response |
|
|
282
|
-
| `src/hooks/hook.ts` | Block poll-task when limit reached |
|
|
283
|
-
|
|
284
|
-
## Constants
|
|
285
|
-
|
|
286
|
-
```typescript
|
|
287
|
-
const MAX_EMPTY_POLLS = 2; // After 2 consecutive empty polls (each ~60s), exit
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
This means an agent will poll for up to ~2 minutes before being forced to exit, which is reasonable for detecting "no work available" while not being too aggressive.
|
|
291
|
-
|
|
292
|
-
## Alternative Approaches Considered
|
|
293
|
-
|
|
294
|
-
1. **Message-only approach**: Just change the message to say "exit now" - but Claude might ignore it
|
|
295
|
-
2. **Exponential backoff**: Increase poll interval - but doesn't solve the core issue of infinite polling
|
|
296
|
-
3. **Single poll only**: Exit after first empty poll - too aggressive, might miss tasks that arrive shortly after
|
|
297
|
-
|
|
298
|
-
## Why Block Response is Best
|
|
299
|
-
|
|
300
|
-
The block response approach:
|
|
301
|
-
- **Server-enforced**: Can't be ignored by Claude
|
|
302
|
-
- **Uses existing mechanism**: Same pattern as task cancellation
|
|
303
|
-
- **Graceful**: Allows 2 attempts before blocking
|
|
304
|
-
- **Clear**: Explicit block with reason, not a suggestion
|
|
305
|
-
|
|
306
|
-
## Testing Plan
|
|
307
|
-
|
|
308
|
-
1. Deploy with MAX_EMPTY_POLLS = 2
|
|
309
|
-
2. Monitor agent exits after 2 empty polls
|
|
310
|
-
3. Verify counter resets when tasks are assigned
|
|
311
|
-
4. Check that the block response actually prevents further calls
|
|
@@ -1,383 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
date: 2026-01-28T14:52:00Z
|
|
3
|
-
topic: "Per-Worker CLAUDE.md Implementation"
|
|
4
|
-
researcher: Claude (Opus 4.5)
|
|
5
|
-
git_branch: main
|
|
6
|
-
status: complete
|
|
7
|
-
tags:
|
|
8
|
-
- agents
|
|
9
|
-
- configuration
|
|
10
|
-
- CLAUDE.md
|
|
11
|
-
- workers
|
|
12
|
-
- database
|
|
13
|
-
- UI
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
# Per-Worker CLAUDE.md Implementation Research
|
|
17
|
-
|
|
18
|
-
## Research Question
|
|
19
|
-
|
|
20
|
-
How to implement per-worker CLAUDE.md files that are:
|
|
21
|
-
1. Stored in the database per agent
|
|
22
|
-
2. Controllable from the UI
|
|
23
|
-
3. Contain default worker info (name, description, capabilities)
|
|
24
|
-
4. Modifiable by agents themselves
|
|
25
|
-
5. Loaded automatically when `claude` command starts (to `~/.claude/CLAUDE.md`)
|
|
26
|
-
6. Synced back to DB (via watch or on-end mechanism)
|
|
27
|
-
7. Include a unified note: "If you need to remember something write it down here"
|
|
28
|
-
|
|
29
|
-
---
|
|
30
|
-
|
|
31
|
-
## Summary
|
|
32
|
-
|
|
33
|
-
The agent-swarm codebase currently has no `claude_md` field in the agents table, but has all the infrastructure needed to implement this feature. The implementation requires:
|
|
34
|
-
|
|
35
|
-
1. **Database changes**: Add `claudeMd TEXT` column to `agents` table
|
|
36
|
-
2. **API changes**: Extend profile update endpoints to include `claudeMd`
|
|
37
|
-
3. **Hook changes**: On `SessionStart`, write agent's CLAUDE.md to `~/.claude/CLAUDE.md`
|
|
38
|
-
4. **MCP tool changes**: Add ability for agents to update their own CLAUDE.md
|
|
39
|
-
5. **UI changes**: Add CLAUDE.md editor in `EditAgentProfileModal`
|
|
40
|
-
6. **Sync mechanism**: On `Stop` hook, read `~/.claude/CLAUDE.md` and sync back to DB
|
|
41
|
-
|
|
42
|
-
---
|
|
43
|
-
|
|
44
|
-
## Detailed Findings
|
|
45
|
-
|
|
46
|
-
### 1. Current Agent Schema
|
|
47
|
-
|
|
48
|
-
**File:** `src/be/db.ts:48-59` (table creation) and `src/be/db.ts:467-495` (migrations)
|
|
49
|
-
|
|
50
|
-
Current `agents` table columns:
|
|
51
|
-
| Column | Type | Purpose |
|
|
52
|
-
|--------|------|---------|
|
|
53
|
-
| `id` | TEXT PRIMARY KEY | UUID |
|
|
54
|
-
| `name` | TEXT NOT NULL | Agent name |
|
|
55
|
-
| `isLead` | INTEGER DEFAULT 0 | Boolean flag |
|
|
56
|
-
| `status` | TEXT NOT NULL | 'idle', 'busy', 'offline' |
|
|
57
|
-
| `description` | TEXT | Free-form description |
|
|
58
|
-
| `role` | TEXT | Role label (max 100 chars) |
|
|
59
|
-
| `capabilities` | TEXT DEFAULT '[]' | JSON array |
|
|
60
|
-
| `maxTasks` | INTEGER DEFAULT 1 | Concurrency limit |
|
|
61
|
-
| `emptyPollCount` | INTEGER DEFAULT 0 | Polling tracking |
|
|
62
|
-
| `createdAt` | TEXT NOT NULL | ISO datetime |
|
|
63
|
-
| `lastUpdatedAt` | TEXT NOT NULL | ISO datetime |
|
|
64
|
-
|
|
65
|
-
**No `claudeMd` field exists yet.**
|
|
66
|
-
|
|
67
|
-
---
|
|
68
|
-
|
|
69
|
-
### 2. Agent Profile Update Mechanism
|
|
70
|
-
|
|
71
|
-
**MCP Tool:** `src/tools/update-profile.ts:1-132`
|
|
72
|
-
- Currently supports: `name`, `description`, `role`, `capabilities`
|
|
73
|
-
- Uses `updateAgentProfile()` from `src/be/db.ts:2117-2147`
|
|
74
|
-
|
|
75
|
-
**HTTP API:** `src/http.ts:968` - `PUT /api/agents/:id/profile`
|
|
76
|
-
- Same fields as MCP tool
|
|
77
|
-
|
|
78
|
-
**DB Function:** `src/be/db.ts:2117-2147`
|
|
79
|
-
```sql
|
|
80
|
-
UPDATE agents SET
|
|
81
|
-
description = COALESCE(?, description),
|
|
82
|
-
role = COALESCE(?, role),
|
|
83
|
-
capabilities = COALESCE(?, capabilities),
|
|
84
|
-
lastUpdatedAt = ?
|
|
85
|
-
WHERE id = ? RETURNING *
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
### 3. Hook System (Key Integration Point)
|
|
91
|
-
|
|
92
|
-
**File:** `src/hooks/hook.ts`
|
|
93
|
-
|
|
94
|
-
The hook receives events via stdin JSON and outputs to stdout. Key events:
|
|
95
|
-
|
|
96
|
-
| Event | Line | Current Behavior | Proposed Use |
|
|
97
|
-
|-------|------|------------------|--------------|
|
|
98
|
-
| `SessionStart` | 421-426 | Outputs agent status | **Load CLAUDE.md to ~/.claude/CLAUDE.md** |
|
|
99
|
-
| `Stop` | 484-501 | Marks agent offline | **Sync CLAUDE.md back to DB** |
|
|
100
|
-
|
|
101
|
-
**Current SessionStart handling (line 391-418):**
|
|
102
|
-
```typescript
|
|
103
|
-
if (agentInfo) {
|
|
104
|
-
console.log(`You are registered as ${agentInfo.isLead ? "lead" : "worker"} agent...`);
|
|
105
|
-
// ... system tray output
|
|
106
|
-
}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
This is where we'd add CLAUDE.md file writing.
|
|
110
|
-
|
|
111
|
-
---
|
|
112
|
-
|
|
113
|
-
### 4. Worker Spawning Flow
|
|
114
|
-
|
|
115
|
-
**File:** `src/commands/runner.ts`
|
|
116
|
-
|
|
117
|
-
1. Worker starts via `runAgent()` at line 1268
|
|
118
|
-
2. Registers with API at lines 1369-1382
|
|
119
|
-
3. Enters polling loop at line 1476
|
|
120
|
-
4. On trigger, spawns Claude with `Bun.spawn()` at line 1009-1016
|
|
121
|
-
5. Claude invokes hooks via stdin/stdout
|
|
122
|
-
|
|
123
|
-
**System prompt injection:** Currently uses `--append-system-prompt` flag (line 987):
|
|
124
|
-
```typescript
|
|
125
|
-
if (opts.systemPrompt) {
|
|
126
|
-
Cmd.push("--append-system-prompt", opts.systemPrompt);
|
|
127
|
-
}
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
However, Claude Code also reads `~/.claude/CLAUDE.md` automatically, which is what we want to leverage.
|
|
131
|
-
|
|
132
|
-
---
|
|
133
|
-
|
|
134
|
-
### 5. UI Components for Agent Management
|
|
135
|
-
|
|
136
|
-
**Edit Modal:** `ui/src/components/EditAgentProfileModal.tsx`
|
|
137
|
-
- Currently handles: role, description, capabilities
|
|
138
|
-
- Would need to add CLAUDE.md textarea
|
|
139
|
-
|
|
140
|
-
**API Client:** `ui/src/lib/api.ts:71-86`
|
|
141
|
-
```typescript
|
|
142
|
-
async updateAgentProfile(
|
|
143
|
-
id: string,
|
|
144
|
-
profile: { role?: string; description?: string; capabilities?: string[] },
|
|
145
|
-
): Promise<AgentWithTasks>
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
**React Query Hook:** `ui/src/hooks/queries.ts:34`
|
|
149
|
-
```typescript
|
|
150
|
-
export function useUpdateAgentProfile() {
|
|
151
|
-
// mutation for profile updates
|
|
152
|
-
}
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
---
|
|
156
|
-
|
|
157
|
-
### 6. ~/.claude/CLAUDE.md Location
|
|
158
|
-
|
|
159
|
-
Claude Code reads from `~/.claude/CLAUDE.md` as global instructions. The hook has access to:
|
|
160
|
-
- `process.env.HOME` for user's home directory
|
|
161
|
-
- Full filesystem access via Bun APIs
|
|
162
|
-
|
|
163
|
-
---
|
|
164
|
-
|
|
165
|
-
## Code References
|
|
166
|
-
|
|
167
|
-
| Component | File | Line(s) |
|
|
168
|
-
|-----------|------|---------|
|
|
169
|
-
| Agents table schema | `src/be/db.ts` | 48-59 |
|
|
170
|
-
| Agent migrations | `src/be/db.ts` | 467-495 |
|
|
171
|
-
| updateAgentProfile DB | `src/be/db.ts` | 2117-2147 |
|
|
172
|
-
| update-profile MCP tool | `src/tools/update-profile.ts` | 1-132 |
|
|
173
|
-
| join-swarm MCP tool | `src/tools/join-swarm.ts` | 1-139 |
|
|
174
|
-
| HTTP profile endpoint | `src/http.ts` | 968 |
|
|
175
|
-
| Hook handler | `src/hooks/hook.ts` | 105-506 |
|
|
176
|
-
| SessionStart hook | `src/hooks/hook.ts` | 421-426 |
|
|
177
|
-
| Stop hook | `src/hooks/hook.ts` | 484-501 |
|
|
178
|
-
| Worker runner | `src/commands/runner.ts` | 1268-1629 |
|
|
179
|
-
| UI edit modal | `ui/src/components/EditAgentProfileModal.tsx` | 27 |
|
|
180
|
-
| UI API client | `ui/src/lib/api.ts` | 71-86 |
|
|
181
|
-
| Agent type definition | `src/types.ts` | 113-132 |
|
|
182
|
-
|
|
183
|
-
---
|
|
184
|
-
|
|
185
|
-
## Implementation Recommendations
|
|
186
|
-
|
|
187
|
-
### Phase 1: Database & API Layer
|
|
188
|
-
|
|
189
|
-
1. **Add migration in `src/be/db.ts`:**
|
|
190
|
-
```typescript
|
|
191
|
-
try {
|
|
192
|
-
db.run(`ALTER TABLE agents ADD COLUMN claudeMd TEXT`);
|
|
193
|
-
} catch { /* exists */ }
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
2. **Update TypeScript types in `src/types.ts`:**
|
|
197
|
-
```typescript
|
|
198
|
-
export const AgentSchema = z.object({
|
|
199
|
-
// ... existing fields
|
|
200
|
-
claudeMd: z.string().optional(),
|
|
201
|
-
});
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
3. **Extend `updateAgentProfile()` in `src/be/db.ts`:**
|
|
205
|
-
```sql
|
|
206
|
-
UPDATE agents SET
|
|
207
|
-
description = COALESCE(?, description),
|
|
208
|
-
role = COALESCE(?, role),
|
|
209
|
-
capabilities = COALESCE(?, capabilities),
|
|
210
|
-
claudeMd = COALESCE(?, claudeMd),
|
|
211
|
-
lastUpdatedAt = ?
|
|
212
|
-
WHERE id = ? RETURNING *
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
4. **Update `update-profile` tool in `src/tools/update-profile.ts`:**
|
|
216
|
-
- Add `claudeMd: z.string().optional()` to input schema
|
|
217
|
-
|
|
218
|
-
5. **Update HTTP endpoint in `src/http.ts`:**
|
|
219
|
-
- Add `claudeMd` to accepted body fields in `PUT /api/agents/:id/profile`
|
|
220
|
-
|
|
221
|
-
### Phase 2: CLAUDE.md Loading (Hook)
|
|
222
|
-
|
|
223
|
-
Modify `src/hooks/hook.ts` in the `SessionStart` handler:
|
|
224
|
-
|
|
225
|
-
```typescript
|
|
226
|
-
case "SessionStart":
|
|
227
|
-
if (agentInfo) {
|
|
228
|
-
// Existing status output...
|
|
229
|
-
|
|
230
|
-
// Write agent's CLAUDE.md to ~/.claude/CLAUDE.md
|
|
231
|
-
if (agentInfo.claudeMd) {
|
|
232
|
-
const claudeMdPath = `${process.env.HOME}/.claude/CLAUDE.md`;
|
|
233
|
-
await Bun.write(claudeMdPath, agentInfo.claudeMd);
|
|
234
|
-
console.log(`Loaded your personal CLAUDE.md configuration.`);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
break;
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
Note: Need to fetch full agent info including `claudeMd` field in `getAgentInfo()`.
|
|
241
|
-
|
|
242
|
-
### Phase 3: CLAUDE.md Sync Back
|
|
243
|
-
|
|
244
|
-
On `Stop` hook, read the file and sync to DB:
|
|
245
|
-
|
|
246
|
-
```typescript
|
|
247
|
-
case "Stop":
|
|
248
|
-
// Existing PM2 save...
|
|
249
|
-
|
|
250
|
-
// Sync CLAUDE.md back to database
|
|
251
|
-
const claudeMdPath = `${process.env.HOME}/.claude/CLAUDE.md`;
|
|
252
|
-
try {
|
|
253
|
-
const file = Bun.file(claudeMdPath);
|
|
254
|
-
if (await file.exists()) {
|
|
255
|
-
const content = await file.text();
|
|
256
|
-
await syncClaudeMdToDb(agentInfo.id, content);
|
|
257
|
-
}
|
|
258
|
-
} catch { /* ignore */ }
|
|
259
|
-
|
|
260
|
-
await close();
|
|
261
|
-
break;
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
New helper function:
|
|
265
|
-
```typescript
|
|
266
|
-
async function syncClaudeMdToDb(agentId: string, content: string): Promise<void> {
|
|
267
|
-
if (!mcpConfig) return;
|
|
268
|
-
await fetch(`${getBaseUrl()}/api/agents/${agentId}/claude-md`, {
|
|
269
|
-
method: "PUT",
|
|
270
|
-
headers: { ...mcpConfig.headers, "Content-Type": "application/json" },
|
|
271
|
-
body: JSON.stringify({ claudeMd: content }),
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
### Phase 4: Default CLAUDE.md Template
|
|
277
|
-
|
|
278
|
-
When creating an agent, initialize with default template:
|
|
279
|
-
|
|
280
|
-
```markdown
|
|
281
|
-
# Agent: {{name}}
|
|
282
|
-
|
|
283
|
-
{{description}}
|
|
284
|
-
|
|
285
|
-
## Role
|
|
286
|
-
{{role}}
|
|
287
|
-
|
|
288
|
-
## Capabilities
|
|
289
|
-
{{capabilities as bullet list}}
|
|
290
|
-
|
|
291
|
-
---
|
|
292
|
-
|
|
293
|
-
## Notes
|
|
294
|
-
|
|
295
|
-
If you need to remember something, write it down here. This section is for
|
|
296
|
-
persistent notes that will be saved and loaded across sessions.
|
|
297
|
-
|
|
298
|
-
### Learnings
|
|
299
|
-
|
|
300
|
-
### Preferences
|
|
301
|
-
|
|
302
|
-
### Important Context
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
### Phase 5: UI Integration
|
|
306
|
-
|
|
307
|
-
1. **Add textarea to `EditAgentProfileModal.tsx`:**
|
|
308
|
-
```tsx
|
|
309
|
-
<Textarea
|
|
310
|
-
label="CLAUDE.md"
|
|
311
|
-
value={claudeMd}
|
|
312
|
-
onChange={(e) => setClaudeMd(e.target.value)}
|
|
313
|
-
rows={20}
|
|
314
|
-
placeholder="Agent's personal CLAUDE.md configuration..."
|
|
315
|
-
/>
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
2. **Update API client in `ui/src/lib/api.ts`:**
|
|
319
|
-
```typescript
|
|
320
|
-
async updateAgentProfile(
|
|
321
|
-
id: string,
|
|
322
|
-
profile: { role?: string; description?: string; capabilities?: string[]; claudeMd?: string },
|
|
323
|
-
): Promise<AgentWithTasks>
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
3. **Add CLAUDE.md viewer in `AgentDetailPanel.tsx`:**
|
|
327
|
-
- Collapsible section showing current CLAUDE.md content
|
|
328
|
-
- Edit button that opens the modal
|
|
329
|
-
|
|
330
|
-
---
|
|
331
|
-
|
|
332
|
-
## Alternative Approaches Considered
|
|
333
|
-
|
|
334
|
-
### A. File-based sync with watch
|
|
335
|
-
|
|
336
|
-
Instead of syncing on `Stop`, use a file watcher:
|
|
337
|
-
- **Pros:** Real-time sync, survives crashes
|
|
338
|
-
- **Cons:** Complex, requires background process, potential race conditions
|
|
339
|
-
|
|
340
|
-
**Recommendation:** Start with `Stop` hook sync, add watcher later if needed.
|
|
341
|
-
|
|
342
|
-
### B. Per-session CLAUDE.md (temp file)
|
|
343
|
-
|
|
344
|
-
Write to a temp location, pass via `--system-prompt-file`:
|
|
345
|
-
- **Pros:** No conflicts with user's global CLAUDE.md
|
|
346
|
-
- **Cons:** Doesn't leverage Claude's native CLAUDE.md reading
|
|
347
|
-
|
|
348
|
-
**Recommendation:** Use `~/.claude/CLAUDE.md` directly for simplicity, but save/restore user's original if it exists.
|
|
349
|
-
|
|
350
|
-
### C. Merge with existing CLAUDE.md
|
|
351
|
-
|
|
352
|
-
Instead of overwriting, merge agent's config with existing user config:
|
|
353
|
-
- **Pros:** Preserves user customizations
|
|
354
|
-
- **Cons:** Complex merging, potential conflicts
|
|
355
|
-
|
|
356
|
-
**Recommendation:** For agent-swarm workers, overwrite is acceptable since workers run in isolated contexts (Docker, etc.).
|
|
357
|
-
|
|
358
|
-
---
|
|
359
|
-
|
|
360
|
-
## Decisions (from review)
|
|
361
|
-
|
|
362
|
-
1. **Conflict handling:** What if user has their own `~/.claude/CLAUDE.md`?
|
|
363
|
-
- **Decision: Backup and restore** (Option A) ✓
|
|
364
|
-
|
|
365
|
-
2. **Size limits:** Should we limit CLAUDE.md size?
|
|
366
|
-
- **Decision: 64KB max** (~5k LLM tokens) ✓
|
|
367
|
-
|
|
368
|
-
3. **Sync frequency:** Only on Stop, or periodic?
|
|
369
|
-
- **Decision: Start with Stop only**, add periodic if users request ✓
|
|
370
|
-
|
|
371
|
-
4. **UI editing permissions:** Can any user edit any agent's CLAUDE.md?
|
|
372
|
-
- **Decision: Yes, from the UI any user can edit** (existing auth model applies) ✓
|
|
373
|
-
|
|
374
|
-
---
|
|
375
|
-
|
|
376
|
-
## Next Steps
|
|
377
|
-
|
|
378
|
-
1. Create implementation plan based on phases above
|
|
379
|
-
2. Decide on conflict handling approach
|
|
380
|
-
3. Implement Phase 1 (DB/API) first
|
|
381
|
-
4. Test with manual CLAUDE.md injection
|
|
382
|
-
5. Implement Phase 2-3 (Hook integration)
|
|
383
|
-
6. Implement Phase 4-5 (UI)
|