opencode-swarm 7.48.1 → 7.49.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.
@@ -1,16 +1,39 @@
1
1
  /**
2
2
  * Tool Doctor Service
3
3
  *
4
- * Validates that every tool name in TOOL_NAMES has a corresponding
5
- * registration in the plugin's tool: {} block in src/index.ts.
4
+ * Validates that every tool assigned in AGENT_TOOL_MAP is a registered tool name.
5
+ *
6
+ * As of #507, registration is DERIVED from the single registration-data source
7
+ * (tool-metadata) and the handler set is compile-time-guaranteed to match it
8
+ * (`manifest.ts satisfies Record<ToolName, () => ToolDefinition>`), so the set of
9
+ * registered tools is exactly TOOL_NAME_SET. This service therefore validates
10
+ * against TOOL_NAME_SET (handler-free) rather than importing the handler-bearing
11
+ * manifest — that keeps tool-doctor (and the `../services` barrel that re-exports
12
+ * it) out of the tool-module import graph, avoiding init cycles (#507 CI finding).
13
+ * The handler-level coherence is enforced by the compile-time `satisfies` plus the
14
+ * standalone CI script `scripts/check-tool-registration.ts`.
6
15
  *
7
16
  * Also validates:
8
- * - AGENT_TOOL_MAP alignment: tools assigned to agents are registered in the plugin
17
+ * - AGENT_TOOL_MAP alignment: tools assigned to agents are registered tool names
9
18
  * - Class 3 tool binary readiness: external binaries needed by lint tools are available
10
19
  */
11
- import type { ConfigDoctorResult } from './config-doctor';
20
+ import type { ConfigDoctorResult, ConfigFinding } from './config-doctor';
12
21
  /** Result of tool registration coherence check */
13
22
  export type ToolDoctorResult = ConfigDoctorResult;
23
+ /**
24
+ * Check AGENT_TOOL_MAP alignment with registered tools
25
+ *
26
+ * Verifies that every tool listed in AGENT_TOOL_MAP is a registered tool name
27
+ * (a member of the manifest-derived registered set passed in). A missing
28
+ * registration means the agent's system prompt would instruct the model to call
29
+ * a tool that opencode never exposes to the runtime, which silently breaks the
30
+ * agent's workflow (this is how the council feature shipped broken in 6.66.0 —
31
+ * submit_council_verdicts and declare_council_criteria were in
32
+ * AGENT_TOOL_MAP.architect but never registered). Findings are emitted at
33
+ * severity 'error' so `config doctor` / `/swarm preflight` treats this class of
34
+ * drift as fatal rather than advisory.
35
+ */
36
+ export declare function checkAgentToolMapAlignment(registeredKeys: Set<string>): ConfigFinding[];
14
37
  /**
15
38
  * Run tool registration coherence check
16
39
  *
@@ -23,4 +46,4 @@ export type ToolDoctorResult = ConfigDoctorResult;
23
46
  * Returns null if all binaries are available.
24
47
  */
25
48
  export declare function getBinaryReadinessAdvisory(): string | null;
26
- export declare function runToolDoctor(_directory: string, pluginRoot?: string): ToolDoctorResult;
49
+ export declare function runToolDoctor(_directory: string, _pluginRoot?: string): ToolDoctorResult;
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Tool manifest - HANDLER wiring for every tool. The registration METADATA
3
+ * (names, descriptions, agents) lives in ./tool-metadata.ts.
4
+ *
5
+ * The `defineHandlers` helper below constrains its argument to
6
+ * `Record<ToolName, () => ToolDefinition>` (ToolName = keyof typeof TOOL_METADATA),
7
+ * which makes this map exhaustive: every metadata entry MUST have a handler here,
8
+ * or it is a COMPILE error. That, plus the required fields in ToolMeta, keeps the
9
+ * dead-tools bug class impossible while the two files stay decoupled (this one
10
+ * imports handlers; metadata imports none). A stray handler key (no metadata) is
11
+ * caught at runtime by scripts/check-tool-registration.ts.
12
+ *
13
+ * Handlers are stored as lazy thunks (`() => tool`) so this object never reads a
14
+ * handler binding during module evaluation - safe inside import cycles. Resolve
15
+ * via buildPluginToolObject (src/tools/plugin-registration.ts), never at module
16
+ * top level. swarm_command uses its static (no-DI) handler here; the real
17
+ * dependency-injected instance is applied in buildPluginToolObject.
18
+ *
19
+ * Adding a tool: add a ./tool-metadata.ts entry AND a handler here (both compile-
20
+ * checked). Async-init tools would need a factory + async consumers, conflicting
21
+ * with the synchronous bounded plugin-init contract (AGENTS.md #1); runtime-
22
+ * conditional tools would need a `runtime` field + a buildPluginToolObject filter.
23
+ * Neither is implemented (no current tool needs them). Not tree-shakeable.
24
+ */
25
+ import type { ToolDefinition } from '@opencode-ai/plugin/tool';
26
+ export declare const TOOL_MANIFEST: {
27
+ diff: () => ToolDefinition;
28
+ diff_summary: () => ToolDefinition;
29
+ syntax_check: () => ToolDefinition;
30
+ placeholder_scan: () => ToolDefinition;
31
+ imports: () => ToolDefinition;
32
+ lint: () => ToolDefinition;
33
+ secretscan: () => ToolDefinition;
34
+ sast_scan: () => ToolDefinition;
35
+ build_check: () => ToolDefinition;
36
+ pre_check_batch: () => ToolDefinition;
37
+ quality_budget: () => ToolDefinition;
38
+ symbols: () => ToolDefinition;
39
+ complexity_hotspots: () => ToolDefinition;
40
+ schema_drift: () => ToolDefinition;
41
+ todo_extract: () => ToolDefinition;
42
+ evidence_check: () => ToolDefinition;
43
+ check_gate_status: () => ToolDefinition;
44
+ completion_verify: () => ToolDefinition;
45
+ submit_council_verdicts: () => ToolDefinition;
46
+ submit_phase_council_verdicts: () => ToolDefinition;
47
+ declare_council_criteria: () => ToolDefinition;
48
+ sbom_generate: () => ToolDefinition;
49
+ checkpoint: () => ToolDefinition;
50
+ pkg_audit: () => ToolDefinition;
51
+ test_runner: () => ToolDefinition;
52
+ test_impact: () => ToolDefinition;
53
+ mutation_test: () => ToolDefinition;
54
+ generate_mutants: () => ToolDefinition;
55
+ detect_domains: () => ToolDefinition;
56
+ gitingest: () => ToolDefinition;
57
+ retrieve_summary: () => ToolDefinition;
58
+ extract_code_blocks: () => ToolDefinition;
59
+ phase_complete: () => ToolDefinition;
60
+ save_plan: () => ToolDefinition;
61
+ update_task_status: () => ToolDefinition;
62
+ lint_spec: () => ToolDefinition;
63
+ write_retro: () => ToolDefinition;
64
+ write_drift_evidence: () => ToolDefinition;
65
+ write_hallucination_evidence: () => ToolDefinition;
66
+ write_mutation_evidence: () => ToolDefinition;
67
+ declare_scope: () => ToolDefinition;
68
+ knowledge_query: () => ToolDefinition;
69
+ doc_scan: () => ToolDefinition;
70
+ doc_extract: () => ToolDefinition;
71
+ curator_analyze: () => ToolDefinition;
72
+ knowledge_add: () => ToolDefinition;
73
+ knowledge_recall: () => ToolDefinition;
74
+ knowledge_remove: () => ToolDefinition;
75
+ co_change_analyzer: () => ToolDefinition;
76
+ search: () => ToolDefinition;
77
+ batch_symbols: () => ToolDefinition;
78
+ suggest_patch: () => ToolDefinition;
79
+ req_coverage: () => ToolDefinition;
80
+ get_approved_plan: () => ToolDefinition;
81
+ repo_map: () => ToolDefinition;
82
+ get_qa_gate_profile: () => ToolDefinition;
83
+ set_qa_gates: () => ToolDefinition;
84
+ web_search: () => ToolDefinition;
85
+ convene_general_council: () => ToolDefinition;
86
+ write_final_council_evidence: () => ToolDefinition;
87
+ skill_generate: () => ToolDefinition;
88
+ skill_list: () => ToolDefinition;
89
+ skill_apply: () => ToolDefinition;
90
+ skill_inspect: () => ToolDefinition;
91
+ skill_regenerate: () => ToolDefinition;
92
+ skill_retire: () => ToolDefinition;
93
+ skill_improve: () => ToolDefinition;
94
+ spec_write: () => ToolDefinition;
95
+ knowledge_ack: () => ToolDefinition;
96
+ knowledge_receipt: () => ToolDefinition;
97
+ knowledge_archive: () => ToolDefinition;
98
+ swarm_memory_recall: () => ToolDefinition;
99
+ swarm_memory_propose: () => ToolDefinition;
100
+ swarm_command: () => ToolDefinition;
101
+ summarize_work: () => ToolDefinition;
102
+ write_architecture_supervisor_evidence: () => ToolDefinition;
103
+ lean_turbo_plan_lanes: () => ToolDefinition;
104
+ lean_turbo_acquire_locks: () => ToolDefinition;
105
+ lean_turbo_runner_status: () => ToolDefinition;
106
+ lean_turbo_review: () => ToolDefinition;
107
+ lean_turbo_run_phase: () => ToolDefinition;
108
+ lean_turbo_status: () => ToolDefinition;
109
+ };
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Builds the plugin's `tool: {}` object from the single-source-of-truth
3
+ * {@link TOOL_MANIFEST}. This is the ONLY place the OpenCode plugin tool object
4
+ * is assembled, so registration drift between the manifest and the plugin is
5
+ * structurally impossible.
6
+ *
7
+ * Extracted into its own module (rather than inlined in src/index.ts) so the
8
+ * registration tests and `tool-doctor` can assert against the real object
9
+ * instead of regex-parsing source text.
10
+ */
11
+ import type { ToolDefinition } from '@opencode-ai/plugin/tool';
12
+ import type { AgentDefinition } from '../agents/index.js';
13
+ /**
14
+ * Construct the plugin tool object: one handler per manifest entry, with
15
+ * `swarm_command` overridden by its dependency-injected instance.
16
+ *
17
+ * The manifest's `swarm_command` handler is the static (no-DI) form used only
18
+ * for derivation; the real instance needs the agent definition map, which is
19
+ * only available at plugin-init time.
20
+ */
21
+ export declare function buildPluginToolObject(agents: Record<string, AgentDefinition>): Record<string, ToolDefinition>;
@@ -0,0 +1,373 @@
1
+ /**
2
+ * Tool METADATA - the single source of truth for every tool's name, description,
3
+ * and default agents. Handler wiring lives in ./manifest.ts.
4
+ *
5
+ * This module imports NO tool handler modules. That is deliberate: constants.ts
6
+ * and tool-names.ts (and a few tool modules, e.g. completion-verify) derive from
7
+ * here, and they are transitively imported by tool modules. If this file imported
8
+ * the handler-bearing manifest, every constants.ts consumer would pull all 82 tool
9
+ * modules and form an init cycle (#507 CI finding). Keeping metadata handler-free
10
+ * makes the module graph acyclic.
11
+ *
12
+ * Cross-checked with ./manifest.ts: that file does
13
+ * `satisfies Record<ToolName, () => ToolDefinition>` with `ToolName = keyof typeof
14
+ * TOOL_METADATA`, so adding a tool here without wiring a handler there (or vice
15
+ * versa) is a COMPILE error - the dead-tools bug class stays impossible.
16
+ */
17
+ import { type AgentName } from '../config/agent-names';
18
+ /** A tool's registration metadata. All fields required so a missing one is a compile error. */
19
+ export interface ToolMeta {
20
+ /** Human-readable description surfaced to agents (TOOL_DESCRIPTIONS). */
21
+ description: string;
22
+ /** Agents granted this tool by default (inverted into AGENT_TOOL_MAP). Empty = overlay-only. */
23
+ agents: AgentName[];
24
+ }
25
+ /**
26
+ * The registry metadata. Keys are the canonical tool names; `ToolName` derives
27
+ * from them (the keys ARE the name set).
28
+ */
29
+ export declare const TOOL_METADATA: {
30
+ diff: {
31
+ description: string;
32
+ agents: ("reviewer" | "test_engineer" | "coder" | "critic_oversight" | "architect")[];
33
+ };
34
+ diff_summary: {
35
+ description: string;
36
+ agents: ("reviewer" | "critic_oversight" | "architect")[];
37
+ };
38
+ syntax_check: {
39
+ description: string;
40
+ agents: ("test_engineer" | "coder" | "architect")[];
41
+ };
42
+ placeholder_scan: {
43
+ description: string;
44
+ agents: ("reviewer" | "architect")[];
45
+ };
46
+ imports: {
47
+ description: string;
48
+ agents: ("reviewer" | "test_engineer" | "coder" | "docs" | "explorer" | "sme" | "critic" | "critic_oversight" | "architect" | "docs_design" | "critic_sounding_board" | "critic_drift_verifier" | "critic_hallucination_verifier")[];
49
+ };
50
+ lint: {
51
+ description: string;
52
+ agents: ("reviewer" | "coder" | "architect")[];
53
+ };
54
+ secretscan: {
55
+ description: string;
56
+ agents: ("reviewer" | "critic_oversight" | "architect")[];
57
+ };
58
+ sast_scan: {
59
+ description: string;
60
+ agents: ("reviewer" | "critic_oversight" | "architect")[];
61
+ };
62
+ build_check: {
63
+ description: string;
64
+ agents: ("test_engineer" | "coder" | "architect")[];
65
+ };
66
+ pre_check_batch: {
67
+ description: string;
68
+ agents: ("reviewer" | "architect")[];
69
+ };
70
+ quality_budget: {
71
+ description: string;
72
+ agents: "architect"[];
73
+ };
74
+ symbols: {
75
+ description: string;
76
+ agents: ("reviewer" | "test_engineer" | "coder" | "docs" | "designer" | "explorer" | "sme" | "critic" | "critic_oversight" | "architect" | "docs_design" | "critic_sounding_board" | "critic_drift_verifier" | "critic_hallucination_verifier" | "spec_writer")[];
77
+ };
78
+ complexity_hotspots: {
79
+ description: string;
80
+ agents: ("reviewer" | "test_engineer" | "explorer" | "sme" | "critic" | "critic_oversight" | "architect" | "critic_sounding_board" | "critic_drift_verifier" | "critic_hallucination_verifier")[];
81
+ };
82
+ schema_drift: {
83
+ description: string;
84
+ agents: ("docs" | "explorer" | "sme" | "architect")[];
85
+ };
86
+ todo_extract: {
87
+ description: string;
88
+ agents: ("docs" | "explorer" | "architect")[];
89
+ };
90
+ evidence_check: {
91
+ description: string;
92
+ agents: ("critic_oversight" | "architect")[];
93
+ };
94
+ check_gate_status: {
95
+ description: string;
96
+ agents: ("critic_oversight" | "architect")[];
97
+ };
98
+ completion_verify: {
99
+ description: string;
100
+ agents: ("critic_oversight" | "architect")[];
101
+ };
102
+ submit_council_verdicts: {
103
+ description: string;
104
+ agents: "architect"[];
105
+ };
106
+ submit_phase_council_verdicts: {
107
+ description: string;
108
+ agents: "architect"[];
109
+ };
110
+ declare_council_criteria: {
111
+ description: string;
112
+ agents: "architect"[];
113
+ };
114
+ sbom_generate: {
115
+ description: string;
116
+ agents: "architect"[];
117
+ };
118
+ checkpoint: {
119
+ description: string;
120
+ agents: "architect"[];
121
+ };
122
+ pkg_audit: {
123
+ description: string;
124
+ agents: ("reviewer" | "test_engineer" | "critic_oversight" | "architect" | "critic_hallucination_verifier")[];
125
+ };
126
+ test_runner: {
127
+ description: string;
128
+ agents: ("reviewer" | "test_engineer" | "architect")[];
129
+ };
130
+ test_impact: {
131
+ description: string;
132
+ agents: ("reviewer" | "test_engineer" | "critic_oversight" | "architect")[];
133
+ };
134
+ mutation_test: {
135
+ description: string;
136
+ agents: ("test_engineer" | "architect")[];
137
+ };
138
+ generate_mutants: {
139
+ description: string;
140
+ agents: "architect"[];
141
+ };
142
+ detect_domains: {
143
+ description: string;
144
+ agents: ("docs" | "explorer" | "sme" | "critic" | "critic_oversight" | "architect" | "docs_design" | "critic_sounding_board" | "critic_drift_verifier" | "critic_hallucination_verifier")[];
145
+ };
146
+ gitingest: {
147
+ description: string;
148
+ agents: ("docs" | "explorer" | "architect")[];
149
+ };
150
+ retrieve_summary: {
151
+ description: string;
152
+ agents: ("reviewer" | "test_engineer" | "coder" | "docs" | "designer" | "explorer" | "sme" | "critic" | "critic_oversight" | "architect" | "docs_design" | "critic_sounding_board" | "critic_drift_verifier" | "critic_hallucination_verifier" | "critic_architecture_supervisor" | "spec_writer")[];
153
+ };
154
+ extract_code_blocks: {
155
+ description: string;
156
+ agents: ("reviewer" | "test_engineer" | "coder" | "docs" | "designer" | "explorer" | "sme" | "architect" | "docs_design" | "spec_writer")[];
157
+ };
158
+ phase_complete: {
159
+ description: string;
160
+ agents: "architect"[];
161
+ };
162
+ save_plan: {
163
+ description: string;
164
+ agents: "architect"[];
165
+ };
166
+ update_task_status: {
167
+ description: string;
168
+ agents: "architect"[];
169
+ };
170
+ lint_spec: {
171
+ description: string;
172
+ agents: ("architect" | "spec_writer")[];
173
+ };
174
+ write_retro: {
175
+ description: string;
176
+ agents: "architect"[];
177
+ };
178
+ write_drift_evidence: {
179
+ description: string;
180
+ agents: "architect"[];
181
+ };
182
+ write_hallucination_evidence: {
183
+ description: string;
184
+ agents: "architect"[];
185
+ };
186
+ write_mutation_evidence: {
187
+ description: string;
188
+ agents: "architect"[];
189
+ };
190
+ declare_scope: {
191
+ description: string;
192
+ agents: "architect"[];
193
+ };
194
+ knowledge_query: {
195
+ description: string;
196
+ agents: ("architect" | "skill_improver" | "spec_writer")[];
197
+ };
198
+ doc_scan: {
199
+ description: string;
200
+ agents: ("explorer" | "architect" | "docs_design" | "skill_improver" | "spec_writer")[];
201
+ };
202
+ doc_extract: {
203
+ description: string;
204
+ agents: ("architect" | "docs_design" | "skill_improver" | "spec_writer")[];
205
+ };
206
+ curator_analyze: {
207
+ description: string;
208
+ agents: "architect"[];
209
+ };
210
+ knowledge_add: {
211
+ description: string;
212
+ agents: ("coder" | "architect")[];
213
+ };
214
+ knowledge_recall: {
215
+ description: string;
216
+ agents: ("reviewer" | "test_engineer" | "coder" | "docs" | "designer" | "explorer" | "sme" | "critic" | "critic_oversight" | "architect" | "docs_design" | "critic_sounding_board" | "critic_drift_verifier" | "critic_hallucination_verifier" | "critic_architecture_supervisor" | "curator_init" | "curator_phase" | "skill_improver" | "spec_writer")[];
217
+ };
218
+ knowledge_remove: {
219
+ description: string;
220
+ agents: "architect"[];
221
+ };
222
+ co_change_analyzer: {
223
+ description: string;
224
+ agents: "architect"[];
225
+ };
226
+ search: {
227
+ description: string;
228
+ agents: ("reviewer" | "test_engineer" | "coder" | "docs" | "designer" | "explorer" | "sme" | "critic_oversight" | "architect" | "docs_design" | "critic_hallucination_verifier" | "skill_improver" | "spec_writer")[];
229
+ };
230
+ batch_symbols: {
231
+ description: string;
232
+ agents: ("reviewer" | "explorer" | "critic_oversight" | "architect" | "critic_hallucination_verifier")[];
233
+ };
234
+ suggest_patch: {
235
+ description: string;
236
+ agents: ("reviewer" | "architect")[];
237
+ };
238
+ req_coverage: {
239
+ description: string;
240
+ agents: ("critic" | "critic_oversight" | "critic_sounding_board" | "critic_drift_verifier" | "critic_hallucination_verifier" | "spec_writer")[];
241
+ };
242
+ get_approved_plan: {
243
+ description: string;
244
+ agents: ("critic" | "critic_oversight" | "critic_drift_verifier")[];
245
+ };
246
+ repo_map: {
247
+ description: string;
248
+ agents: ("reviewer" | "coder" | "explorer" | "critic" | "critic_oversight" | "architect" | "critic_sounding_board" | "critic_drift_verifier" | "critic_hallucination_verifier" | "critic_architecture_supervisor")[];
249
+ };
250
+ get_qa_gate_profile: {
251
+ description: string;
252
+ agents: "architect"[];
253
+ };
254
+ set_qa_gates: {
255
+ description: string;
256
+ agents: "architect"[];
257
+ };
258
+ web_search: {
259
+ description: string;
260
+ agents: ("architect" | "skill_improver")[];
261
+ };
262
+ convene_general_council: {
263
+ description: string;
264
+ agents: "architect"[];
265
+ };
266
+ write_final_council_evidence: {
267
+ description: string;
268
+ agents: "architect"[];
269
+ };
270
+ skill_generate: {
271
+ description: string;
272
+ agents: ("architect" | "skill_improver")[];
273
+ };
274
+ skill_list: {
275
+ description: string;
276
+ agents: ("architect" | "skill_improver")[];
277
+ };
278
+ skill_apply: {
279
+ description: string;
280
+ agents: "architect"[];
281
+ };
282
+ skill_inspect: {
283
+ description: string;
284
+ agents: ("architect" | "skill_improver")[];
285
+ };
286
+ skill_regenerate: {
287
+ description: string;
288
+ agents: "architect"[];
289
+ };
290
+ skill_retire: {
291
+ description: string;
292
+ agents: "architect"[];
293
+ };
294
+ skill_improve: {
295
+ description: string;
296
+ agents: ("architect" | "skill_improver")[];
297
+ };
298
+ spec_write: {
299
+ description: string;
300
+ agents: "spec_writer"[];
301
+ };
302
+ knowledge_ack: {
303
+ description: string;
304
+ agents: "architect"[];
305
+ };
306
+ knowledge_receipt: {
307
+ description: string;
308
+ agents: ("coder" | "architect")[];
309
+ };
310
+ knowledge_archive: {
311
+ description: string;
312
+ agents: "architect"[];
313
+ };
314
+ swarm_memory_recall: {
315
+ description: string;
316
+ agents: never[];
317
+ };
318
+ swarm_memory_propose: {
319
+ description: string;
320
+ agents: never[];
321
+ };
322
+ swarm_command: {
323
+ description: string;
324
+ agents: ("reviewer" | "test_engineer" | "coder" | "docs" | "designer" | "explorer" | "sme" | "critic" | "architect" | "docs_design")[];
325
+ };
326
+ summarize_work: {
327
+ description: string;
328
+ agents: ("test_engineer" | "coder" | "docs" | "designer" | "explorer" | "sme" | "architect" | "docs_design")[];
329
+ };
330
+ write_architecture_supervisor_evidence: {
331
+ description: string;
332
+ agents: "architect"[];
333
+ };
334
+ lean_turbo_plan_lanes: {
335
+ description: string;
336
+ agents: "architect"[];
337
+ };
338
+ lean_turbo_acquire_locks: {
339
+ description: string;
340
+ agents: "architect"[];
341
+ };
342
+ lean_turbo_runner_status: {
343
+ description: string;
344
+ agents: "architect"[];
345
+ };
346
+ lean_turbo_review: {
347
+ description: string;
348
+ agents: "architect"[];
349
+ };
350
+ lean_turbo_run_phase: {
351
+ description: string;
352
+ agents: "architect"[];
353
+ };
354
+ lean_turbo_status: {
355
+ description: string;
356
+ agents: "architect"[];
357
+ };
358
+ };
359
+ /** Union type of all valid tool names (the metadata keys). */
360
+ export type ToolName = keyof typeof TOOL_METADATA;
361
+ /** Readonly array of all tool names, in metadata declaration order. */
362
+ export declare const TOOL_NAMES: readonly ToolName[];
363
+ /** Set for O(1) tool name validation. */
364
+ export declare const TOOL_NAME_SET: ReadonlySet<ToolName>;
365
+ /** Human-readable descriptions, keyed by tool name. */
366
+ export declare const TOOL_DESCRIPTIONS: Partial<Record<ToolName, string>>;
367
+ /**
368
+ * Default tool permissions per agent, inverted from each tool's `agents` list.
369
+ * All agent names are initialized (agents with no tools keep an empty array, e.g.
370
+ * the council members). Tools with `agents: []` (the memory tools) stay OUT of
371
+ * this map and are applied only via MEMORY_AGENT_TOOL_MAP.
372
+ */
373
+ export declare const AGENT_TOOL_MAP: Record<AgentName, ToolName[]>;
@@ -1,10 +1,15 @@
1
1
  /**
2
2
  * Central registry of all tool names used by the swarm.
3
- * Used for constants and agent setup references.
3
+ *
4
+ * As of #507 these are DERIVED from the single registration-data source,
5
+ * {@link TOOL_METADATA}, and are COMPUTED in `./tool-metadata`. This module is a
6
+ * thin re-export facade so existing `from '../tools/tool-names'` call sites are
7
+ * unchanged. Adding a tool = add one `tool-metadata` entry; `ToolName`,
8
+ * `TOOL_NAMES`, and `TOOL_NAME_SET` update automatically.
9
+ *
10
+ * It re-exports from the HANDLER-FREE metadata module (not the handler-bearing
11
+ * `./manifest`), so importing tool-names never pulls tool modules — that is what
12
+ * keeps the module graph acyclic.
4
13
  */
5
- /** Union type of all valid tool names */
6
- export type ToolName = 'diff' | 'diff_summary' | 'syntax_check' | 'placeholder_scan' | 'imports' | 'lint' | 'secretscan' | 'sast_scan' | 'build_check' | 'pre_check_batch' | 'quality_budget' | 'symbols' | 'complexity_hotspots' | 'schema_drift' | 'todo_extract' | 'evidence_check' | 'check_gate_status' | 'completion_verify' | 'submit_council_verdicts' | 'submit_phase_council_verdicts' | 'declare_council_criteria' | 'sbom_generate' | 'checkpoint' | 'pkg_audit' | 'test_runner' | 'test_impact' | 'mutation_test' | 'generate_mutants' | 'detect_domains' | 'gitingest' | 'retrieve_summary' | 'extract_code_blocks' | 'phase_complete' | 'save_plan' | 'update_task_status' | 'lint_spec' | 'write_retro' | 'write_drift_evidence' | 'write_hallucination_evidence' | 'write_mutation_evidence' | 'declare_scope' | 'knowledge_query' | 'doc_scan' | 'doc_extract' | 'curator_analyze' | 'knowledge_add' | 'knowledge_recall' | 'knowledge_remove' | 'co_change_analyzer' | 'search' | 'batch_symbols' | 'suggest_patch' | 'req_coverage' | 'get_approved_plan' | 'repo_map' | 'get_qa_gate_profile' | 'set_qa_gates' | 'web_search' | 'convene_general_council' | 'write_final_council_evidence' | 'skill_generate' | 'skill_list' | 'skill_apply' | 'skill_inspect' | 'skill_regenerate' | 'skill_retire' | 'skill_improve' | 'spec_write' | 'knowledge_ack' | 'knowledge_receipt' | 'knowledge_archive' | 'swarm_memory_recall' | 'swarm_memory_propose' | 'swarm_command' | 'summarize_work' | 'write_architecture_supervisor_evidence' | 'lean_turbo_plan_lanes' | 'lean_turbo_acquire_locks' | 'lean_turbo_runner_status' | 'lean_turbo_review' | 'lean_turbo_run_phase' | 'lean_turbo_status';
7
- /** Readonly array of all tool names */
8
- export declare const TOOL_NAMES: readonly ToolName[];
9
- /** Set for O(1) tool name validation */
10
- export declare const TOOL_NAME_SET: ReadonlySet<ToolName>;
14
+ export type { ToolName } from './tool-metadata';
15
+ export { TOOL_NAME_SET, TOOL_NAMES } from './tool-metadata';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.48.1",
3
+ "version": "7.49.0",
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",