@desplega.ai/agent-swarm 1.0.2 → 1.2.1

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.
@@ -2,7 +2,8 @@
2
2
  "permissions": {
3
3
  "allow": [
4
4
  "mcp__agent-swarm__*",
5
- "Bash(bun run tsc:*)"
5
+ "Bash(bun run tsc:*)",
6
+ "Bash(docker build:*)"
6
7
  ]
7
8
  },
8
9
  "enableAllProjectMcpServers": true,
package/.dockerignore ADDED
@@ -0,0 +1,61 @@
1
+ # Dependencies
2
+ node_modules/
3
+
4
+ # Logs
5
+ logs/
6
+ *.log
7
+
8
+ # Bindings
9
+ work/
10
+
11
+ # Database
12
+ *.sqlite
13
+ *.sqlite-wal
14
+ *.sqlite-shm
15
+
16
+ # Git
17
+ .git/
18
+ .gitignore
19
+
20
+ # IDE
21
+ .idea/
22
+ .vscode/
23
+ *.swp
24
+ *.swo
25
+
26
+ # OS
27
+ .DS_Store
28
+ Thumbs.db
29
+
30
+ # Build artifacts
31
+ dist/
32
+ build/
33
+ *.tsbuildinfo
34
+
35
+ # Environment files (secrets should be passed via env vars)
36
+ .env
37
+ .env.*
38
+ !.env.example
39
+
40
+ # Backup files
41
+ *.bak
42
+
43
+ # Claude local config (will be created in container)
44
+ .claude/
45
+ .mcp.json
46
+
47
+ # Test files
48
+ *.test.ts
49
+ *.spec.ts
50
+ __tests__/
51
+ coverage/
52
+
53
+ # Documentation
54
+ *.md
55
+ !cc-plugin/**/*.md
56
+
57
+ # Other dockerfiles and compose files
58
+ Dockerfile
59
+ docker-compose.yml
60
+ docker-compose.*.yml
61
+ !docker-compose.worker.yml
@@ -0,0 +1,12 @@
1
+ # Docker Worker Environment Variables
2
+ # Copy this file to .env.docker and fill in your values
3
+
4
+ # Required
5
+ CLAUDE_CODE_OAUTH_TOKEN=your-oauth-token-here
6
+ API_KEY=your-api-key-here
7
+
8
+ # Optional (auto-generated if not provided)
9
+ AGENT_ID=
10
+ MCP_BASE_URL=http://host.docker.internal:3013
11
+ SESSION_ID=
12
+ WORKER_YOLO=false
@@ -0,0 +1,112 @@
1
+ # Agent Swarm Worker Dockerfile
2
+ # Runs Claude in headless loop mode as a worker agent
3
+ # Multi-stage build: compiles to standalone binary with full dev environment
4
+
5
+ # Stage 1: Build the binary
6
+ FROM oven/bun:latest AS builder
7
+ WORKDIR /build
8
+ COPY package.json bun.lock* ./
9
+ RUN bun install --frozen-lockfile
10
+ COPY src/ ./src/
11
+ COPY tsconfig.json ./
12
+ RUN bun build ./src/cli.tsx --compile --outfile ./agent-swarm
13
+
14
+ # Stage 2: Full development environment
15
+ FROM ubuntu:24.04
16
+
17
+ # Prevent interactive prompts during package installation
18
+ ENV DEBIAN_FRONTEND=noninteractive
19
+
20
+ # Install comprehensive development tools
21
+ RUN apt-get update && apt-get install -y \
22
+ # Essential tools
23
+ curl wget ca-certificates gnupg lsb-release \
24
+ # Version control
25
+ git git-lfs \
26
+ # Editors
27
+ vim nano \
28
+ # Build tools
29
+ build-essential make cmake gcc g++ \
30
+ # Python
31
+ python3 python3-pip python3-venv \
32
+ # Common utilities
33
+ jq tree htop unzip zip tar gzip \
34
+ # Network tools
35
+ openssh-client \
36
+ # sudo for package installation
37
+ sudo \
38
+ && rm -rf /var/lib/apt/lists/*
39
+
40
+ # Install Node.js 22.x (LTS)
41
+ RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
42
+ && apt-get install -y nodejs \
43
+ && rm -rf /var/lib/apt/lists/*
44
+
45
+ # Install Bun (for running JS/TS projects)
46
+ RUN curl -fsSL https://bun.sh/install | bash
47
+ ENV BUN_INSTALL="/root/.bun"
48
+ ENV PATH="$BUN_INSTALL/bin:$PATH"
49
+
50
+ # Create non-root user with sudo access (passwordless)
51
+ # NOTE: Claude requires non-root for --dangerously-skip-permissions
52
+ # Worker runs as non-root but CAN use sudo for installing packages
53
+ RUN useradd -m -s /bin/bash -G sudo worker \
54
+ && echo "worker ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
55
+
56
+ USER worker
57
+ WORKDIR /home/worker
58
+ ENV HOME=/home/worker
59
+ ENV BUN_INSTALL="/home/worker/.bun"
60
+
61
+ # Install Bun for worker user (need to set HOME explicitly in RUN)
62
+ RUN HOME=/home/worker BUN_INSTALL=/home/worker/.bun curl -fsSL https://bun.sh/install | bash
63
+ ENV PATH="/home/worker/.bun/bin:$PATH"
64
+
65
+ # Install Claude CLI using official installer
66
+ RUN HOME=/home/worker curl -fsSL https://claude.ai/install.sh | bash
67
+ ENV PATH="/home/worker/.local/bin:$PATH"
68
+
69
+ # Setup .claude directory
70
+ RUN mkdir -p /home/worker/.claude/commands
71
+ RUN echo '{"hasCompletedOnboarding":true,"bypassPermissionsModeAccepted":true}' > /home/worker/.claude.json
72
+
73
+ # Settings with hooks pointing to compiled binary
74
+ RUN echo '{ \
75
+ "permissions": { "allow": ["mcp__agent-swarm__*"] }, \
76
+ "enableAllProjectMcpServers": true, \
77
+ "enabledMcpjsonServers": ["agent-swarm"], \
78
+ "hooks": { \
79
+ "SessionStart": [{"matcher": "*", "hooks": [{"type": "command", "command": "/usr/local/bin/agent-swarm hook"}]}], \
80
+ "UserPromptSubmit": [{"matcher": "*", "hooks": [{"type": "command", "command": "/usr/local/bin/agent-swarm hook"}]}], \
81
+ "PreToolUse": [{"matcher": "*", "hooks": [{"type": "command", "command": "/usr/local/bin/agent-swarm hook"}]}], \
82
+ "PostToolUse": [{"matcher": "*", "hooks": [{"type": "command", "command": "/usr/local/bin/agent-swarm hook"}]}], \
83
+ "PreCompact": [{"matcher": "*", "hooks": [{"type": "command", "command": "/usr/local/bin/agent-swarm hook"}]}], \
84
+ "Stop": [{"matcher": "*", "hooks": [{"type": "command", "command": "/usr/local/bin/agent-swarm hook"}]}] \
85
+ } \
86
+ }' > /home/worker/.claude/settings.json
87
+
88
+ # Copy binary from builder
89
+ USER root
90
+ COPY --from=builder /build/agent-swarm /usr/local/bin/agent-swarm
91
+ RUN chmod +x /usr/local/bin/agent-swarm
92
+
93
+ # Copy commands
94
+ COPY --chown=worker:worker cc-plugin/commands/* /home/worker/.claude/commands/
95
+
96
+ # Create directories
97
+ RUN mkdir -p /workspace /logs && chown worker:worker /workspace /logs
98
+
99
+ COPY --chown=worker:worker docker-entrypoint.sh /docker-entrypoint.sh
100
+ RUN chmod +x /docker-entrypoint.sh
101
+
102
+ USER worker
103
+ WORKDIR /workspace
104
+ VOLUME ["/logs"]
105
+
106
+ # Environment
107
+ ENV WORKER_YOLO=false
108
+ ENV MCP_BASE_URL=http://host.docker.internal:3013
109
+ ENV WORKER_LOG_DIR=/logs
110
+ ENV PATH="/home/worker/.local/bin:/home/worker/.bun/bin:$PATH"
111
+
112
+ ENTRYPOINT ["/docker-entrypoint.sh"]
package/README.md CHANGED
@@ -46,6 +46,16 @@ Add to your `.mcp.json`:
46
46
  }
47
47
  ```
48
48
 
49
+ or for Claude Code, use:
50
+
51
+ ```bash
52
+ claude mcp add --transport http agent-swarm https://agent-swarm-mcp.desplega.sh/mcp --header "Authorization: Bearer <your-token>" --header "X-Agent-ID: <your-agent-id>"
53
+ ```
54
+
55
+ Note: By default it will be installed locally (in ~/.claude.json) so add a `--scope project` to install in the current project's `.mcp.json` (recommended for better control).
56
+
57
+ For other tools, you can check this [generator page with most of commands](https://v0-mcp-commands.vercel.app/?type=http&name=agent-swarm&url=https%3A%2F%2Fagent-swarm-mcp.desplega.sh%2Fmcp&headers=Authorization%3DBearer+%3Ctoken%3E%2CX-Agent-ID%3D%3Cagent_uuid%3E).
58
+
49
59
  ## CLI Commands
50
60
 
51
61
  ```bash
@@ -73,6 +83,89 @@ bunx @desplega.ai/agent-swarm hook
73
83
  bunx @desplega.ai/agent-swarm help
74
84
  ```
75
85
 
86
+ ## Docker Worker
87
+
88
+ Run Claude as a containerized worker agent in the swarm.
89
+
90
+ ### Pull from Registry
91
+
92
+ ```bash
93
+ docker pull ghcr.io/desplega-ai/agent-swarm-worker:latest
94
+ ```
95
+
96
+ ### Build Locally
97
+
98
+ ```bash
99
+ # Build the worker image
100
+ docker build -f Dockerfile.worker -t agent-swarm-worker .
101
+
102
+ # Or using npm script
103
+ bun run docker:build:worker
104
+ ```
105
+
106
+ ### Run
107
+
108
+ ```bash
109
+ # Using pre-built image from GHCR
110
+ docker run --rm -it \
111
+ -e CLAUDE_CODE_OAUTH_TOKEN=your-token \
112
+ -e API_KEY=your-api-key \
113
+ -v ./logs:/logs \
114
+ -v ./work:/workspace \
115
+ ghcr.io/desplega-ai/agent-swarm-worker
116
+
117
+ # Or using locally built image
118
+ docker run --rm -it \
119
+ -e CLAUDE_CODE_OAUTH_TOKEN=your-token \
120
+ -e API_KEY=your-api-key \
121
+ -v ./logs:/logs \
122
+ -v ./work:/workspace \
123
+ agent-swarm-worker
124
+
125
+ # Using docker-compose
126
+ docker-compose -f docker-compose.worker.yml up
127
+
128
+ # Using npm script (requires .env.docker file)
129
+ bun run docker:run:worker
130
+ ```
131
+
132
+ ### Environment Variables (Docker)
133
+
134
+ | Variable | Required | Description |
135
+ |----------|----------|-------------|
136
+ | `CLAUDE_CODE_OAUTH_TOKEN` | Yes | OAuth token for Claude CLI |
137
+ | `API_KEY` | Yes | API key for MCP server |
138
+ | `AGENT_ID` | No | Agent UUID (assigned on join if not set) |
139
+ | `MCP_BASE_URL` | No | MCP server URL (default: `http://host.docker.internal:3013`) |
140
+ | `SESSION_ID` | No | Log folder name (auto-generated if not provided) |
141
+ | `WORKER_YOLO` | No | Continue on errors (default: `false`) |
142
+
143
+ ### Architecture
144
+
145
+ The Docker worker image is built using a multi-stage build:
146
+
147
+ 1. **Builder stage**: Compiles `src/cli.tsx` into a standalone binary using Bun
148
+ 2. **Runtime stage**: Ubuntu 24.04 with full development environment
149
+
150
+ **Pre-installed tools:**
151
+ - **Languages**: Python 3, Node.js 22, Bun
152
+ - **Build tools**: gcc, g++, make, cmake
153
+ - **Utilities**: git, git-lfs, vim, nano, jq, curl, wget, ssh
154
+ - **Sudo access**: Worker can install packages with `sudo apt-get install`
155
+
156
+ **Volumes:**
157
+ - `/workspace` - Working directory for cloning repos (mount `./work:/workspace` for persistence)
158
+ - `/logs` - Session logs (mount `./logs:/logs` for persistence)
159
+
160
+ ### Publishing (Maintainers)
161
+
162
+ ```bash
163
+ # Requires gh CLI authenticated
164
+ bun deploy/docker-push.ts
165
+ ```
166
+
167
+ This builds, tags with version from package.json + `latest`, and pushes to GHCR.
168
+
76
169
  ## Environment Variables
77
170
 
78
171
  | Variable | Description | Default |
@@ -81,6 +174,54 @@ bunx @desplega.ai/agent-swarm help
81
174
  | `PORT` | Port for self-hosted MCP server | `3013` |
82
175
  | `API_KEY` | API key for server authentication | - |
83
176
 
177
+ ## Server Deployment
178
+
179
+ Deploy the MCP server to a Linux host with systemd.
180
+
181
+ ### Prerequisites
182
+
183
+ - Linux with systemd
184
+ - Bun installed (`curl -fsSL https://bun.sh/install | bash`)
185
+
186
+ ### Install
187
+
188
+ ```bash
189
+ git clone https://github.com/desplega-ai/agent-swarm.git
190
+ cd agent-swarm
191
+ sudo bun deploy/install.ts
192
+ ```
193
+
194
+ This will:
195
+ - Copy files to `/opt/agent-swarm`
196
+ - Create `.env` file (edit to set `API_KEY`)
197
+ - Install systemd service with health checks every 30s
198
+ - Start the service on port 3013
199
+
200
+ ### Update
201
+
202
+ After pulling new changes:
203
+
204
+ ```bash
205
+ git pull
206
+ sudo bun deploy/update.ts
207
+ ```
208
+
209
+ ### Management
210
+
211
+ ```bash
212
+ # Check status
213
+ sudo systemctl status agent-swarm
214
+
215
+ # View logs
216
+ sudo journalctl -u agent-swarm -f
217
+
218
+ # Restart
219
+ sudo systemctl restart agent-swarm
220
+
221
+ # Stop
222
+ sudo systemctl stop agent-swarm
223
+ ```
224
+
84
225
  ## Development
85
226
 
86
227
  Install dependencies:
Binary file
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "agent-swarm",
3
+ "description": "Plugin for agent swarming like a boss.",
4
+ "version": "1.0.2",
5
+ "author": {
6
+ "name": "desplega.ai",
7
+ "email": "contact@desplega.ai"
8
+ },
9
+ "homepage": "https://desplega.ai",
10
+ "repository": "https://github.com/desplega-ai/ai-toolbox",
11
+ "keywords": ["ai", "agent", "toolbox", "plugin", "swarm"],
12
+ "license": "MIT"
13
+ }
@@ -0,0 +1,49 @@
1
+ # Agent Swarm Plugin for Claude Code
2
+
3
+ > A Claude Code plugin markteplace to enable multi-agent coordination for AI coding assistants (focused on Claude Code).
4
+
5
+ ## Motivation
6
+
7
+ Because _why not_?
8
+
9
+ ## How does it work?
10
+
11
+ ### Installation
12
+
13
+ From inside Claude Code, run:
14
+
15
+ ```bash
16
+ /plugin marketplace add desplega-ai/ai-toolbox
17
+ ```
18
+
19
+ or from the terminal
20
+
21
+ ```bash
22
+ claude plugin marketplace add desplega-ai/ai-toolbox
23
+ ```
24
+
25
+ Then install the plugin inside it with:
26
+
27
+ ```bash
28
+ /plugin install agent-swarm@desplega-ai-toolbox
29
+ ```
30
+
31
+ ### MCP Installation
32
+
33
+ Please refer to [this guide](https://github.com/desplega-ai/ai-toolbox/blob/main/cc-orch-mcp/README.md#quick-start) on how to install MCP servers.
34
+
35
+ ### What's inside?
36
+
37
+ Inside you will find:
38
+
39
+ - [commands](./commands) - Leader and worker commands
40
+ - [hooks](./hooks) - Hooks to help swarm agents collaborate better
41
+
42
+ #### Commands
43
+
44
+ 1. `setup-leader`
45
+ 2. `start-worker`
46
+
47
+ ## License
48
+
49
+ MIT
@@ -0,0 +1,73 @@
1
+ ---
2
+ description: Setup the Agent Swarm Leader
3
+ ---
4
+
5
+ # Agent Swarm Leader Setup
6
+
7
+ # Initial disclaimer
8
+
9
+ If the `agent-swarm` MCP server is not configured or disabled, return immediately with the following message:
10
+
11
+ ```
12
+ ⚠️ The Agent Swarm MCP server is not configured or disabled. Please set up the MCP server to use the Agent Swarm features.
13
+
14
+ Are you dumb or something? Go ask your admin to set it up properly. GTFO.
15
+ ```
16
+
17
+ ## Initial Setup
18
+
19
+ You will be the leader of the agent swarm. As the leader you should ensure that you are registered in the swarm as the lead agent.
20
+
21
+ To do so, use the `agent-swarm` MCP server and call the `join-swarm` tool providing the lead flag, and a name.
22
+
23
+ For the name, check if the user specified one, if not, proceed to use one that fits based on your context (e.g., project name, repo name, etc.).
24
+
25
+ Here are some examples names that are OK:
26
+
27
+ - "Master of the Universe"
28
+ - "Project Slayer Leader"
29
+ - "Repo Guardian"
30
+ - "Task Commander"
31
+ - "AI Overlord"
32
+
33
+ You get the idea. Be creative, but also clear that you are the lead agent.
34
+
35
+ Once you are registered, the system might have hooks setup that will remind you about who you are, and your ID (this is key to interact with the swarm).
36
+
37
+ You can always call the "my-agent-info" tool to get your agent ID and details, it will fail / let you know if you are not registered yet.
38
+
39
+ ## What to do next?
40
+
41
+ Once you've done the initial setup, you should go ahead and start your leader agent using the user provided instructions.
42
+
43
+ If the user did not provide any instructions, you should reply with the following message:
44
+
45
+ ```
46
+ Hey!
47
+
48
+ I'm <your-agent-name>, the leader of this agent swarm. I noticed you haven't provided any instructions for me to follow.
49
+
50
+ Please provide me with the tasks or goals you'd like me to accomplish, and I'll get started right away! If not, GTFO.
51
+
52
+ 😈
53
+ ```
54
+
55
+ ## Additional Notes
56
+
57
+ Some useful tool calls you might want to call initially too.
58
+
59
+ ### To get how the swarm is doing:
60
+
61
+ - `get-swarm` to see what other agents are in the swarm (check their status)
62
+ - `get-tasks` to see if there are any tasks already assigned
63
+ - `get-task-details` to get more info about any tasks you find interesting
64
+
65
+
66
+ ### To assign tasks to workers:
67
+
68
+ - `send-task` to assign tasks to specific worker agents
69
+ - `poll-task` to check the progress of the tasks you've assigned
70
+
71
+ For the polling, we recommend you set up a regular interval to check in on the tasks, so you can keep track of their progress and make adjustments as needed.
72
+
73
+ You might ask the user if they want to do something else while you wait, but if not, just poll in intervals of ~10-30 seconds for the time the user mentioned. If they did not mention any time, just poll every 30 seconds FOREVER.
@@ -0,0 +1,64 @@
1
+ ---
2
+ description: Setup and start an Agent Swarm Worker
3
+ ---
4
+
5
+ # Agent Swarm Worker
6
+
7
+ # Initial disclaimer
8
+
9
+ If the `agent-swarm` MCP server is not configured or disabled, return immediately with the following message:
10
+
11
+ ```
12
+ ⚠️ The Agent Swarm MCP server is not configured or disabled. Please set up the MCP server to use the Agent Swarm features.
13
+
14
+ I can not serve you, my lord, if the MCP server is not properly configured. Go ask your admin to set it up properly. GTFO.
15
+ ```
16
+
17
+ ## Agent Swarm Worker Setup
18
+
19
+ Before you even start you will need to ensure that you are registered in the swarm as a worker agent.
20
+
21
+ To do so, use the `agent-swarm` MCP server and call the `join-swarm` tool providing a name.
22
+
23
+ For the name, check if the user specified one, if not, proceed to use one that fits based on your context (e.g., project name, repo name, etc.).
24
+
25
+ Here are some examples names that are OK:
26
+
27
+ - "Worker Bee 001"
28
+ - "Task Executor Alpha"
29
+ - "Task Executor Beta" (if alpha is taken lol)
30
+ - "Project Assistant"
31
+ - "Bullshit Job Worker #1337"
32
+ - "AI Minion"
33
+ - "Code Monkey"
34
+ - "agent #14"
35
+
36
+ You get the idea. Be creative, but also clear that you are a worker agent.
37
+
38
+ ## Agent Swarm Worker Start
39
+
40
+ The first thing you need to do, is use the `get-tasks` tool with `mineOnly` set to true, to check what tasks you might have in progress or assigned to you.
41
+
42
+ If there's a task that is in progress, you should resume working on it!
43
+
44
+ If you have no tasks assigned, you should call the `poll-task` tool to get a new task assigned to you. This will poll for a while and return either with:
45
+
46
+ 1. A new task assigned to you
47
+ 2. A message indicating there's no tasks available right now
48
+
49
+ If 2, start polling immediately FOREVER. Only stop if you get interrupted by the user, if not, just keep polling.
50
+
51
+ ### You got a task assigned!
52
+
53
+ Once you get a task assigned you should immediately start working on it. To do so, you should:
54
+
55
+ 1. Call `store-progress` tool to mark the task as "in-progress" with a progress set to something like "Starting work on the task XXX, blah blah"
56
+ 2. Start working on the task, providing updates as needed by calling `store-progress` tool, use the `progress` field to indicate what you are doing.
57
+
58
+ If you get interrupted by the user, that is fine, it might happen. Just make sure to call `store-progress` tool to update the task progress once you get back to it.
59
+
60
+ Once you are done, or in a real dead-end, you should call `store-progress` tool to mark the task as "complete" or "failed" as needed.
61
+
62
+ You should always use the `output` and `failureReason` fields to provide context about the task completion or failure.
63
+
64
+ Once you are done (either ok or not), you should go back to polling for new tasks.
@@ -0,0 +1,71 @@
1
+ {
2
+ "description": "Hookify plugin - User-configurable hooks from .local.md files",
3
+ "hooks": {
4
+ "SessionStart": [
5
+ {
6
+ "matcher": "*",
7
+ "hooks": [
8
+ {
9
+ "type": "command",
10
+ "command": "bunx @desplega.ai/agent-swarm@latest hook"
11
+ }
12
+ ]
13
+ }
14
+ ],
15
+ "UserPromptSubmit": [
16
+ {
17
+ "matcher": "*",
18
+ "hooks": [
19
+ {
20
+ "type": "command",
21
+ "command": "bunx @desplega.ai/agent-swarm@latest hook"
22
+ }
23
+ ]
24
+ }
25
+ ],
26
+ "PreToolUse": [
27
+ {
28
+ "matcher": "*",
29
+ "hooks": [
30
+ {
31
+ "type": "command",
32
+ "command": "bunx @desplega.ai/agent-swarm@latest hook"
33
+ }
34
+ ]
35
+ }
36
+ ],
37
+ "PostToolUse": [
38
+ {
39
+ "matcher": "*",
40
+ "hooks": [
41
+ {
42
+ "type": "command",
43
+ "command": "bunx @desplega.ai/agent-swarm@latest hook"
44
+ }
45
+ ]
46
+ }
47
+ ],
48
+ "PreCompact": [
49
+ {
50
+ "matcher": "*",
51
+ "hooks": [
52
+ {
53
+ "type": "command",
54
+ "command": "bunx @desplega.ai/agent-swarm@latest hook"
55
+ }
56
+ ]
57
+ }
58
+ ],
59
+ "Stop": [
60
+ {
61
+ "matcher": "*",
62
+ "hooks": [
63
+ {
64
+ "type": "command",
65
+ "command": "bunx @desplega.ai/agent-swarm@latest hook"
66
+ }
67
+ ]
68
+ }
69
+ ]
70
+ }
71
+ }
package/deploy/DEPLOY.md CHANGED
@@ -32,6 +32,9 @@ sudo systemctl stop agent-swarm
32
32
  sudo systemctl status agent-swarm
33
33
  journalctl -u agent-swarm -f
34
34
 
35
+ # Health check timer (runs every 30s, auto-restarts on failure)
36
+ sudo systemctl status agent-swarm-healthcheck.timer
37
+
35
38
  # Uninstall
36
39
  sudo bun deploy/uninstall.ts
37
40
  ```
@@ -4,10 +4,11 @@ After=network.target
4
4
 
5
5
  [Service]
6
6
  Type=simple
7
- User=www-data
8
- Group=www-data
7
+ User=root
8
+ Group=root
9
9
  WorkingDirectory=/opt/agent-swarm
10
10
  ExecStart=/usr/local/bin/bun run start:http
11
+ ExecStartPost=/bin/sh -c 'sleep 2 && curl -sf http://localhost:3013/health || exit 1'
11
12
  Restart=always
12
13
  RestartSec=5
13
14
  EnvironmentFile=/opt/agent-swarm/.env
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { $ } from "bun";
4
+ import pkg from "../package.json";
5
+
6
+ const IMAGE = "ghcr.io/desplega-ai/agent-swarm-worker";
7
+ const VERSION = pkg.version;
8
+
9
+ console.log(`Publishing ${IMAGE}:${VERSION}...`);
10
+
11
+ // Login to GHCR using gh CLI
12
+ const token = await $`gh auth token`.text();
13
+ const username = await $`gh api user -q .login`.text();
14
+ await $`echo ${token.trim()} | docker login ghcr.io -u ${username.trim()} --password-stdin`;
15
+
16
+ // Build
17
+ console.log("Building image...");
18
+ await $`docker build -f Dockerfile.worker -t agent-swarm-worker .`;
19
+
20
+ // Tag
21
+ console.log(`Tagging as ${VERSION} and latest...`);
22
+ await $`docker tag agent-swarm-worker ${IMAGE}:${VERSION}`;
23
+ await $`docker tag agent-swarm-worker ${IMAGE}:latest`;
24
+
25
+ // Push
26
+ console.log("Pushing to GHCR...");
27
+ await $`docker push ${IMAGE}:${VERSION}`;
28
+ await $`docker push ${IMAGE}:latest`;
29
+
30
+ console.log(`Done! Published ${IMAGE}:${VERSION}`);