opencode-swarm 7.84.0 → 7.86.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 (32) hide show
  1. package/.opencode/skills/codebase-review-swarm/references/review-protocol-v8.2.md +4 -0
  2. package/.opencode/skills/council/SKILL.md +6 -1
  3. package/.opencode/skills/deep-dive/SKILL.md +2 -0
  4. package/.opencode/skills/deep-research/SKILL.md +6 -0
  5. package/.opencode/skills/swarm-pr-feedback/SKILL.md +6 -0
  6. package/.opencode/skills/swarm-pr-review/SKILL.md +4 -0
  7. package/dist/background/lane-output-store.d.ts +72 -0
  8. package/dist/background/pending-delegations.d.ts +6 -0
  9. package/dist/cli/{config-doctor-4tcdd9vt.js → config-doctor-zejarrr6.js} +2 -2
  10. package/dist/cli/{guardrail-explain-tcamcdfy.js → guardrail-explain-rtd1x26f.js} +5 -5
  11. package/dist/cli/{guardrail-log-fd14n96q.js → guardrail-log-80116wmz.js} +3 -3
  12. package/dist/cli/{index-a82d6d87.js → index-0sxvwjt0.js} +1 -1
  13. package/dist/cli/{index-jfgr5gye.js → index-5cb86007.js} +1 -1
  14. package/dist/cli/{index-8ra2qpk8.js → index-5q66xc88.js} +9 -9
  15. package/dist/cli/{index-xw0bcy0v.js → index-7r2b453y.js} +2 -2
  16. package/dist/cli/{index-wg3r6acj.js → index-hw9b2xng.js} +5 -1
  17. package/dist/cli/{index-j710h2ge.js → index-jwz50183.js} +6 -6
  18. package/dist/cli/{index-pv2xmc9k.js → index-vq2321gg.js} +1 -1
  19. package/dist/cli/index.js +4 -4
  20. package/dist/cli/{pending-delegations-pz61mrsz.js → pending-delegations-rd40tv9s.js} +7 -1
  21. package/dist/cli/{schema-c2dbzhm8.js → schema-8d32b2v6.js} +1 -1
  22. package/dist/index.js +985 -357
  23. package/dist/tools/dispatch-lanes.d.ts +14 -3
  24. package/dist/tools/index.d.ts +1 -0
  25. package/dist/tools/manifest.d.ts +1 -0
  26. package/dist/tools/repo-graph/builder.d.ts +46 -0
  27. package/dist/tools/repo-graph/query.d.ts +26 -1
  28. package/dist/tools/repo-graph/types.d.ts +73 -1
  29. package/dist/tools/repo-graph.d.ts +4 -3
  30. package/dist/tools/retrieve-lane-output.d.ts +2 -0
  31. package/dist/tools/tool-metadata.d.ts +4 -0
  32. package/package.json +1 -1
@@ -56,6 +56,13 @@ export interface DispatchLaneResult {
56
56
  output?: string;
57
57
  output_chars?: number;
58
58
  output_truncated?: boolean;
59
+ output_ref?: string;
60
+ output_digest?: string;
61
+ output_preview_chars?: number;
62
+ output_degraded?: boolean;
63
+ output_artifact_error?: string;
64
+ transcript_incomplete?: boolean;
65
+ message_count?: number;
59
66
  error?: string;
60
67
  }
61
68
  export interface DispatchLanesResult {
@@ -194,7 +201,7 @@ export declare const _internals: {
194
201
  };
195
202
  export declare const _test_exports: {
196
203
  applyCommonPrompt: typeof applyCommonPrompt;
197
- extractLastAssistantText: typeof extractLastAssistantText;
204
+ extractAssistantTranscript: typeof extractAssistantTranscript;
198
205
  formatError: typeof formatError;
199
206
  nextCollectPollInterval: typeof nextCollectPollInterval;
200
207
  promptHash: typeof promptHash;
@@ -235,7 +242,7 @@ interface DispatchLanesExecutionContext {
235
242
  export declare function executeDispatchLanes(args: unknown, directory: string, context?: DispatchLanesExecutionContext): Promise<DispatchLanesResult>;
236
243
  export declare function executeDispatchLanesAsync(args: unknown, directory: string, context?: DispatchLanesExecutionContext): Promise<DispatchLanesAsyncResult>;
237
244
  export declare function executeCollectLaneResults(args: unknown, directory: string, context?: Pick<DispatchLanesExecutionContext, 'sessionID'>): Promise<CollectLaneResultsResult>;
238
- declare function extractLastAssistantText(messages: Array<{
245
+ declare function extractAssistantTranscript(messages: Array<{
239
246
  info?: {
240
247
  role?: string;
241
248
  };
@@ -243,7 +250,11 @@ declare function extractLastAssistantText(messages: Array<{
243
250
  type: string;
244
251
  text?: string;
245
252
  }>;
246
- }>): string;
253
+ }>): {
254
+ text: string;
255
+ messageCount: number;
256
+ transcriptIncomplete: boolean;
257
+ };
247
258
  declare function nextCollectPollInterval(currentMs: number): number;
248
259
  type ApplyCommonPromptResult = {
249
260
  ok: true;
@@ -47,6 +47,7 @@ export { type QualityBudgetInput, type QualityBudgetResult, quality_budget, qual
47
47
  export { buildWorkspaceGraph, type GraphEdge, type GraphNode, loadGraph, loadOrCreateGraph, type RepoGraph, resolveModuleSpecifier, saveGraph, updateGraphForFiles, } from './repo-graph';
48
48
  export { repo_map } from './repo-map';
49
49
  export { req_coverage } from './req-coverage';
50
+ export { retrieve_lane_output } from './retrieve-lane-output';
50
51
  export { retrieve_summary } from './retrieve-summary';
51
52
  export { type SastScanFinding, type SastScanInput, type SastScanResult, sast_scan, sastScan, } from './sast-scan';
52
53
  export type { SavePlanArgs, SavePlanResult } from './save-plan';
@@ -56,6 +56,7 @@ export declare const TOOL_MANIFEST: {
56
56
  git_blame: () => ToolDefinition;
57
57
  gitingest: () => ToolDefinition;
58
58
  retrieve_summary: () => ToolDefinition;
59
+ retrieve_lane_output: () => ToolDefinition;
59
60
  extract_code_blocks: () => ToolDefinition;
60
61
  phase_complete: () => ToolDefinition;
61
62
  save_plan: () => ToolDefinition;
@@ -26,6 +26,8 @@ export declare const _internals: {
26
26
  extractPythonSymbols: typeof extractPythonSymbols;
27
27
  parseFileImports: typeof parseFileImports;
28
28
  extractFileOntology: typeof extractFileOntology;
29
+ stripComments: typeof stripComments;
30
+ computeUsedSymbols: typeof computeUsedSymbols;
29
31
  };
30
32
  /**
31
33
  * Add or update a node in the graph.
@@ -66,6 +68,16 @@ export declare function resolveModuleSpecifier(workspaceRoot: string, sourceFile
66
68
  /**
67
69
  * A parsed import with its specifier and type.
68
70
  */
71
+ /**
72
+ * A single imported binding: the symbol's *exported* name in the target file
73
+ * and the *local* name it is bound to in the importing file (differs when an
74
+ * `as` alias or default import is used). Used to attribute call-site usage back
75
+ * to the correct exported symbol.
76
+ */
77
+ interface ImportBinding {
78
+ imported: string;
79
+ local: string;
80
+ }
69
81
  interface ParsedImport {
70
82
  /** The module specifier (e.g., './foo', 'lodash') */
71
83
  specifier: string;
@@ -73,8 +85,42 @@ interface ParsedImport {
73
85
  importType: 'default' | 'named' | 'namespace' | 'require' | 'sideeffect';
74
86
  /** Named imported symbols when statically detectable */
75
87
  importedSymbols: string[];
88
+ /** Alias-aware imported→local bindings for usage attribution */
89
+ bindings: ImportBinding[];
90
+ /** True for `export { x } from '...'` re-exports (symbols are re-exposed). */
91
+ reExport: boolean;
76
92
  }
93
+ /**
94
+ * Strip line (`//…`) and block (`/* … *\/`) comments from JS/TS source while
95
+ * preserving string, template-literal, and regex-literal contents (DD-C010).
96
+ * Import specifiers live inside string literals, so strings must be kept
97
+ * intact; only comment spans are removed. This is a bounded single-pass scanner
98
+ * — not a full parser (AST parsing in the repo-graph init path would violate
99
+ * AGENTS.md invariant 1) — and it eliminates the most common source of false
100
+ * import edges: import-like text inside comments (`// import x from "y"`).
101
+ *
102
+ * It is string-aware (a `//` inside `"http://…"` is not a comment) and
103
+ * regex-aware (a regex literal such as `/[/*]/` must not be mistaken for the
104
+ * start of a block comment, which would otherwise run to EOF and delete real
105
+ * imports). Regex-vs-division is disambiguated by the previous significant
106
+ * character (REGEX_ALLOWED_AFTER).
107
+ */
108
+ declare function stripComments(content: string): string;
77
109
  declare function parseFileImports(rawContent: string): ParsedImport[];
110
+ /**
111
+ * Conservatively determine which imported bindings are actually referenced in
112
+ * the importing file's body.
113
+ *
114
+ * Heuristic: in a well-formed import statement, each local binding name appears
115
+ * exactly once. Counting occurrences of the local name across the
116
+ * comment-stripped file content, a count > 1 means at least one body reference.
117
+ * Strings are intentionally *not* stripped, so the bias is toward "used" — a
118
+ * conservative direction that avoids false dead-export positives. Bindings whose
119
+ * local name cannot be safely word-boundary matched are assumed used.
120
+ *
121
+ * @returns the *exported* names (binding.imported) judged to be used.
122
+ */
123
+ declare function computeUsedSymbols(strippedContent: string, bindings: readonly ImportBinding[]): string[];
78
124
  /**
79
125
  * Result of scanning a single file for graph updates.
80
126
  */
@@ -1,10 +1,35 @@
1
- import type { BlastRadiusResult, FileOntology, FileReference, GraphNode, LocalizationBlock, PackageBoundarySummary, RepoGraph, SymbolReference } from './types';
1
+ import type { BlastRadiusResult, CallerReference, DeadExportsResult, FileOntology, FileReference, GraphNode, LocalizationBlock, PackageBoundarySummary, RepoGraph, SymbolReference } from './types';
2
2
  export declare function getGraphNode(graph: RepoGraph, input: string): GraphNode | undefined;
3
3
  export declare function resetQueryCache(): void;
4
4
  export declare function isGraphFresh(graph: RepoGraph | null, maxAgeMs?: number): boolean;
5
5
  export declare function getImporters(graph: RepoGraph, filePath: string): FileReference[];
6
6
  export declare function getDependencies(graph: RepoGraph, filePath: string): FileReference[];
7
7
  export declare function getSymbolConsumers(graph: RepoGraph, filePath: string, symbolName: string): SymbolReference[];
8
+ /**
9
+ * Files that actually *reference* an exported symbol of `filePath` — call-site
10
+ * granularity, not just "imports the file". On schema >= 1.1.0 graphs this uses
11
+ * per-edge `usedSymbols`; on older graphs (or namespace imports) it falls back
12
+ * to import-level matching, flagged via `resolution: 'imported'`.
13
+ */
14
+ export declare function getCallers(graph: RepoGraph, filePath: string, symbolName: string): CallerReference[];
15
+ export interface DeadExportsOptions {
16
+ /** Max candidates returned (default 100). */
17
+ maxCandidates?: number;
18
+ }
19
+ /**
20
+ * Conservatively detect exported symbols with no detected in-repo reference.
21
+ *
22
+ * Scoping for precision (advisory "candidate" output, never a delete directive):
23
+ * - Requires schema >= 1.1.0 (per-edge usedSymbols); otherwise returns
24
+ * schemaSupported=false so the caller can prompt a rebuild.
25
+ * - Only considers files imported by >= 1 other file — a file with no
26
+ * importers is a likely public-API entry / CLI / test, not dead code.
27
+ * - Skips files imported anywhere via namespace/side-effect/require/dynamic
28
+ * imports, where per-symbol usage is unresolvable.
29
+ * - Excludes framework-invoked roles (routes, CLIs, tests, agents, hooks,
30
+ * middleware) and the synthetic 'default' export.
31
+ */
32
+ export declare function getDeadExports(graph: RepoGraph, options?: DeadExportsOptions): DeadExportsResult;
8
33
  export declare function getBlastRadius(graph: RepoGraph, filePaths: string[], maxDepth?: number): BlastRadiusResult;
9
34
  export declare function getKeyFiles(graph: RepoGraph, topN?: number): GraphNode[];
10
35
  export declare function getFileOntology(graph: RepoGraph, filePath: string): FileOntology | null;
@@ -7,7 +7,23 @@
7
7
  * Every other submodule imports from here.
8
8
  */
9
9
  export declare const REPO_GRAPH_FILENAME = "repo-graph.json";
10
- export declare const GRAPH_SCHEMA_VERSION = "1.0.0";
10
+ /**
11
+ * Graph schema version.
12
+ *
13
+ * 1.1.0 added per-edge `usedSymbols` (imported symbols actually referenced in
14
+ * the importing file) and per-node `exportLines`, enabling the `callers` and
15
+ * `dead_exports` queries. Both fields are optional, so graphs written by older
16
+ * versions (1.0.0) still load — but `dead_exports` requires >= 1.1.0 data and
17
+ * self-gates via {@link isSchemaVersionAtLeast} rather than relying on the
18
+ * loader (which only checks that a version string is present, not its value).
19
+ */
20
+ export declare const GRAPH_SCHEMA_VERSION = "1.1.0";
21
+ /**
22
+ * Compare dotted numeric version strings (e.g. '1.1.0' >= '1.1.0').
23
+ * Missing/non-numeric segments are treated as 0. Returns true when `version`
24
+ * is greater than or equal to `minimum`.
25
+ */
26
+ export declare function isSchemaVersionAtLeast(version: string | undefined, minimum: string): boolean;
11
27
  export declare const FILE_ROLE_VALUES: readonly ["api_route", "middleware", "service_module", "data_module", "swarm_tool", "agent", "hook", "config", "schema", "test_file", "cli_command", "documentation", "source_module"];
12
28
  export type FileRole = (typeof FILE_ROLE_VALUES)[number];
13
29
  export declare const ROUTE_METHOD_VALUES: readonly ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD", "ALL"];
@@ -73,6 +89,13 @@ export interface GraphNode {
73
89
  moduleName: string;
74
90
  /** Exported symbols from this file */
75
91
  exports: string[];
92
+ /**
93
+ * Definition line for each exported symbol, keyed by symbol name (1-based).
94
+ * Optional and best-effort: present on graphs built at schema >= 1.1.0,
95
+ * absent for symbols whose line could not be determined. Used to point
96
+ * `dead_exports` candidates at a location.
97
+ */
98
+ exportLines?: Record<string, number>;
76
99
  /** Imported module specifiers */
77
100
  imports: string[];
78
101
  /** Language/extension of the file */
@@ -98,6 +121,14 @@ export interface GraphEdge {
98
121
  importType: ImportType;
99
122
  /** Named symbols imported from the target, when statically detectable */
100
123
  importedSymbols?: string[];
124
+ /**
125
+ * The subset of the target's exported symbols (by their *exported* name)
126
+ * that are actually referenced in the source file's body — not merely
127
+ * imported. Computed at build time via a conservative, alias-aware textual
128
+ * scan (schema >= 1.1.0). Absent on namespace/side-effect/require/dynamic
129
+ * imports, where individual symbol usage is not statically resolvable.
130
+ */
131
+ usedSymbols?: string[];
101
132
  }
102
133
  export interface FileReference {
103
134
  file: string;
@@ -109,6 +140,47 @@ export interface SymbolReference {
109
140
  line?: number;
110
141
  importedAs: string;
111
142
  }
143
+ /**
144
+ * A file that references a specific exported symbol of a target file.
145
+ * `resolution` records how confidently the usage was attributed:
146
+ * - 'used' → the symbol was found referenced in the source body
147
+ * - 'imported' → fallback for graphs predating usedSymbols (schema < 1.1.0);
148
+ * the symbol is imported but body usage was not analyzed
149
+ */
150
+ export interface CallerReference {
151
+ file: string;
152
+ resolution: 'used' | 'imported';
153
+ }
154
+ /**
155
+ * An exported symbol with no detected in-repo reference. Advisory only —
156
+ * regex-based analysis cannot see dynamic dispatch, string-keyed access, or
157
+ * usage through namespace/barrel re-exports, so this is a *candidate* for
158
+ * review, never a directive to delete.
159
+ */
160
+ export interface DeadExportCandidate {
161
+ /** Module name (workspace-relative) of the file that owns the export */
162
+ file: string;
163
+ /** The exported symbol name */
164
+ symbol: string;
165
+ /** Definition line, when known (from exportLines) */
166
+ line?: number;
167
+ /** How many other in-repo files import this file at all */
168
+ importerCount: number;
169
+ }
170
+ export interface DeadExportsResult {
171
+ /** False when the graph predates schema 1.1.0 (rebuild required). */
172
+ schemaSupported: boolean;
173
+ /** Files whose exports were analyzed (imported by >= 1 other file). */
174
+ analyzedFiles: number;
175
+ /**
176
+ * Files skipped because at least one importer used a namespace/side-effect/
177
+ * require/dynamic import, making per-symbol usage unresolvable.
178
+ */
179
+ skippedUnresolvable: number;
180
+ candidates: DeadExportCandidate[];
181
+ /** Human-readable note describing scope and limitations of the result. */
182
+ note: string;
183
+ }
112
184
  export interface BlastRadiusResult {
113
185
  target: string[];
114
186
  directDependents: string[];
@@ -20,8 +20,9 @@ export { clearCache, getCachedGraph, getCachedMtime, isDirty, markDirty, setCach
20
20
  export { updateGraphForFiles } from './repo-graph/incremental';
21
21
  export type { ExtractFileOntologyInput } from './repo-graph/ontology';
22
22
  export { extractFileOntology } from './repo-graph/ontology';
23
- export { buildOntologyPreflightPacket, getBlastRadius, getDependencies, getFileOntology, getGraphNode, getImporters, getKeyFiles, getLocalizationContext, getPackageBoundaries, getSymbolConsumers, isGraphFresh, resetQueryCache, } from './repo-graph/query';
23
+ export type { DeadExportsOptions } from './repo-graph/query';
24
+ export { buildOntologyPreflightPacket, getBlastRadius, getCallers, getDeadExports, getDependencies, getFileOntology, getGraphNode, getImporters, getKeyFiles, getLocalizationContext, getPackageBoundaries, getSymbolConsumers, isGraphFresh, resetQueryCache, } from './repo-graph/query';
24
25
  export { getGraphPath, loadGraph, loadGraphSync, loadOrCreateGraph, saveGraph, saveIfDirty, } from './repo-graph/storage';
25
- export type { BlastRadiusResult, BuildWorkspaceGraphOptions, ConventionFact, DataOperationFact, FileOntology, FileReference, FileRole, GraphEdge, GraphNode, LocalizationBlock, OntologyFinding, PackageBoundarySummary, RepoGraph, RouteFact, RouteMethod, SecurityFact, SymbolReference, } from './repo-graph/types';
26
- export { createEmptyGraph, GRAPH_SCHEMA_VERSION, normalizeGraphPath, REPO_GRAPH_FILENAME, updateGraphMetadata, } from './repo-graph/types';
26
+ export type { BlastRadiusResult, BuildWorkspaceGraphOptions, CallerReference, ConventionFact, DataOperationFact, DeadExportCandidate, DeadExportsResult, FileOntology, FileReference, FileRole, GraphEdge, GraphNode, LocalizationBlock, OntologyFinding, PackageBoundarySummary, RepoGraph, RouteFact, RouteMethod, SecurityFact, SymbolReference, } from './repo-graph/types';
27
+ export { createEmptyGraph, GRAPH_SCHEMA_VERSION, isSchemaVersionAtLeast, normalizeGraphPath, REPO_GRAPH_FILENAME, updateGraphMetadata, } from './repo-graph/types';
27
28
  export { validateGraphEdge, validateGraphNode, validateWorkspace, } from './repo-graph/validation';
@@ -0,0 +1,2 @@
1
+ import { createSwarmTool } from './create-tool';
2
+ export declare const retrieve_lane_output: ReturnType<typeof createSwarmTool>;
@@ -155,6 +155,10 @@ export declare const TOOL_METADATA: {
155
155
  description: string;
156
156
  agents: ("reviewer" | "test_engineer" | "coder" | "docs" | "designer" | "explorer" | "sme" | "critic" | "critic_sounding_board" | "critic_drift_verifier" | "critic_hallucination_verifier" | "critic_architecture_supervisor" | "critic_oversight" | "architect" | "docs_design" | "spec_writer")[];
157
157
  };
158
+ retrieve_lane_output: {
159
+ description: string;
160
+ agents: "architect"[];
161
+ };
158
162
  extract_code_blocks: {
159
163
  description: string;
160
164
  agents: ("reviewer" | "test_engineer" | "coder" | "docs" | "designer" | "explorer" | "sme" | "architect" | "docs_design" | "spec_writer")[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.84.0",
3
+ "version": "7.86.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",