opencode-swarm 7.1.0 → 7.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -6
- package/dist/cli/index.js +10 -18
- package/dist/config/project-init.d.ts +15 -0
- package/dist/index.js +818 -798
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
<div align="center">
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
# Your AI writes the code. Swarm proves it works.
|
|
6
|
+
|
|
7
|
+
**Closing the trust gap between "the model said it's done" and "this actually works in production."**
|
|
6
8
|
|
|
7
9
|
[](https://www.npmjs.com/package/opencode-swarm)
|
|
8
10
|
[](LICENSE)
|
|
@@ -14,7 +16,7 @@
|
|
|
14
16
|
|
|
15
17
|
---
|
|
16
18
|
|
|
17
|
-
OpenCode Swarm is a plugin for [OpenCode](https://opencode.ai) that turns a single AI coding session into an **architect-led team of
|
|
19
|
+
OpenCode Swarm is a plugin for [OpenCode](https://opencode.ai) that turns a single AI coding session into an **architect-led team of specialized core, optional, and conditional agents** — see `/swarm agents` for the live roster. One agent writes the code. A different agent reviews it. Another writes and runs tests. Another checks security. **Nothing ships until every required gate passes.**
|
|
18
20
|
|
|
19
21
|
```bash
|
|
20
22
|
bunx opencode-swarm install
|
|
@@ -22,13 +24,15 @@ bunx opencode-swarm install
|
|
|
22
24
|
|
|
23
25
|
> This single command installs the package, registers it as an OpenCode plugin, disables conflicting default agents, and creates a ready-to-edit config at `~/.config/opencode/opencode-swarm.json`. Requires [Bun](https://bun.sh) (`bun --version` to check). If you must use npm: `npm install -g opencode-swarm && opencode-swarm install`.
|
|
24
26
|
|
|
27
|
+
> ⚠️ **You must select the Swarm architect mode/agent in OpenCode after install.** The default OpenCode `Build` and `Plan` modes **bypass this plugin entirely** — none of the gates, reviewers, or test agents below run. Open the OpenCode mode/agent picker and choose the Swarm architect once; it then coordinates every other agent automatically. If you ever see Swarm "do nothing," this is almost always the cause.
|
|
28
|
+
|
|
25
29
|
### Why Swarm?
|
|
26
30
|
|
|
27
31
|
Most AI coding tools let one model write code and ask that same model whether the code is good. That misses too much. Swarm separates planning, implementation, review, testing, and documentation into specialized internal roles — and enforces gated execution so agents never mutate the codebase in parallel.
|
|
28
32
|
|
|
29
33
|
### Key Features
|
|
30
34
|
|
|
31
|
-
- 🏗️ **
|
|
35
|
+
- 🏗️ **Specialized core, optional, and conditional agents** — architect, coder, reviewer, test_engineer, critic, explorer, sme, docs, designer, critic_oversight, critic_sounding_board, critic_drift_verifier, critic_hallucination_verifier, curator_init, curator_phase, council_generalist, council_skeptic, council_domain_expert. Run `/swarm agents` for the live roster — that is the source of truth, not this list.
|
|
32
36
|
- 🔒 **Gated pipeline** — code never ships without reviewer + test engineer approval
|
|
33
37
|
- 🔄 **Phase completion gates** — completion-verify and drift verifier gates enforced before phase completion
|
|
34
38
|
- 🔁 **Resumable sessions** — all state saved to `.swarm/`; pick up any project any day
|
|
@@ -37,7 +41,20 @@ Most AI coding tools let one model write code and ask that same model whether th
|
|
|
37
41
|
- 🆓 **Free tier** — works with OpenCode Zen's free model roster
|
|
38
42
|
- ⚙️ **Fully configurable** — override any agent's model, disable agents, tune guardrails
|
|
39
43
|
|
|
40
|
-
> **You select a Swarm architect once in the OpenCode GUI.** The architect coordinates all other agents automatically — you never manually switch between internal roles. If you use the default OpenCode `Build` / `Plan` modes, the plugin is bypassed entirely.
|
|
44
|
+
> **You select a Swarm architect once in the OpenCode GUI.** The architect coordinates all other agents automatically — you never manually switch between internal roles. If you use the default OpenCode `Build` / `Plan` modes, the plugin is bypassed entirely (see the install warning above).
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## What Swarm Catches
|
|
49
|
+
|
|
50
|
+
Concrete classes of failure that Swarm gates exist to stop — every item ties to an agent or pipeline gate that already runs in this repo:
|
|
51
|
+
|
|
52
|
+
- **Hallucinated APIs and citations** — `critic_hallucination_verifier` verifies referenced APIs and citations against real sources before they reach the codebase.
|
|
53
|
+
- **Missing tests and regressions** — `test_engineer` writes and runs tests on every task; the architect runs a regression sweep across the graph after each task (pipeline step `5l`).
|
|
54
|
+
- **Unsafe secret and logging patterns** — `secretscan` and `sast_scan` (63+ rules across 9 languages, offline) run as part of the per-task `pre_check_batch`.
|
|
55
|
+
- **Plan and spec drift** — `critic_drift_verifier` is a blocking phase-completion gate; `curator_phase` also flags workflow drift across phases.
|
|
56
|
+
- **Placeholders and TODO stubs** — `placeholder_scan` runs in the per-task pipeline (step `5d`) and rejects code that ships incomplete stubs.
|
|
57
|
+
- **Untrusted plans** — `critic` reviews the plan before any code is written; `completion-verify` is a deterministic phase-close gate that checks plan task identifiers actually exist in source files.
|
|
41
58
|
|
|
42
59
|
---
|
|
43
60
|
|
|
@@ -107,6 +124,62 @@ The 15-minute guide covers:
|
|
|
107
124
|
|
|
108
125
|
---
|
|
109
126
|
|
|
127
|
+
## 30-Second Demo
|
|
128
|
+
|
|
129
|
+
No animated GIF is shipped in the repo — instead, here is the exact terminal session you can record yourself with `asciinema rec demo.cast` (or any screen recorder). Every command below is real and runs against this repo as published.
|
|
130
|
+
|
|
131
|
+
**Recording script (copy/paste-able, ~30 seconds):**
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
# 1. Install the plugin (5s)
|
|
135
|
+
bunx opencode-swarm install
|
|
136
|
+
|
|
137
|
+
# 2. Open opencode and select the Swarm architect mode/agent in the picker
|
|
138
|
+
# (this step is manual in the OpenCode UI — without it, the plugin is bypassed)
|
|
139
|
+
opencode
|
|
140
|
+
|
|
141
|
+
# 3. Inside the OpenCode session, verify Swarm is live (5s)
|
|
142
|
+
/swarm diagnose
|
|
143
|
+
/swarm agents
|
|
144
|
+
|
|
145
|
+
# 4. Kick off a task — the architect plans, then gates fire automatically (15s)
|
|
146
|
+
Build me a JWT auth helper with tests.
|
|
147
|
+
|
|
148
|
+
# 5. Watch the gates land in real time (5s)
|
|
149
|
+
/swarm status
|
|
150
|
+
/swarm evidence
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**ASCII storyboard** of what a viewer should see:
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
┌──────────────────────────────────────────────────────────────┐
|
|
157
|
+
│ $ bunx opencode-swarm install │
|
|
158
|
+
│ ✓ installed opencode-swarm │
|
|
159
|
+
│ ✓ wrote ~/.config/opencode/opencode-swarm.json │
|
|
160
|
+
│ │
|
|
161
|
+
│ $ opencode │
|
|
162
|
+
│ [mode picker] → select: Swarm Architect │
|
|
163
|
+
│ │
|
|
164
|
+
│ > /swarm diagnose │
|
|
165
|
+
│ ✓ plugin loaded ✓ agents registered ✓ gates armed │
|
|
166
|
+
│ │
|
|
167
|
+
│ > Build me a JWT auth helper with tests. │
|
|
168
|
+
│ [architect] PLAN → critic gate → APPROVED │
|
|
169
|
+
│ [coder] task 1.1 implementing… │
|
|
170
|
+
│ [reviewer] correctness OK │
|
|
171
|
+
│ [test_eng.] 3 tests written, 3 pass │
|
|
172
|
+
│ [architect] regression sweep clean → phase_complete │
|
|
173
|
+
│ │
|
|
174
|
+
│ > /swarm evidence │
|
|
175
|
+
│ task 1.1: review ✓ tests ✓ sast ✓ secrets ✓ drift ✓ │
|
|
176
|
+
└──────────────────────────────────────────────────────────────┘
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Each row corresponds to a real gate documented further down this README — none are simulated.
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
110
183
|
## Upgrading
|
|
111
184
|
|
|
112
185
|
**OpenCode caches plugins indefinitely.** A normal OpenCode restart does **not**
|
|
@@ -154,7 +227,7 @@ See [docs/commands.md](docs/commands.md) for the full reference (41 commands).
|
|
|
154
227
|
|
|
155
228
|
## The Agents
|
|
156
229
|
|
|
157
|
-
Swarm
|
|
230
|
+
Swarm registers a roster of specialized core, optional, and conditional agents. The exact count shifts as agents are added or feature-flagged, so treat `/swarm agents` as the live source of truth — that command lists what is actually registered in your session. You don't manually switch between them — the architect coordinates automatically.
|
|
158
231
|
|
|
159
232
|
| Agent | Role | Badge |
|
|
160
233
|
|---|---|---|
|
|
@@ -239,7 +312,7 @@ graph TB
|
|
|
239
312
|
|
|
240
313
|
| Feature | Swarm | oh-my-opencode | get-shit-done |
|
|
241
314
|
|---|:-:|:-:|:-:|
|
|
242
|
-
| Multiple specialized agents | ✅
|
|
315
|
+
| Multiple specialized agents | ✅ Core + optional + conditional roster (`/swarm agents`) | ❌ | ❌ |
|
|
243
316
|
| Plan reviewed before coding | ✅ | ❌ | ❌ |
|
|
244
317
|
| Every task reviewed + tested | ✅ | ❌ | ❌ |
|
|
245
318
|
| Different model for review vs. code | ✅ | ❌ | ❌ |
|
package/dist/cli/index.js
CHANGED
|
@@ -33,8 +33,11 @@ var __require = import.meta.require;
|
|
|
33
33
|
var init_errors = () => {};
|
|
34
34
|
|
|
35
35
|
// src/utils/logger.ts
|
|
36
|
+
function isDebug() {
|
|
37
|
+
return process.env.OPENCODE_SWARM_DEBUG === "1";
|
|
38
|
+
}
|
|
36
39
|
function log(message, data) {
|
|
37
|
-
if (!
|
|
40
|
+
if (!isDebug())
|
|
38
41
|
return;
|
|
39
42
|
const timestamp = new Date().toISOString();
|
|
40
43
|
if (data !== undefined) {
|
|
@@ -44,7 +47,7 @@ function log(message, data) {
|
|
|
44
47
|
}
|
|
45
48
|
}
|
|
46
49
|
function warn(message, data) {
|
|
47
|
-
if (!
|
|
50
|
+
if (!isDebug())
|
|
48
51
|
return;
|
|
49
52
|
const timestamp = new Date().toISOString();
|
|
50
53
|
if (data !== undefined) {
|
|
@@ -53,10 +56,6 @@ function warn(message, data) {
|
|
|
53
56
|
console.warn(`[opencode-swarm ${timestamp}] WARN: ${message}`);
|
|
54
57
|
}
|
|
55
58
|
}
|
|
56
|
-
var DEBUG;
|
|
57
|
-
var init_logger = __esm(() => {
|
|
58
|
-
DEBUG = process.env.OPENCODE_SWARM_DEBUG === "1";
|
|
59
|
-
});
|
|
60
59
|
|
|
61
60
|
// src/utils/merge.ts
|
|
62
61
|
function deepMergeInternal(base, override, depth) {
|
|
@@ -96,7 +95,6 @@ function simpleGlobToRegex(pattern, flags = "i") {
|
|
|
96
95
|
// src/utils/index.ts
|
|
97
96
|
var init_utils = __esm(() => {
|
|
98
97
|
init_errors();
|
|
99
|
-
init_logger();
|
|
100
98
|
});
|
|
101
99
|
|
|
102
100
|
// src/utils/bun-compat.ts
|
|
@@ -18911,7 +18909,7 @@ import * as path35 from "path";
|
|
|
18911
18909
|
// package.json
|
|
18912
18910
|
var package_default = {
|
|
18913
18911
|
name: "opencode-swarm",
|
|
18914
|
-
version: "7.
|
|
18912
|
+
version: "7.2.0",
|
|
18915
18913
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
18916
18914
|
main: "dist/index.js",
|
|
18917
18915
|
types: "dist/index.d.ts",
|
|
@@ -20505,7 +20503,6 @@ function getEffectiveGates(profile, sessionOverrides) {
|
|
|
20505
20503
|
|
|
20506
20504
|
// src/hooks/delegation-gate.ts
|
|
20507
20505
|
init_telemetry();
|
|
20508
|
-
init_logger();
|
|
20509
20506
|
|
|
20510
20507
|
// node_modules/quick-lru/index.js
|
|
20511
20508
|
class QuickLRU extends Map {
|
|
@@ -20980,7 +20977,6 @@ function clearAllScopes(directory) {
|
|
|
20980
20977
|
init_telemetry();
|
|
20981
20978
|
init_utils();
|
|
20982
20979
|
init_bun_compat();
|
|
20983
|
-
init_logger();
|
|
20984
20980
|
|
|
20985
20981
|
// src/hooks/conflict-resolution.ts
|
|
20986
20982
|
init_telemetry();
|
|
@@ -34277,7 +34273,6 @@ import path13 from "path";
|
|
|
34277
34273
|
init_manager2();
|
|
34278
34274
|
|
|
34279
34275
|
// src/git/branch.ts
|
|
34280
|
-
init_logger();
|
|
34281
34276
|
import * as child_process2 from "child_process";
|
|
34282
34277
|
var GIT_TIMEOUT_MS2 = 30000;
|
|
34283
34278
|
function gitExec2(args, cwd) {
|
|
@@ -34518,7 +34513,6 @@ function resetToRemoteBranch(cwd, options) {
|
|
|
34518
34513
|
};
|
|
34519
34514
|
}
|
|
34520
34515
|
}
|
|
34521
|
-
|
|
34522
34516
|
// src/hooks/knowledge-store.ts
|
|
34523
34517
|
var import_proper_lockfile3 = __toESM(require_proper_lockfile(), 1);
|
|
34524
34518
|
import { existsSync as existsSync7 } from "fs";
|
|
@@ -34928,12 +34922,12 @@ function validateLesson(candidate, existingLessons, meta3) {
|
|
|
34928
34922
|
}
|
|
34929
34923
|
async function quarantineEntry(directory, entryId, reason, reportedBy) {
|
|
34930
34924
|
if (!directory || directory.includes("..")) {
|
|
34931
|
-
|
|
34925
|
+
warn("[knowledge-validator] quarantineEntry: directory traversal attempt blocked");
|
|
34932
34926
|
return;
|
|
34933
34927
|
}
|
|
34934
34928
|
if (!entryId || entryId.includes("\x00") || entryId.includes(`
|
|
34935
34929
|
`)) {
|
|
34936
|
-
|
|
34930
|
+
warn("[knowledge-validator] quarantineEntry: invalid entryId rejected");
|
|
34937
34931
|
return;
|
|
34938
34932
|
}
|
|
34939
34933
|
const validReportedBy = ["architect", "user", "auto"];
|
|
@@ -34993,12 +34987,12 @@ async function quarantineEntry(directory, entryId, reason, reportedBy) {
|
|
|
34993
34987
|
}
|
|
34994
34988
|
async function restoreEntry(directory, entryId) {
|
|
34995
34989
|
if (!directory || directory.includes("..")) {
|
|
34996
|
-
|
|
34990
|
+
warn("[knowledge-validator] restoreEntry: directory traversal attempt blocked");
|
|
34997
34991
|
return;
|
|
34998
34992
|
}
|
|
34999
34993
|
if (!entryId || entryId.includes("\x00") || entryId.includes(`
|
|
35000
34994
|
`)) {
|
|
35001
|
-
|
|
34995
|
+
warn("[knowledge-validator] restoreEntry: invalid entryId rejected");
|
|
35002
34996
|
return;
|
|
35003
34997
|
}
|
|
35004
34998
|
const knowledgePath = path11.join(directory, ".swarm", "knowledge.jsonl");
|
|
@@ -36257,7 +36251,6 @@ function getGlobalEventBus() {
|
|
|
36257
36251
|
// src/hooks/curator.ts
|
|
36258
36252
|
init_manager();
|
|
36259
36253
|
init_bun_compat();
|
|
36260
|
-
init_logger();
|
|
36261
36254
|
init_utils2();
|
|
36262
36255
|
|
|
36263
36256
|
// src/hooks/hive-promoter.ts
|
|
@@ -40358,7 +40351,6 @@ ${USAGE2}`;
|
|
|
40358
40351
|
import { join as join22 } from "path";
|
|
40359
40352
|
|
|
40360
40353
|
// src/hooks/knowledge-migrator.ts
|
|
40361
|
-
init_logger();
|
|
40362
40354
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
40363
40355
|
import { existsSync as existsSync13, readFileSync as readFileSync10 } from "fs";
|
|
40364
40356
|
import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile5 } from "fs/promises";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates .opencode/opencode-swarm.json in the given directory if it does not
|
|
3
|
+
* already exist. Uses an atomic exclusive write (flag 'wx') so concurrent
|
|
4
|
+
* plugin loads never double-write or corrupt the file.
|
|
5
|
+
*
|
|
6
|
+
* Non-fatal: any fs error (permissions, disk full, etc.) is swallowed so the
|
|
7
|
+
* plugin continues with its default or global config.
|
|
8
|
+
*/
|
|
9
|
+
export declare function writeProjectConfigIfNew(directory: string, quiet?: boolean): void;
|
|
10
|
+
/**
|
|
11
|
+
* Writes .swarm/config.example.json on first plugin init for a given project.
|
|
12
|
+
* Creates .swarm/ if it does not yet exist. Non-fatal: all errors are silently
|
|
13
|
+
* ignored.
|
|
14
|
+
*/
|
|
15
|
+
export declare function writeSwarmConfigExampleIfNew(projectDirectory: string): void;
|