opencode-swarm 7.1.0 → 7.1.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.
- package/README.md +79 -6
- package/dist/cli/index.js +10 -18
- package/dist/index.js +19 -37
- 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.1.
|
|
18912
|
+
version: "7.1.1",
|
|
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";
|
package/dist/index.js
CHANGED
|
@@ -33,7 +33,7 @@ var package_default;
|
|
|
33
33
|
var init_package = __esm(() => {
|
|
34
34
|
package_default = {
|
|
35
35
|
name: "opencode-swarm",
|
|
36
|
-
version: "7.1.
|
|
36
|
+
version: "7.1.1",
|
|
37
37
|
description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
38
38
|
main: "dist/index.js",
|
|
39
39
|
types: "dist/index.d.ts",
|
|
@@ -15873,8 +15873,11 @@ var init_errors3 = __esm(() => {
|
|
|
15873
15873
|
});
|
|
15874
15874
|
|
|
15875
15875
|
// src/utils/logger.ts
|
|
15876
|
+
function isDebug() {
|
|
15877
|
+
return process.env.OPENCODE_SWARM_DEBUG === "1";
|
|
15878
|
+
}
|
|
15876
15879
|
function log(message, data) {
|
|
15877
|
-
if (!
|
|
15880
|
+
if (!isDebug())
|
|
15878
15881
|
return;
|
|
15879
15882
|
const timestamp = new Date().toISOString();
|
|
15880
15883
|
if (data !== undefined) {
|
|
@@ -15884,7 +15887,7 @@ function log(message, data) {
|
|
|
15884
15887
|
}
|
|
15885
15888
|
}
|
|
15886
15889
|
function warn(message, data) {
|
|
15887
|
-
if (!
|
|
15890
|
+
if (!isDebug())
|
|
15888
15891
|
return;
|
|
15889
15892
|
const timestamp = new Date().toISOString();
|
|
15890
15893
|
if (data !== undefined) {
|
|
@@ -15901,10 +15904,6 @@ function error48(message, data) {
|
|
|
15901
15904
|
console.error(`[opencode-swarm ${timestamp}] ERROR: ${message}`);
|
|
15902
15905
|
}
|
|
15903
15906
|
}
|
|
15904
|
-
var DEBUG;
|
|
15905
|
-
var init_logger = __esm(() => {
|
|
15906
|
-
DEBUG = process.env.OPENCODE_SWARM_DEBUG === "1";
|
|
15907
|
-
});
|
|
15908
15907
|
|
|
15909
15908
|
// src/utils/regex.ts
|
|
15910
15909
|
function escapeRegex2(s) {
|
|
@@ -15918,7 +15917,6 @@ function simpleGlobToRegex(pattern, flags2 = "i") {
|
|
|
15918
15917
|
// src/utils/index.ts
|
|
15919
15918
|
var init_utils = __esm(() => {
|
|
15920
15919
|
init_errors3();
|
|
15921
|
-
init_logger();
|
|
15922
15920
|
});
|
|
15923
15921
|
|
|
15924
15922
|
// src/utils/bun-compat.ts
|
|
@@ -25138,7 +25136,6 @@ var init_guardrails = __esm(() => {
|
|
|
25138
25136
|
init_telemetry();
|
|
25139
25137
|
init_utils();
|
|
25140
25138
|
init_bun_compat();
|
|
25141
|
-
init_logger();
|
|
25142
25139
|
init_conflict_resolution();
|
|
25143
25140
|
init_delegation_gate();
|
|
25144
25141
|
init_loop_detector();
|
|
@@ -26098,7 +26095,6 @@ var init_delegation_gate = __esm(() => {
|
|
|
26098
26095
|
init_schema();
|
|
26099
26096
|
init_state();
|
|
26100
26097
|
init_telemetry();
|
|
26101
|
-
init_logger();
|
|
26102
26098
|
init_guardrails();
|
|
26103
26099
|
init_normalize_tool_name();
|
|
26104
26100
|
init_utils2();
|
|
@@ -40586,9 +40582,7 @@ function resetToRemoteBranch(cwd, options) {
|
|
|
40586
40582
|
}
|
|
40587
40583
|
}
|
|
40588
40584
|
var GIT_TIMEOUT_MS2 = 30000;
|
|
40589
|
-
var init_branch =
|
|
40590
|
-
init_logger();
|
|
40591
|
-
});
|
|
40585
|
+
var init_branch = () => {};
|
|
40592
40586
|
|
|
40593
40587
|
// src/hooks/knowledge-store.ts
|
|
40594
40588
|
import { existsSync as existsSync9 } from "node:fs";
|
|
@@ -40915,7 +40909,7 @@ async function recordLessonsShown(directory, lessonIds, currentPhase) {
|
|
|
40915
40909
|
await mkdir4(path16.dirname(shownFile), { recursive: true });
|
|
40916
40910
|
await writeFile4(shownFile, JSON.stringify(shownData, null, 2), "utf-8");
|
|
40917
40911
|
} catch {
|
|
40918
|
-
|
|
40912
|
+
warn("[swarm] Knowledge: failed to record shown lessons");
|
|
40919
40913
|
}
|
|
40920
40914
|
}
|
|
40921
40915
|
async function readMergedKnowledge(directory, config3, context) {
|
|
@@ -41065,7 +41059,7 @@ async function updateRetrievalOutcome(directory, phaseInfo, phaseSucceeded) {
|
|
|
41065
41059
|
delete shownData[phaseInfo];
|
|
41066
41060
|
await writeFile4(shownFile, JSON.stringify(shownData, null, 2), "utf-8");
|
|
41067
41061
|
} catch {
|
|
41068
|
-
|
|
41062
|
+
warn("[swarm] Knowledge: failed to update retrieval outcomes");
|
|
41069
41063
|
}
|
|
41070
41064
|
}
|
|
41071
41065
|
var JACCARD_THRESHOLD = 0.6, HIVE_TIER_BOOST = 0.05, SAME_PROJECT_PENALTY = -0.05;
|
|
@@ -41216,12 +41210,12 @@ function validateLesson(candidate, existingLessons, meta3) {
|
|
|
41216
41210
|
}
|
|
41217
41211
|
async function quarantineEntry(directory, entryId, reason, reportedBy) {
|
|
41218
41212
|
if (!directory || directory.includes("..")) {
|
|
41219
|
-
|
|
41213
|
+
warn("[knowledge-validator] quarantineEntry: directory traversal attempt blocked");
|
|
41220
41214
|
return;
|
|
41221
41215
|
}
|
|
41222
41216
|
if (!entryId || entryId.includes("\x00") || entryId.includes(`
|
|
41223
41217
|
`)) {
|
|
41224
|
-
|
|
41218
|
+
warn("[knowledge-validator] quarantineEntry: invalid entryId rejected");
|
|
41225
41219
|
return;
|
|
41226
41220
|
}
|
|
41227
41221
|
const validReportedBy = ["architect", "user", "auto"];
|
|
@@ -41281,12 +41275,12 @@ async function quarantineEntry(directory, entryId, reason, reportedBy) {
|
|
|
41281
41275
|
}
|
|
41282
41276
|
async function restoreEntry(directory, entryId) {
|
|
41283
41277
|
if (!directory || directory.includes("..")) {
|
|
41284
|
-
|
|
41278
|
+
warn("[knowledge-validator] restoreEntry: directory traversal attempt blocked");
|
|
41285
41279
|
return;
|
|
41286
41280
|
}
|
|
41287
41281
|
if (!entryId || entryId.includes("\x00") || entryId.includes(`
|
|
41288
41282
|
`)) {
|
|
41289
|
-
|
|
41283
|
+
warn("[knowledge-validator] restoreEntry: invalid entryId rejected");
|
|
41290
41284
|
return;
|
|
41291
41285
|
}
|
|
41292
41286
|
const knowledgePath = path17.join(directory, ".swarm", "knowledge.jsonl");
|
|
@@ -43245,9 +43239,7 @@ async function readCuratorSummary(directory) {
|
|
|
43245
43239
|
}
|
|
43246
43240
|
return parsed;
|
|
43247
43241
|
} catch {
|
|
43248
|
-
|
|
43249
|
-
console.warn("Failed to parse curator-summary.json: invalid JSON");
|
|
43250
|
-
}
|
|
43242
|
+
warn("Failed to parse curator-summary.json: invalid JSON");
|
|
43251
43243
|
return null;
|
|
43252
43244
|
}
|
|
43253
43245
|
}
|
|
@@ -43280,9 +43272,7 @@ function filterPhaseEvents(eventsJsonl, phase, sinceTimestamp) {
|
|
|
43280
43272
|
}
|
|
43281
43273
|
}
|
|
43282
43274
|
} catch {
|
|
43283
|
-
|
|
43284
|
-
console.warn("filterPhaseEvents: skipping malformed line");
|
|
43285
|
-
}
|
|
43275
|
+
warn("filterPhaseEvents: skipping malformed line");
|
|
43286
43276
|
}
|
|
43287
43277
|
}
|
|
43288
43278
|
return filtered;
|
|
@@ -43831,7 +43821,6 @@ var init_curator = __esm(() => {
|
|
|
43831
43821
|
init_event_bus();
|
|
43832
43822
|
init_manager();
|
|
43833
43823
|
init_bun_compat();
|
|
43834
|
-
init_logger();
|
|
43835
43824
|
init_knowledge_store();
|
|
43836
43825
|
init_knowledge_validator();
|
|
43837
43826
|
init_utils2();
|
|
@@ -49256,7 +49245,6 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
|
|
|
49256
49245
|
await writeFile6(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
|
|
49257
49246
|
}
|
|
49258
49247
|
var init_knowledge_migrator = __esm(() => {
|
|
49259
|
-
init_logger();
|
|
49260
49248
|
init_knowledge_store();
|
|
49261
49249
|
init_knowledge_validator();
|
|
49262
49250
|
});
|
|
@@ -60446,7 +60434,6 @@ var init_preflight_integration = __esm(() => {
|
|
|
60446
60434
|
init_status_artifact();
|
|
60447
60435
|
init_trigger();
|
|
60448
60436
|
init_preflight_service();
|
|
60449
|
-
init_logger();
|
|
60450
60437
|
});
|
|
60451
60438
|
|
|
60452
60439
|
// node_modules/web-tree-sitter/tree-sitter.js
|
|
@@ -64493,7 +64480,6 @@ function buildDriftInjectionText(report, maxChars) {
|
|
|
64493
64480
|
var DRIFT_REPORT_PREFIX = "drift-report-phase-";
|
|
64494
64481
|
var init_curator_drift = __esm(() => {
|
|
64495
64482
|
init_event_bus();
|
|
64496
|
-
init_logger();
|
|
64497
64483
|
init_utils2();
|
|
64498
64484
|
});
|
|
64499
64485
|
|
|
@@ -65721,7 +65707,6 @@ init_schema();
|
|
|
65721
65707
|
init_file_locks();
|
|
65722
65708
|
init_state();
|
|
65723
65709
|
init_telemetry();
|
|
65724
|
-
init_logger();
|
|
65725
65710
|
init_utils2();
|
|
65726
65711
|
import * as fs33 from "node:fs";
|
|
65727
65712
|
var END_OF_SENTENCE_QUESTION_PATTERN = /\?\s*$/;
|
|
@@ -66513,7 +66498,6 @@ import * as path52 from "node:path";
|
|
|
66513
66498
|
|
|
66514
66499
|
// src/tools/repo-graph.ts
|
|
66515
66500
|
init_utils2();
|
|
66516
|
-
init_logger();
|
|
66517
66501
|
init_path_security();
|
|
66518
66502
|
import * as fsSync3 from "node:fs";
|
|
66519
66503
|
import { constants as constants4, existsSync as existsSync28, realpathSync as realpathSync6 } from "node:fs";
|
|
@@ -67645,9 +67629,7 @@ async function updateGraphForFiles(workspaceRoot, filePaths, options) {
|
|
|
67645
67629
|
await saveGraph(workspaceRoot, graph);
|
|
67646
67630
|
return graph;
|
|
67647
67631
|
}
|
|
67648
|
-
|
|
67649
67632
|
// src/hooks/repo-graph-builder.ts
|
|
67650
|
-
init_logger();
|
|
67651
67633
|
var SUPPORTED_EXTENSIONS2 = [
|
|
67652
67634
|
".ts",
|
|
67653
67635
|
".tsx",
|
|
@@ -70768,15 +70750,15 @@ function createSystemEnhancerHook(config3, directory) {
|
|
|
70768
70750
|
const existingLessons = new Set(existingEntries.map((e) => e.lesson));
|
|
70769
70751
|
const newEntries = knowledgeEntries.filter((e) => !existingLessons.has(e.lesson));
|
|
70770
70752
|
if (newEntries.length === 0) {
|
|
70771
|
-
|
|
70753
|
+
warn(`[system-enhancer] No new knowledge entries (all duplicates)`);
|
|
70772
70754
|
} else {
|
|
70773
70755
|
for (const entry of newEntries) {
|
|
70774
70756
|
await appendKnowledge(knowledgePath, entry);
|
|
70775
70757
|
}
|
|
70776
|
-
|
|
70758
|
+
warn(`[system-enhancer] Created ${newEntries.length} new knowledge entries (${knowledgeEntries.length - newEntries.length} duplicates skipped)`);
|
|
70777
70759
|
}
|
|
70778
70760
|
} catch (e) {
|
|
70779
|
-
|
|
70761
|
+
warn(`[system-enhancer] Failed to create knowledge entries: ${e}`);
|
|
70780
70762
|
}
|
|
70781
70763
|
}
|
|
70782
70764
|
}
|
|
@@ -72477,7 +72459,7 @@ function createKnowledgeInjectorHook(directory, config3) {
|
|
|
72477
72459
|
const headroomChars = MODEL_LIMIT_CHARS - existingChars;
|
|
72478
72460
|
const MIN_INJECT_CHARS = config3.context_budget_threshold ?? 300;
|
|
72479
72461
|
if (headroomChars < MIN_INJECT_CHARS) {
|
|
72480
|
-
|
|
72462
|
+
warn(`[knowledge-injector] Skipping: only ${headroomChars} chars of headroom remain (existing: ${existingChars}, limit: ${MODEL_LIMIT_CHARS})`);
|
|
72481
72463
|
return;
|
|
72482
72464
|
}
|
|
72483
72465
|
const maxInjectChars = config3.inject_char_budget ?? 2000;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "7.1.
|
|
3
|
+
"version": "7.1.1",
|
|
4
4
|
"description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|