@heretek-ai/epistemic-swarm 0.7.5 → 0.7.7
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/.claude-plugin/plugin.json +1 -1
- package/config/opencode-snippet.json +102 -149
- package/install.sh +81 -58
- package/package.json +1 -1
- package/plugins/opencode/index.js +283 -0
- package/runner/__pycache__/__init__.cpython-311.pyc +0 -0
- package/runner/__pycache__/auctioneer.cpython-311.pyc +0 -0
- package/runner/__pycache__/auditor_engine.cpython-311.pyc +0 -0
- package/runner/__pycache__/claim_store.cpython-311.pyc +0 -0
- package/runner/__pycache__/claim_witness.cpython-311.pyc +0 -0
- package/runner/__pycache__/living_dossiers.cpython-311.pyc +0 -0
- package/runner/__pycache__/mcp_protocol.cpython-311.pyc +0 -0
- package/runner/__pycache__/mcp_server.cpython-311.pyc +0 -0
- package/runner/__pycache__/path_safety.cpython-311.pyc +0 -0
- package/runner/__pycache__/pcrb.cpython-311.pyc +0 -0
- package/runner/__pycache__/pcrb_verify.cpython-311.pyc +0 -0
- package/runner/__pycache__/refinement.cpython-311.pyc +0 -0
- package/runner/__pycache__/research_swarm.cpython-311.pyc +0 -0
- package/runner/__pycache__/state_machine.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_auction_order.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_backends.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_bet1_spike.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_claim_store.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_claim_witness.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_claude_plugin.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_domain_packs.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_factory.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_fleet_seam.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_living_dossiers.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_mcp_server.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_opencode_ux.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_opencode_v2_registrars.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_pcrb.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_refinement.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_swarm.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_sweep_regressions.cpython-311.pyc +0 -0
- package/runner/tests/__pycache__/test_webcache.cpython-311.pyc +0 -0
- package/runner/tests/test_factory.py +15 -7
- package/runner/tests/test_opencode_ux.py +37 -27
- package/runner/tests/test_opencode_v2_registrars.py +260 -0
- package/scripts/__pycache__/bet1_advisory_spike.cpython-311.pyc +0 -0
- package/scripts/__pycache__/build_adapters.cpython-311.pyc +0 -0
- package/scripts/__pycache__/divergence_experiment.cpython-311.pyc +0 -0
- package/skills/epistemic_search/scripts/__pycache__/search.cpython-311.pyc +0 -0
- package/skills/research_cache/__pycache__/__init__.cpython-311.pyc +0 -0
- package/skills/research_cache/__pycache__/hasher.cpython-311.pyc +0 -0
- package/skills/swarm_config/__pycache__/__init__.cpython-311.pyc +0 -0
- package/skills/swarm_config/__pycache__/configure.cpython-311.pyc +0 -0
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://opencode.ai/config.json",
|
|
3
3
|
"mcp": {
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
"servers": {
|
|
5
|
+
"iumbtems": {
|
|
6
|
+
"type": "local",
|
|
7
|
+
"command": ["python3", "<IUMBTEMS_ROOT>/runner/mcp_server.py"],
|
|
8
|
+
"enabled": true
|
|
9
|
+
}
|
|
8
10
|
}
|
|
9
11
|
},
|
|
10
12
|
"plugins": [
|
|
@@ -17,187 +19,138 @@
|
|
|
17
19
|
}
|
|
18
20
|
}
|
|
19
21
|
],
|
|
20
|
-
"
|
|
22
|
+
"agents": {
|
|
21
23
|
"code-auditor": {
|
|
22
24
|
"description": "IUMBTEMS Codebase Auditor: Dialectic architecture mapping and vulnerability red-teaming with line-level proof.",
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
"
|
|
26
|
-
"grep":
|
|
27
|
-
"glob":
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
|
|
25
|
+
"mode": "all",
|
|
26
|
+
"permissions": [
|
|
27
|
+
{ "action": "read", "resource": "*", "effect": "allow" },
|
|
28
|
+
{ "action": "grep", "resource": "*", "effect": "allow" },
|
|
29
|
+
{ "action": "glob", "resource": "*", "effect": "allow" },
|
|
30
|
+
{ "action": "edit", "resource": "*", "effect": "allow" },
|
|
31
|
+
{ "action": "shell", "resource": "*", "effect": "ask" }
|
|
32
|
+
]
|
|
31
33
|
},
|
|
32
34
|
"oss-scout": {
|
|
33
35
|
"description": "IUMBTEMS Open Source Scout: Discovers mature OSS packages, audits copyleft licensing, and generates clean-room blueprints.",
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
"
|
|
37
|
-
"grep":
|
|
38
|
-
"glob":
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
|
|
36
|
+
"mode": "all",
|
|
37
|
+
"permissions": [
|
|
38
|
+
{ "action": "read", "resource": "*", "effect": "allow" },
|
|
39
|
+
{ "action": "grep", "resource": "*", "effect": "allow" },
|
|
40
|
+
{ "action": "glob", "resource": "*", "effect": "allow" },
|
|
41
|
+
{ "action": "edit", "resource": "*", "effect": "allow" },
|
|
42
|
+
{ "action": "shell", "resource": "*", "effect": "ask" }
|
|
43
|
+
]
|
|
42
44
|
},
|
|
43
45
|
"alpha-thesis": {
|
|
44
46
|
"description": "IUMBTEMS Proponent Agent: Gathers corroborating primary sources, benchmark results, and empirical proofs.",
|
|
45
|
-
"
|
|
46
|
-
|
|
47
|
-
"read":
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
"iumbtems_config": true
|
|
55
|
-
}
|
|
47
|
+
"mode": "all",
|
|
48
|
+
"permissions": [
|
|
49
|
+
{ "action": "read", "resource": "*", "effect": "allow" },
|
|
50
|
+
{ "action": "grep", "resource": "*", "effect": "allow" },
|
|
51
|
+
{ "action": "glob", "resource": "*", "effect": "allow" },
|
|
52
|
+
{ "action": "edit", "resource": "*", "effect": "allow" },
|
|
53
|
+
{ "action": "shell", "resource": "*", "effect": "ask" },
|
|
54
|
+
{ "action": "subagent", "resource": "*", "effect": "allow" }
|
|
55
|
+
]
|
|
56
56
|
},
|
|
57
57
|
"beta-redteam": {
|
|
58
58
|
"description": "IUMBTEMS Adversary Agent: Active falsification, red-teaming, hunting for counter-benchmarks, and edge-case failure modes.",
|
|
59
|
-
"
|
|
60
|
-
|
|
61
|
-
"read":
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
|
|
68
|
-
}
|
|
59
|
+
"mode": "all",
|
|
60
|
+
"permissions": [
|
|
61
|
+
{ "action": "read", "resource": "*", "effect": "allow" },
|
|
62
|
+
{ "action": "grep", "resource": "*", "effect": "allow" },
|
|
63
|
+
{ "action": "glob", "resource": "*", "effect": "allow" },
|
|
64
|
+
{ "action": "edit", "resource": "*", "effect": "allow" },
|
|
65
|
+
{ "action": "shell", "resource": "*", "effect": "ask" },
|
|
66
|
+
{ "action": "subagent", "resource": "*", "effect": "allow" }
|
|
67
|
+
]
|
|
69
68
|
},
|
|
70
69
|
"epistemic-auditor": {
|
|
71
70
|
"description": "IUMBTEMS Synthesizer & Auditor: Verifies verbatim source quotes, downgrades unverified claims, and calculates divergence.",
|
|
72
|
-
"
|
|
73
|
-
|
|
74
|
-
"
|
|
75
|
-
"grep":
|
|
76
|
-
"glob":
|
|
77
|
-
"
|
|
78
|
-
|
|
71
|
+
"mode": "all",
|
|
72
|
+
"permissions": [
|
|
73
|
+
{ "action": "read", "resource": "*", "effect": "allow" },
|
|
74
|
+
{ "action": "grep", "resource": "*", "effect": "allow" },
|
|
75
|
+
{ "action": "glob", "resource": "*", "effect": "allow" },
|
|
76
|
+
{ "action": "edit", "resource": "*", "effect": "allow" }
|
|
77
|
+
]
|
|
79
78
|
},
|
|
80
79
|
"brainstormer": {
|
|
81
80
|
"description": "IUMBTEMS Lateral Brainstormer: divergent what-if features, paradigm inversions, falsifiable spikes (never bug fixes).",
|
|
82
|
-
"
|
|
83
|
-
|
|
84
|
-
"
|
|
85
|
-
"grep":
|
|
86
|
-
"glob":
|
|
87
|
-
"
|
|
88
|
-
|
|
89
|
-
}
|
|
81
|
+
"mode": "all",
|
|
82
|
+
"permissions": [
|
|
83
|
+
{ "action": "read", "resource": "*", "effect": "allow" },
|
|
84
|
+
{ "action": "grep", "resource": "*", "effect": "allow" },
|
|
85
|
+
{ "action": "glob", "resource": "*", "effect": "allow" },
|
|
86
|
+
{ "action": "edit", "resource": "*", "effect": "allow" }
|
|
87
|
+
]
|
|
90
88
|
},
|
|
91
89
|
"darkharvester": {
|
|
92
90
|
"description": "IUMBTEMS Competitor Teardown: seed plus expand, product plus code matrix, per-feature harvest verdicts with SPDX attribution.",
|
|
93
|
-
"
|
|
94
|
-
|
|
95
|
-
"
|
|
96
|
-
"grep":
|
|
97
|
-
"glob":
|
|
98
|
-
"
|
|
99
|
-
|
|
100
|
-
"iumbtems_config": true
|
|
101
|
-
}
|
|
91
|
+
"mode": "all",
|
|
92
|
+
"permissions": [
|
|
93
|
+
{ "action": "read", "resource": "*", "effect": "allow" },
|
|
94
|
+
{ "action": "grep", "resource": "*", "effect": "allow" },
|
|
95
|
+
{ "action": "glob", "resource": "*", "effect": "allow" },
|
|
96
|
+
{ "action": "edit", "resource": "*", "effect": "allow" }
|
|
97
|
+
]
|
|
102
98
|
},
|
|
103
99
|
"manager": {
|
|
104
100
|
"description": "IUMBTEMS Factory Manager: grill-gated phased builds. Owns gates, swarm dispatch, roadmap synthesis, QA tiebreaks. Never writes code.",
|
|
105
101
|
"mode": "primary",
|
|
106
|
-
"
|
|
107
|
-
"
|
|
108
|
-
"edit": "deny",
|
|
109
|
-
"
|
|
110
|
-
"
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
"darkharvester": "allow"
|
|
118
|
-
}
|
|
119
|
-
},
|
|
120
|
-
"tools": {
|
|
121
|
-
"read": true,
|
|
122
|
-
"write": true,
|
|
123
|
-
"grep": true,
|
|
124
|
-
"glob": true,
|
|
125
|
-
"task": true,
|
|
126
|
-
"iumbtems_brainstorm": true,
|
|
127
|
-
"iumbtems_darkharvest": true,
|
|
128
|
-
"iumbtems_verify_quote": true,
|
|
129
|
-
"iumbtems_socratic_frontier": true,
|
|
130
|
-
"iumbtems_config": true
|
|
131
|
-
}
|
|
102
|
+
"system": "You are the IUMBTEMS Factory Manager. Own gate discipline: grill until the frontier is settled, run the brainstorm and darkharvest swarms, synthesize .roadmap phase dossiers, spawn the programmer per phase, run qa-a and qa-b, and tiebreak their disagreements. Never write implementation code. Use the iumbtems_factory tool for run state. Explicit user approval advances each gate.",
|
|
103
|
+
"permissions": [
|
|
104
|
+
{ "action": "edit", "resource": "*", "effect": "deny" },
|
|
105
|
+
{ "action": "shell", "resource": "*", "effect": "ask" },
|
|
106
|
+
{ "action": "subagent", "resource": "*", "effect": "deny" },
|
|
107
|
+
{ "action": "subagent", "resource": "programmer", "effect": "allow" },
|
|
108
|
+
{ "action": "subagent", "resource": "qa-a", "effect": "allow" },
|
|
109
|
+
{ "action": "subagent", "resource": "qa-b", "effect": "allow" },
|
|
110
|
+
{ "action": "subagent", "resource": "brainstormer", "effect": "allow" },
|
|
111
|
+
{ "action": "subagent", "resource": "darkharvester", "effect": "allow" }
|
|
112
|
+
]
|
|
132
113
|
},
|
|
133
114
|
"programmer": {
|
|
134
115
|
"description": "IUMBTEMS Factory Programmer: implements exactly one phase brief per spawn. Cites phase evidence hashes. Never invokes swarms or other programmers.",
|
|
135
116
|
"mode": "subagent",
|
|
136
|
-
"
|
|
137
|
-
"
|
|
138
|
-
"edit": "allow",
|
|
139
|
-
"
|
|
140
|
-
"
|
|
141
|
-
|
|
142
|
-
}
|
|
143
|
-
},
|
|
144
|
-
"tools": {
|
|
145
|
-
"read": true,
|
|
146
|
-
"write": true,
|
|
147
|
-
"bash": true,
|
|
148
|
-
"grep": true,
|
|
149
|
-
"glob": true,
|
|
150
|
-
"iumbtems_verify_quote": true
|
|
151
|
-
}
|
|
117
|
+
"system": "You are the IUMBTEMS Factory Programmer. Implement exactly one phase brief per spawn. Cite phase evidence hashes. Never invoke swarms or other programmers. If the brief is ambiguous or untestable, stop and ask the manager.",
|
|
118
|
+
"permissions": [
|
|
119
|
+
{ "action": "edit", "resource": "*", "effect": "allow" },
|
|
120
|
+
{ "action": "shell", "resource": "*", "effect": "ask" },
|
|
121
|
+
{ "action": "subagent", "resource": "*", "effect": "deny" }
|
|
122
|
+
]
|
|
152
123
|
},
|
|
153
124
|
"qa-a": {
|
|
154
125
|
"description": "IUMBTEMS Factory QA (functional): verifies phase acceptance criteria pass on the real surface. Read-only plus test execution. Diverged prompt from qa-b.",
|
|
155
126
|
"mode": "subagent",
|
|
156
|
-
"
|
|
157
|
-
"
|
|
158
|
-
"edit": "deny",
|
|
159
|
-
"
|
|
160
|
-
"
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
},
|
|
164
|
-
"tools": {
|
|
165
|
-
"read": true,
|
|
166
|
-
"bash": true,
|
|
167
|
-
"grep": true,
|
|
168
|
-
"glob": true
|
|
169
|
-
}
|
|
127
|
+
"system": "You are the IUMBTEMS Factory functional QA. Verify each phase acceptance criterion on the real surface with tests and inspection. Read-only plus test execution; never edit code. Return pass|fail(reason)|conditional(note).",
|
|
128
|
+
"permissions": [
|
|
129
|
+
{ "action": "edit", "resource": "*", "effect": "deny" },
|
|
130
|
+
{ "action": "shell", "resource": "*", "effect": "ask" },
|
|
131
|
+
{ "action": "subagent", "resource": "*", "effect": "deny" }
|
|
132
|
+
]
|
|
170
133
|
},
|
|
171
134
|
"qa-b": {
|
|
172
135
|
"description": "IUMBTEMS Factory QA (adversarial): hunts edge cases, regressions, and acceptance loopholes the functional pass missed. Read-only plus test execution. Diverged prompt from qa-a.",
|
|
173
136
|
"mode": "subagent",
|
|
174
|
-
"
|
|
175
|
-
"
|
|
176
|
-
"edit": "deny",
|
|
177
|
-
"
|
|
178
|
-
"
|
|
179
|
-
|
|
180
|
-
}
|
|
181
|
-
},
|
|
182
|
-
"tools": {
|
|
183
|
-
"read": true,
|
|
184
|
-
"bash": true,
|
|
185
|
-
"grep": true,
|
|
186
|
-
"glob": true
|
|
187
|
-
}
|
|
137
|
+
"system": "You are the IUMBTEMS Factory adversarial QA. Attack the phase: edge cases, regressions, vacuous acceptance criteria, error paths, resource limits. Read-only plus test execution; never edit code. Return pass|fail(reason)|conditional(note) with reproductions.",
|
|
138
|
+
"permissions": [
|
|
139
|
+
{ "action": "edit", "resource": "*", "effect": "deny" },
|
|
140
|
+
{ "action": "shell", "resource": "*", "effect": "ask" },
|
|
141
|
+
{ "action": "subagent", "resource": "*", "effect": "deny" }
|
|
142
|
+
]
|
|
188
143
|
}
|
|
189
144
|
},
|
|
190
|
-
"skills":
|
|
191
|
-
"
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
]
|
|
202
|
-
}
|
|
145
|
+
"skills": [
|
|
146
|
+
"./skills/grilling",
|
|
147
|
+
"./skills/research_cache",
|
|
148
|
+
"./skills/epistemic_search",
|
|
149
|
+
"./skills/swarm_config",
|
|
150
|
+
"./skills/code_audit",
|
|
151
|
+
"./skills/oss_scout",
|
|
152
|
+
"./skills/brainstorming",
|
|
153
|
+
"./skills/darkharvest",
|
|
154
|
+
"./skills/factory"
|
|
155
|
+
]
|
|
203
156
|
}
|
package/install.sh
CHANGED
|
@@ -109,7 +109,7 @@ except Exception as e:
|
|
|
109
109
|
EOF
|
|
110
110
|
fi
|
|
111
111
|
|
|
112
|
-
# 5. OpenCode V2 integration (
|
|
112
|
+
# 5. OpenCode V2 integration (plugins/agents/skills/mcp.servers — merge only)
|
|
113
113
|
OPENCODE_JSON="$HOME/.config/opencode/opencode.json"
|
|
114
114
|
echo "🔧 Merging OpenCode V2 configuration into $OPENCODE_JSON..."
|
|
115
115
|
python3 - <<EOF
|
|
@@ -124,91 +124,114 @@ OPTION_KEYS = {"search_engine", "max_iterations", "mode", "divergence_threshold"
|
|
|
124
124
|
oc_path.parent.mkdir(parents=True, exist_ok=True)
|
|
125
125
|
cfg = json.loads(oc_path.read_text(encoding="utf-8")) if oc_path.exists() else {}
|
|
126
126
|
|
|
127
|
-
# ---
|
|
128
|
-
plugins = cfg.get("
|
|
127
|
+
# --- plugins (V2): object form {"package", "options"}; migrate legacy `plugin` ---
|
|
128
|
+
plugins = cfg.get("plugins")
|
|
129
129
|
if not isinstance(plugins, list):
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
130
|
+
plugins = []
|
|
131
|
+
|
|
132
|
+
# Migrate any legacy V1 `plugin` entries: bare strings, [pkg, options] tuples,
|
|
133
|
+
# and the "wild" malformation where a bare options object trails our package.
|
|
134
|
+
legacy = cfg.get("plugin")
|
|
135
|
+
if isinstance(legacy, list):
|
|
134
136
|
i = 0
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
item
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
)
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
merged = {**(repaired[-1][1] if len(repaired[-1]) > 1 else {}), **item}
|
|
152
|
-
repaired[-1] = [PKG, merged]
|
|
153
|
-
changed = True
|
|
154
|
-
print(" ~ Folded stray options into existing tuple entry")
|
|
137
|
+
while i < len(legacy):
|
|
138
|
+
item = legacy[i]
|
|
139
|
+
if isinstance(item, str):
|
|
140
|
+
if item == PKG and i + 1 < len(legacy) and isinstance(legacy[i + 1], dict) and (set(legacy[i + 1]) & OPTION_KEYS):
|
|
141
|
+
plugins.append({"package": PKG, "options": legacy[i + 1]})
|
|
142
|
+
i += 2
|
|
143
|
+
continue
|
|
144
|
+
plugins.append(item)
|
|
145
|
+
elif isinstance(item, list) and item:
|
|
146
|
+
opts = item[1] if len(item) > 1 and isinstance(item[1], dict) else {}
|
|
147
|
+
plugins.append({"package": item[0], "options": opts})
|
|
148
|
+
elif isinstance(item, dict):
|
|
149
|
+
if "package" in item:
|
|
150
|
+
plugins.append(item)
|
|
151
|
+
elif set(item) & OPTION_KEYS:
|
|
152
|
+
plugins.append({"package": PKG, "options": item})
|
|
155
153
|
else:
|
|
156
|
-
|
|
157
|
-
changed = True
|
|
158
|
-
print(" ~ Attached stray options object to new tuple entry")
|
|
159
|
-
else:
|
|
160
|
-
repaired.append(item)
|
|
154
|
+
plugins.append(item)
|
|
161
155
|
i += 1
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
156
|
+
cfg.pop("plugin", None)
|
|
157
|
+
print(" ~ Migrated legacy 'plugin' entries to V2 'plugins' (object form)")
|
|
158
|
+
|
|
159
|
+
# Normalize our entry to the V2 object form and ensure default options exist.
|
|
160
|
+
DEFAULT_OPTIONS = {"search_engine": "duckduckgo", "max_iterations": 2, "mode": "research"}
|
|
161
|
+
our = None
|
|
162
|
+
for idx, entry in enumerate(plugins):
|
|
163
|
+
if entry == PKG:
|
|
164
|
+
our = {"package": PKG, "options": {}}
|
|
165
|
+
plugins[idx] = our
|
|
166
|
+
elif isinstance(entry, dict) and entry.get("package") == PKG:
|
|
167
|
+
our = entry
|
|
168
|
+
entry["options"] = {**DEFAULT_OPTIONS, **(entry.get("options") or {})}
|
|
169
|
+
if our is None:
|
|
170
|
+
our = {"package": PKG, "options": dict(DEFAULT_OPTIONS)}
|
|
171
|
+
plugins.append(our)
|
|
172
|
+
print(f" + Added plugin entry: {PKG}")
|
|
173
|
+
else:
|
|
174
|
+
print(f" ℹ️ Plugin entry already configured: {PKG}")
|
|
175
|
+
cfg["plugins"] = plugins
|
|
176
|
+
|
|
177
|
+
# --- agents (V2 plural): merge snippet definitions, never overwrite users ---
|
|
171
178
|
try:
|
|
172
179
|
snippet = json.loads((repo / "config" / "opencode-snippet.json").read_text(encoding="utf-8"))
|
|
173
|
-
agents = cfg.setdefault("
|
|
174
|
-
|
|
180
|
+
agents = cfg.setdefault("agents", {})
|
|
181
|
+
legacy_agents = cfg.get("agent")
|
|
182
|
+
if isinstance(legacy_agents, dict):
|
|
183
|
+
for name, definition in legacy_agents.items():
|
|
184
|
+
agents.setdefault(name, definition)
|
|
185
|
+
cfg.pop("agent", None)
|
|
186
|
+
print(" ~ Migrated legacy 'agent' entries to V2 'agents'")
|
|
187
|
+
for name, definition in (snippet.get("agents") or snippet.get("agent") or {}).items():
|
|
175
188
|
if name not in agents:
|
|
176
189
|
agents[name] = definition
|
|
177
190
|
print(f" + Added agent: {name}")
|
|
178
191
|
else:
|
|
179
192
|
print(f" ℹ️ Agent already configured: {name}")
|
|
180
193
|
|
|
181
|
-
# Skills:
|
|
182
|
-
# from ~/.config — merge as absolute paths
|
|
194
|
+
# Skills: V2 is a list of directories/URLs. Snippet paths are repo-relative
|
|
195
|
+
# ("./skills/x") which breaks from ~/.config — merge as absolute paths and
|
|
196
|
+
# repair a legacy `{"paths": [...]}` object or relative entries in place.
|
|
183
197
|
import os as _os
|
|
184
198
|
wanted = []
|
|
185
|
-
for sp in snippet.get("skills"
|
|
199
|
+
for sp in snippet.get("skills") or []:
|
|
186
200
|
wanted.append(sp if _os.path.isabs(sp) else str(repo / sp.lstrip("./")))
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
201
|
+
skills = cfg.get("skills")
|
|
202
|
+
if isinstance(skills, dict):
|
|
203
|
+
skills = cfg["skills"] = list(skills.get("paths") or [])
|
|
204
|
+
print(" ~ Migrated legacy skills.paths to the V2 skills list")
|
|
205
|
+
elif not isinstance(skills, list):
|
|
206
|
+
skills = cfg["skills"] = []
|
|
207
|
+
for i, existing in enumerate(list(skills)):
|
|
208
|
+
if existing in wanted:
|
|
209
|
+
continue
|
|
191
210
|
for abs_sp in wanted:
|
|
192
|
-
if existing == abs_sp:
|
|
193
|
-
break
|
|
194
211
|
rel = "./" + str(Path(abs_sp).relative_to(repo)) if str(abs_sp).startswith(str(repo)) else None
|
|
195
212
|
if rel and existing == rel:
|
|
196
|
-
|
|
213
|
+
skills[i] = abs_sp
|
|
197
214
|
print(f" ~ Repaired relative skill path: {rel} -> {abs_sp}")
|
|
198
215
|
break
|
|
199
216
|
for abs_sp in wanted:
|
|
200
|
-
if abs_sp not in
|
|
201
|
-
|
|
217
|
+
if abs_sp not in skills:
|
|
218
|
+
skills.append(abs_sp)
|
|
202
219
|
print(f" + Added skill path: {abs_sp}")
|
|
203
220
|
else:
|
|
204
221
|
print(f" ℹ️ Skill path already configured: {abs_sp}")
|
|
205
222
|
except Exception as e:
|
|
206
223
|
print(f" ⚠️ Non-critical warning merging agents: {e}")
|
|
207
224
|
|
|
208
|
-
# --- MCP server: absolute runner path
|
|
225
|
+
# --- MCP server (V2 `mcp.servers`): absolute runner path ---
|
|
209
226
|
mcp = cfg.setdefault("mcp", {})
|
|
210
|
-
|
|
211
|
-
|
|
227
|
+
servers = mcp.setdefault("servers", {})
|
|
228
|
+
legacy_mcp = mcp.get("iumbtems")
|
|
229
|
+
if isinstance(legacy_mcp, dict):
|
|
230
|
+
servers.setdefault("iumbtems", legacy_mcp)
|
|
231
|
+
mcp.pop("iumbtems", None)
|
|
232
|
+
print(" ~ Migrated legacy mcp.iumbtems to V2 mcp.servers.iumbtems")
|
|
233
|
+
if "iumbtems" not in servers:
|
|
234
|
+
servers["iumbtems"] = {
|
|
212
235
|
"type": "local",
|
|
213
236
|
"command": ["python3", str(repo / "runner" / "mcp_server.py")],
|
|
214
237
|
"enabled": True,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heretek-ai/epistemic-swarm",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.7",
|
|
4
4
|
"description": "IUMBTEMS: I Use My Brain To Express My Self — High-Integrity Dialectic Research Agent Harness for Claude Code, OpenCode V2, Pi, OMP (oh-my-pi), Gemini CLI, Codex CLI, and AntiGravity",
|
|
5
5
|
"main": "bin/cli.js",
|
|
6
6
|
"bin": {
|