@desplega.ai/agent-swarm 1.2.1 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/.claude/settings.local.json +20 -1
  2. package/.env.docker.example +22 -1
  3. package/.env.example +17 -0
  4. package/.github/workflows/docker-publish.yml +92 -0
  5. package/CONTRIBUTING.md +270 -0
  6. package/DEPLOYMENT.md +391 -0
  7. package/Dockerfile.worker +29 -1
  8. package/FAQ.md +19 -0
  9. package/LICENSE +21 -0
  10. package/MCP.md +249 -0
  11. package/README.md +103 -207
  12. package/assets/agent-swarm-logo-orange.png +0 -0
  13. package/assets/agent-swarm-logo.png +0 -0
  14. package/docker-compose.example.yml +137 -0
  15. package/docker-entrypoint.sh +223 -7
  16. package/package.json +8 -3
  17. package/{cc-plugin → plugin}/.claude-plugin/plugin.json +1 -1
  18. package/plugin/README.md +1 -0
  19. package/plugin/agents/.gitkeep +0 -0
  20. package/plugin/agents/codebase-analyzer.md +143 -0
  21. package/plugin/agents/codebase-locator.md +122 -0
  22. package/plugin/agents/codebase-pattern-finder.md +227 -0
  23. package/plugin/agents/web-search-researcher.md +109 -0
  24. package/plugin/commands/create-plan.md +415 -0
  25. package/plugin/commands/implement-plan.md +89 -0
  26. package/plugin/commands/research.md +200 -0
  27. package/plugin/commands/start-leader.md +101 -0
  28. package/plugin/commands/start-worker.md +56 -0
  29. package/plugin/commands/swarm-chat.md +78 -0
  30. package/plugin/commands/todos.md +66 -0
  31. package/plugin/commands/work-on-task.md +44 -0
  32. package/plugin/skills/.gitkeep +0 -0
  33. package/scripts/generate-mcp-docs.ts +415 -0
  34. package/slack-manifest.json +69 -0
  35. package/src/be/db.ts +1431 -25
  36. package/src/cli.tsx +135 -11
  37. package/src/commands/lead.ts +13 -0
  38. package/src/commands/runner.ts +255 -0
  39. package/src/commands/worker.ts +8 -220
  40. package/src/hooks/hook.ts +102 -14
  41. package/src/http.ts +361 -5
  42. package/src/prompts/base-prompt.ts +131 -0
  43. package/src/server.ts +56 -0
  44. package/src/slack/app.ts +73 -0
  45. package/src/slack/commands.ts +88 -0
  46. package/src/slack/handlers.ts +281 -0
  47. package/src/slack/index.ts +3 -0
  48. package/src/slack/responses.ts +175 -0
  49. package/src/slack/router.ts +170 -0
  50. package/src/slack/types.ts +20 -0
  51. package/src/slack/watcher.ts +119 -0
  52. package/src/tools/create-channel.ts +80 -0
  53. package/src/tools/get-tasks.ts +54 -21
  54. package/src/tools/join-swarm.ts +28 -4
  55. package/src/tools/list-channels.ts +37 -0
  56. package/src/tools/list-services.ts +110 -0
  57. package/src/tools/poll-task.ts +46 -3
  58. package/src/tools/post-message.ts +87 -0
  59. package/src/tools/read-messages.ts +192 -0
  60. package/src/tools/register-service.ts +118 -0
  61. package/src/tools/send-task.ts +80 -7
  62. package/src/tools/store-progress.ts +9 -3
  63. package/src/tools/task-action.ts +211 -0
  64. package/src/tools/unregister-service.ts +110 -0
  65. package/src/tools/update-profile.ts +105 -0
  66. package/src/tools/update-service-status.ts +118 -0
  67. package/src/types.ts +110 -3
  68. package/src/utils/pretty-print.ts +224 -0
  69. package/thoughts/shared/plans/.gitkeep +0 -0
  70. package/thoughts/shared/plans/2025-12-18-inverse-teleport.md +1142 -0
  71. package/thoughts/shared/plans/2025-12-18-slack-integration.md +1195 -0
  72. package/thoughts/shared/plans/2025-12-19-agent-log-streaming.md +732 -0
  73. package/thoughts/shared/plans/2025-12-19-role-based-swarm-plugin.md +361 -0
  74. package/thoughts/shared/plans/2025-12-20-mobile-responsive-ui.md +501 -0
  75. package/thoughts/shared/plans/2025-12-20-startup-team-swarm.md +560 -0
  76. package/thoughts/shared/research/.gitkeep +0 -0
  77. package/thoughts/shared/research/2025-12-18-slack-integration.md +442 -0
  78. package/thoughts/shared/research/2025-12-19-agent-log-streaming.md +339 -0
  79. package/thoughts/shared/research/2025-12-19-agent-secrets-cli-research.md +390 -0
  80. package/thoughts/shared/research/2025-12-21-gemini-cli-integration.md +376 -0
  81. package/thoughts/shared/research/2025-12-22-setup-experience-improvements.md +264 -0
  82. package/tsconfig.json +3 -1
  83. package/ui/bun.lock +692 -0
  84. package/ui/index.html +22 -0
  85. package/ui/package.json +32 -0
  86. package/ui/pnpm-lock.yaml +3034 -0
  87. package/ui/postcss.config.js +6 -0
  88. package/ui/public/logo.png +0 -0
  89. package/ui/src/App.tsx +43 -0
  90. package/ui/src/components/ActivityFeed.tsx +415 -0
  91. package/ui/src/components/AgentDetailPanel.tsx +534 -0
  92. package/ui/src/components/AgentsPanel.tsx +549 -0
  93. package/ui/src/components/ChatPanel.tsx +1820 -0
  94. package/ui/src/components/ConfigModal.tsx +232 -0
  95. package/ui/src/components/Dashboard.tsx +534 -0
  96. package/ui/src/components/Header.tsx +168 -0
  97. package/ui/src/components/ServicesPanel.tsx +612 -0
  98. package/ui/src/components/StatsBar.tsx +288 -0
  99. package/ui/src/components/StatusBadge.tsx +124 -0
  100. package/ui/src/components/TaskDetailPanel.tsx +807 -0
  101. package/ui/src/components/TasksPanel.tsx +575 -0
  102. package/ui/src/hooks/queries.ts +170 -0
  103. package/ui/src/index.css +235 -0
  104. package/ui/src/lib/api.ts +161 -0
  105. package/ui/src/lib/config.ts +35 -0
  106. package/ui/src/lib/theme.ts +214 -0
  107. package/ui/src/lib/utils.ts +48 -0
  108. package/ui/src/main.tsx +32 -0
  109. package/ui/src/types/api.ts +164 -0
  110. package/ui/src/vite-env.d.ts +1 -0
  111. package/ui/tailwind.config.js +35 -0
  112. package/ui/tsconfig.json +31 -0
  113. package/ui/vite.config.ts +22 -0
  114. package/cc-plugin/README.md +0 -49
  115. package/cc-plugin/commands/setup-leader.md +0 -73
  116. package/cc-plugin/commands/start-worker.md +0 -64
  117. package/docker-compose.worker.yml +0 -35
  118. package/example-req-meta.json +0 -24
  119. /package/{cc-plugin → plugin}/hooks/hooks.json +0 -0
@@ -0,0 +1,390 @@
1
+ ---
2
+ date: 2025-12-19T14:25:00Z
3
+ researcher: master
4
+ git_commit: 470213538fb1227ec0c1347179d227d28817fca4
5
+ branch: main
6
+ repository: desplega-ai/ai-toolbox
7
+ topic: "Agent Secrets CLI Implementation Research"
8
+ tags: [research, codebase, cli, database, docker, secrets, encryption]
9
+ status: complete
10
+ last_updated: 2025-12-19
11
+ last_updated_by: master
12
+ ---
13
+
14
+ # Research: Agent Secrets CLI Implementation
15
+
16
+ **Date**: 2025-12-19T14:25:00Z
17
+ **Researcher**: master
18
+ **Git Commit**: 470213538fb1227ec0c1347179d227d28817fca4
19
+ **Branch**: main
20
+ **Repository**: desplega-ai/ai-toolbox
21
+
22
+ ## Research Question
23
+
24
+ How to implement a CLI tool called "agent-secrets" for managing encrypted secrets that agents can use. The tool will be shipped with the Docker image and documented in system prompts.
25
+
26
+ ## Summary
27
+
28
+ This research documents the existing codebase structure for implementing the agent-secrets CLI tool. The project uses:
29
+ - **SQLite** via `bun:sqlite` for data storage
30
+ - **Bun-based CLI** with React/Ink for terminal UI
31
+ - **Docker multi-stage builds** for containerization
32
+ - **System prompt injection** via `--append-system-prompt` and custom commands
33
+
34
+ Notably, **no encryption patterns currently exist** in the codebase. The API key authentication uses plain text comparison. Implementing encrypted secrets will require introducing new cryptographic patterns.
35
+
36
+ ## Detailed Findings
37
+
38
+ ### 1. Database Structure and Patterns
39
+
40
+ **File**: `src/be/db.ts:18-174`
41
+
42
+ The project uses SQLite with Bun's built-in `bun:sqlite` module.
43
+
44
+ #### Database Configuration
45
+ - **Path**: `./agent-swarm-db.sqlite`
46
+ - **Pragmas**: WAL mode, foreign keys enabled
47
+ - **Pattern**: Singleton with `initDb()`, `getDb()`, `closeDb()`
48
+
49
+ #### Existing Tables
50
+
51
+ | Table | Purpose |
52
+ |-------|---------|
53
+ | `agents` | Agent registration and status |
54
+ | `agent_tasks` | Task assignments and progress |
55
+ | `agent_log` | Activity logging |
56
+ | `channels` | Communication channels |
57
+ | `channel_messages` | Messages in channels |
58
+ | `channel_read_state` | Message read tracking |
59
+
60
+ #### Table Creation Pattern
61
+
62
+ Tables are created with `CREATE TABLE IF NOT EXISTS` in a single `db.run()` call (`db.ts:27-124`):
63
+
64
+ ```typescript
65
+ db.run(`
66
+ CREATE TABLE IF NOT EXISTS table_name (
67
+ id TEXT PRIMARY KEY,
68
+ name TEXT NOT NULL,
69
+ createdAt TEXT NOT NULL,
70
+ -- more columns...
71
+ );
72
+
73
+ CREATE INDEX IF NOT EXISTS idx_table_name_column ON table_name (column);
74
+ `);
75
+ ```
76
+
77
+ #### UUID Generation
78
+
79
+ Uses global `crypto.randomUUID()` (no import needed in Bun):
80
+
81
+ ```typescript
82
+ const id = crypto.randomUUID();
83
+ ```
84
+
85
+ #### Migration Pattern
86
+
87
+ Since SQLite lacks `ADD COLUMN IF NOT EXISTS`, migrations use try/catch (`db.ts:142-164`):
88
+
89
+ ```typescript
90
+ try {
91
+ db.run(`ALTER TABLE table_name ADD COLUMN new_column TEXT DEFAULT ''`);
92
+ } catch {
93
+ /* column exists */
94
+ }
95
+ ```
96
+
97
+ ### 2. CLI Implementation Patterns
98
+
99
+ **Files**: `src/cli.tsx`, `src/commands/*.ts`
100
+
101
+ The CLI uses React/Ink for terminal UI with command routing via switch statement.
102
+
103
+ #### Entry Point Structure
104
+
105
+ ```typescript
106
+ // src/cli.tsx:628-635
107
+ if (args.command === "hook") {
108
+ runHook(); // Non-UI command
109
+ } else {
110
+ render(<App args={args} />); // UI commands
111
+ }
112
+ ```
113
+
114
+ #### Adding New Commands
115
+
116
+ **Pattern A: Non-UI Command** (for `agent-secrets`):
117
+
118
+ ```typescript
119
+ // src/commands/secrets.ts
120
+ export async function runSecrets(args: string[]): Promise<void> {
121
+ // Parse subcommand: list, get, create, update, add-to-env
122
+ // Execute database operations
123
+ // Output results
124
+ process.exit(0);
125
+ }
126
+
127
+ // src/cli.tsx - before render()
128
+ if (args.command === "secrets") {
129
+ runSecrets(args.additionalArgs);
130
+ }
131
+ ```
132
+
133
+ **Pattern B: UI Command** (React component):
134
+
135
+ ```typescript
136
+ // Add case in switch statement at cli.tsx:591-625
137
+ case "new-command":
138
+ return <NewCommand option1={args.option1} />;
139
+ ```
140
+
141
+ #### Argument Parsing
142
+
143
+ Custom parser at `cli.tsx:23-101`:
144
+
145
+ ```typescript
146
+ interface ParsedArgs {
147
+ command: string | undefined;
148
+ additionalArgs: string[]; // Args after --
149
+ // ... other flags
150
+ }
151
+ ```
152
+
153
+ ### 3. Docker Worker Setup
154
+
155
+ **Files**: `Dockerfile.worker`, `docker-entrypoint.sh`
156
+
157
+ #### Multi-stage Build
158
+
159
+ ```dockerfile
160
+ # Stage 1: Build
161
+ FROM oven/bun:latest AS builder
162
+ RUN bun build ./src/cli.tsx --compile --outfile ./agent-swarm
163
+
164
+ # Stage 2: Runtime
165
+ FROM ubuntu:24.04
166
+ COPY --from=builder /build/agent-swarm /usr/local/bin/agent-swarm
167
+ ```
168
+
169
+ #### Adding New Binary to Docker
170
+
171
+ To add `agent-secrets` to the Docker image:
172
+
173
+ 1. Add to build stage in `Dockerfile.worker`:
174
+ ```dockerfile
175
+ RUN bun build ./src/secrets-cli.ts --compile --outfile ./agent-secrets
176
+ ```
177
+
178
+ 2. Copy to runtime:
179
+ ```dockerfile
180
+ COPY --from=builder /build/agent-secrets /usr/local/bin/agent-secrets
181
+ ```
182
+
183
+ #### Entrypoint Script
184
+
185
+ `docker-entrypoint.sh` runs before the agent starts:
186
+ - Validates environment variables
187
+ - Creates MCP configuration
188
+ - Runs startup scripts from `/workspace/start-up.*`
189
+ - Executes `agent-swarm worker` or `lead`
190
+
191
+ #### Environment Variables
192
+
193
+ | Variable | Description |
194
+ |----------|-------------|
195
+ | `API_KEY` | Required - MCP authentication |
196
+ | `AGENT_ID` | Optional - Agent identifier |
197
+ | `MCP_BASE_URL` | MCP server URL |
198
+
199
+ ### 4. System Prompt Injection
200
+
201
+ **Files**: `src/commands/runner.ts`, `cc-plugin/commands/*.md`
202
+
203
+ #### Passing System Prompts to Claude
204
+
205
+ System prompts are appended via CLI flag (`runner.ts:56-58`):
206
+
207
+ ```typescript
208
+ if (opts.systemPrompt) {
209
+ CMD.push("--append-system-prompt", opts.systemPrompt);
210
+ }
211
+ ```
212
+
213
+ #### Custom Command Files
214
+
215
+ Commands are markdown files with YAML frontmatter in `cc-plugin/commands/`:
216
+
217
+ ```markdown
218
+ ---
219
+ description: Command description shown in help
220
+ ---
221
+
222
+ # Command Title
223
+
224
+ Instructions for Claude...
225
+ ```
226
+
227
+ These are copied to `/home/worker/.claude/commands/` in Docker.
228
+
229
+ #### Documenting New Tools
230
+
231
+ To document `agent-secrets` for agents, add to:
232
+
233
+ 1. **Worker command** (`cc-plugin/commands/start-worker.md`):
234
+ ```markdown
235
+ ### Secret Management
236
+
237
+ Use the `agent-secrets` CLI tool to manage secrets:
238
+ - `agent-secrets list` - List all available secrets
239
+ - `agent-secrets get <id>` - Get a secret value
240
+ - `agent-secrets create --name <name> --value <value>` - Create new secret
241
+ ```
242
+
243
+ 2. **Lead command** (`cc-plugin/commands/setup-leader.md`):
244
+ ```markdown
245
+ ### Secret Management
246
+
247
+ Secrets are managed via the `agent-secrets` CLI. Workers can only access secrets they created or system secrets.
248
+ ```
249
+
250
+ ### 5. Security Patterns (Current State)
251
+
252
+ **Finding**: No encryption patterns exist in the codebase.
253
+
254
+ #### What Exists
255
+ - **UUID generation**: `crypto.randomUUID()`
256
+ - **Bearer token auth**: Plain text comparison
257
+ - **Environment variables**: For all secrets
258
+
259
+ #### What Does NOT Exist
260
+ - Encryption/decryption functions
261
+ - Password hashing
262
+ - Cryptographic signing
263
+ - Data-at-rest encryption
264
+
265
+ #### Implications for Implementation
266
+
267
+ The `agent-secrets` feature will need to introduce:
268
+
269
+ 1. **Encryption algorithm** (e.g., AES-256-GCM)
270
+ 2. **Key derivation** from API_KEY (e.g., PBKDF2 or scrypt)
271
+ 3. **Salt storage** per secret or global
272
+
273
+ Suggested encryption approach using Node.js crypto:
274
+
275
+ ```typescript
276
+ import { createCipheriv, createDecipheriv, randomBytes, scryptSync } from "node:crypto";
277
+
278
+ const ALGORITHM = "aes-256-gcm";
279
+
280
+ function deriveKey(apiKey: string, salt: Buffer): Buffer {
281
+ return scryptSync(apiKey, salt, 32);
282
+ }
283
+
284
+ function encrypt(plaintext: string, apiKey: string): { encrypted: string; salt: string; iv: string; tag: string } {
285
+ const salt = randomBytes(16);
286
+ const key = deriveKey(apiKey, salt);
287
+ const iv = randomBytes(12);
288
+ const cipher = createCipheriv(ALGORITHM, key, iv);
289
+
290
+ let encrypted = cipher.update(plaintext, "utf8", "base64");
291
+ encrypted += cipher.final("base64");
292
+
293
+ return {
294
+ encrypted,
295
+ salt: salt.toString("base64"),
296
+ iv: iv.toString("base64"),
297
+ tag: cipher.getAuthTag().toString("base64"),
298
+ };
299
+ }
300
+
301
+ function decrypt(encrypted: string, apiKey: string, salt: string, iv: string, tag: string): string {
302
+ const key = deriveKey(apiKey, Buffer.from(salt, "base64"));
303
+ const decipher = createDecipheriv(ALGORITHM, key, Buffer.from(iv, "base64"));
304
+ decipher.setAuthTag(Buffer.from(tag, "base64"));
305
+
306
+ let decrypted = decipher.update(encrypted, "base64", "utf8");
307
+ decrypted += decipher.final("utf8");
308
+
309
+ return decrypted;
310
+ }
311
+ ```
312
+
313
+ ## Code References
314
+
315
+ ### Database
316
+ - `src/be/db.ts:18-26` - Database initialization
317
+ - `src/be/db.ts:27-124` - Table creation
318
+ - `src/be/db.ts:142-164` - Migration pattern
319
+ - `src/types.ts` - TypeScript interfaces for all entities
320
+
321
+ ### CLI
322
+ - `src/cli.tsx:23-101` - Argument parsing
323
+ - `src/cli.tsx:591-625` - Command routing
324
+ - `src/cli.tsx:628-635` - Non-UI command handling
325
+ - `src/commands/runner.ts:37-164` - Claude execution
326
+
327
+ ### Docker
328
+ - `Dockerfile.worker:6-12` - Build stage
329
+ - `Dockerfile.worker:97-104` - Binary and commands copy
330
+ - `docker-entrypoint.sh:4-13` - Environment validation
331
+ - `docker-entrypoint.sh:192-194` - Agent startup
332
+
333
+ ### System Prompts
334
+ - `src/commands/runner.ts:56-58` - System prompt injection
335
+ - `cc-plugin/commands/start-worker.md` - Worker instructions
336
+ - `cc-plugin/commands/setup-leader.md` - Lead instructions
337
+
338
+ ## Architecture Documentation
339
+
340
+ ### Proposed Secrets Table Schema
341
+
342
+ ```sql
343
+ CREATE TABLE IF NOT EXISTS secrets (
344
+ id TEXT PRIMARY KEY,
345
+ name TEXT NOT NULL UNIQUE,
346
+ value TEXT NOT NULL, -- Encrypted JSON: {encrypted, salt, iv, tag}
347
+ description TEXT DEFAULT '',
348
+ createdBy TEXT DEFAULT '', -- Agent ID or empty for system
349
+ createdAt TEXT NOT NULL,
350
+ updatedAt TEXT NOT NULL,
351
+ version INTEGER DEFAULT 1
352
+ );
353
+
354
+ CREATE INDEX IF NOT EXISTS idx_secrets_name ON secrets (name);
355
+ CREATE INDEX IF NOT EXISTS idx_secrets_createdBy ON secrets (createdBy);
356
+ ```
357
+
358
+ ### Proposed CLI Commands
359
+
360
+ | Command | Description | Access |
361
+ |---------|-------------|--------|
362
+ | `agent-secrets list` | List all secrets (no values) | All agents |
363
+ | `agent-secrets get <id>` | Get secret value | Creator or system |
364
+ | `agent-secrets create --name <n> --value <v>` | Create secret | All agents |
365
+ | `agent-secrets update <id> --value <v>` | Update secret | Creator or system |
366
+ | `agent-secrets add-to-env <id>` | Add to .env file | Creator or system |
367
+
368
+ ### Access Control Logic
369
+
370
+ ```typescript
371
+ function canAccess(secret: Secret, agentId: string): boolean {
372
+ return secret.createdBy === "" || secret.createdBy === agentId;
373
+ }
374
+ ```
375
+
376
+ ## Historical Context
377
+
378
+ No prior research documents exist for secrets management in this codebase.
379
+
380
+ ## Related Research
381
+
382
+ - `thoughts/shared/research/2025-12-19-agent-log-streaming.md` - Related agent features
383
+ - `thoughts/shared/plans/2025-12-19-role-based-swarm-plugin.md` - Related swarm architecture
384
+
385
+ ## Open Questions
386
+
387
+ 1. **Key rotation**: How should API_KEY changes affect existing encrypted secrets?
388
+ 2. **Secret sharing**: Should leads be able to create secrets accessible to specific workers?
389
+ 3. **Environment scope**: Should `add-to-env` write to container env or workspace `.env`?
390
+ 4. **Audit logging**: Should secret access be logged to `agent_log` table?