opencode-swarm 7.179.0 → 7.179.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.
Files changed (70) hide show
  1. package/.opencode/skills/execute/SKILL.md +9 -8
  2. package/.opencode/skills/running-tests/SKILL.md +41 -36
  3. package/.opencode/skills/writing-tests/SKILL.md +11 -4
  4. package/binaries/win32-arm64/swarm-sandbox-runner.exe +0 -0
  5. package/binaries/win32-x64/swarm-sandbox-runner.exe +0 -0
  6. package/dist/agents/explorer.d.ts +1 -1
  7. package/dist/cli/{coder-settlement-7pt3a0y0.js → coder-settlement-f1nmezzv.js} +3 -3
  8. package/dist/cli/{config-doctor-82w4bp4b.js → config-doctor-ena2803f.js} +2 -2
  9. package/dist/cli/{core-9rqzs794.js → core-fcfzme3m.js} +1 -1
  10. package/dist/cli/{curator-llm-factory-cbm1ny30.js → curator-llm-factory-dds2fnhj.js} +21 -21
  11. package/dist/cli/{curator-m8act07j.js → curator-q9s5q9v4.js} +21 -21
  12. package/dist/cli/{dispatch-3rwdxpp2.js → dispatch-p5zjg5e6.js} +1 -1
  13. package/dist/cli/{evidence-summary-service-a99bgje1.js → evidence-summary-service-wtj8mkm6.js} +6 -6
  14. package/dist/cli/{explorer-z0cf5cz0.js → explorer-m50sfrp7.js} +1 -1
  15. package/dist/cli/{gate-evidence-yssmxba5.js → gate-evidence-h83yb8nd.js} +2 -2
  16. package/dist/cli/{guardrail-explain-ffwmhf7s.js → guardrail-explain-qm5wej7v.js} +22 -22
  17. package/dist/cli/{guardrail-log-j2wtq7p2.js → guardrail-log-zf1htf1d.js} +3 -3
  18. package/dist/cli/{guardrail-reset-07byr7nr.js → guardrail-reset-f2p198j3.js} +21 -21
  19. package/dist/cli/{hive-promoter-ewrz7vh1.js → hive-promoter-1mhx2jh0.js} +21 -21
  20. package/dist/cli/{index-yagqxt2p.js → index-5d224akk.js} +1 -1
  21. package/dist/cli/{index-tmy46dtd.js → index-93nx95me.js} +3 -3
  22. package/dist/cli/{index-amf88k1e.js → index-9fb01jk5.js} +1 -1
  23. package/dist/cli/{index-twtez316.js → index-9s1xzvnn.js} +1 -1
  24. package/dist/cli/{index-kanxpgf8.js → index-ajm7ebyd.js} +2 -2
  25. package/dist/cli/{index-7zmbtxw1.js → index-aqpwm350.js} +1 -1
  26. package/dist/cli/{index-09wm3963.js → index-b567t0cr.js} +2 -2
  27. package/dist/cli/{index-8815e95e.js → index-dz12bshh.js} +3 -3
  28. package/dist/cli/{index-hwcra3y9.js → index-epfjc1c1.js} +3 -3
  29. package/dist/cli/{index-zgvzbz48.js → index-hamqvzqn.js} +69 -13
  30. package/dist/cli/{index-d66zb40k.js → index-ky262b73.js} +1605 -716
  31. package/dist/cli/{index-1sz02k85.js → index-m1w40kfw.js} +1 -1
  32. package/dist/cli/{index-kmhnkn6t.js → index-n2wjrgcs.js} +1 -1
  33. package/dist/cli/{index-1rwyfvq2.js → index-pfg3jwe9.js} +1 -1
  34. package/dist/cli/{index-pxtye2ng.js → index-pn023bf9.js} +23 -23
  35. package/dist/cli/{index-0bc8jdnv.js → index-q375xdcw.js} +1 -1
  36. package/dist/cli/{index-9p1pqykb.js → index-rb9jmj30.js} +2 -2
  37. package/dist/cli/{index-1c1dbwze.js → index-rdec0y3z.js} +1 -1
  38. package/dist/cli/{index-sv4y1cma.js → index-sj29n50e.js} +1 -1
  39. package/dist/cli/{index-qxk5qkfh.js → index-vp9pn7sv.js} +5 -5
  40. package/dist/cli/{index-etmwjgre.js → index-w4c2repz.js} +21 -21
  41. package/dist/cli/{index-80q47hpw.js → index-xy7k7f3k.js} +2 -2
  42. package/dist/cli/{index-3hne91yd.js → index-y94vwx2q.js} +3 -3
  43. package/dist/cli/{index-wvpsm8ja.js → index-y98fvmb8.js} +4 -4
  44. package/dist/cli/{index-ndwbb3xm.js → index-yp25bc9n.js} +4 -4
  45. package/dist/cli/{index-6tnkvqr9.js → index-zbhvr9st.js} +1 -1
  46. package/dist/cli/index.js +22 -22
  47. package/dist/cli/{knowledge-escalator-yx97q9c1.js → knowledge-escalator-z6tkgrjq.js} +6 -6
  48. package/dist/cli/{knowledge-events-p269fyvv.js → knowledge-events-2bgefatz.js} +4 -4
  49. package/dist/cli/{knowledge-store-36zemyqa.js → knowledge-store-1fphg9sa.js} +1 -1
  50. package/dist/cli/{knowledge-validator-rd20yq41.js → knowledge-validator-723h2vck.js} +2 -2
  51. package/dist/cli/{mcp-sg9zrkz2.js → mcp-xyswgya5.js} +1 -1
  52. package/dist/cli/{pending-delegations-8p2gf4kt.js → pending-delegations-5zm19yvv.js} +2 -2
  53. package/dist/cli/{pr-subscriptions-4dj9r71h.js → pr-subscriptions-5hm6hzv6.js} +1 -1
  54. package/dist/cli/{pr-workflow-gate-8dgz5z1h.js → pr-workflow-gate-48rzb2bh.js} +21 -21
  55. package/dist/cli/{scan-cursor-nx0jv9ya.js → scan-cursor-m28tddrg.js} +2 -2
  56. package/dist/cli/{schema-q6gsrxwz.js → schema-jt9axyj6.js} +1 -1
  57. package/dist/cli/{scope-persistence-1k4xsyh7.js → scope-persistence-d0358pw7.js} +5 -5
  58. package/dist/cli/{server-shhxq34t.js → server-d5jxcbxz.js} +21 -21
  59. package/dist/cli/{skill-generator-6j7tq2tb.js → skill-generator-qanka67x.js} +7 -7
  60. package/dist/cli/{snapshot-coordination-init-h8n8w1cm.js → snapshot-coordination-init-mhrq11p8.js} +21 -21
  61. package/dist/cli/{worktree-collision-ownership-97jzh4ra.js → worktree-collision-ownership-ygdbpexh.js} +2 -2
  62. package/dist/cli/{worktree-isolation-g4w74ccb.js → worktree-isolation-4855f2az.js} +21 -21
  63. package/dist/index.js +207 -200
  64. package/dist/lang/backends/go.d.ts +2 -0
  65. package/dist/mutation/engine.d.ts +1 -0
  66. package/dist/test-impact/analyzer.d.ts +46 -4
  67. package/dist/test-impact/constants.d.ts +4 -0
  68. package/dist/tools/mutation-test.d.ts +11 -5
  69. package/dist/tools/test-runner.d.ts +34 -6
  70. package/package.json +1 -1
@@ -10,6 +10,8 @@
10
10
  * `typescript.ts` for the rationale; backend-purity test enforces.
11
11
  */
12
12
  import type { LanguageBackend } from '../backend';
13
+ /** Avoid spending unbounded time parsing an attacker-controlled source file. */
14
+ export declare const MAX_IMPORT_SOURCE_BYTES: number;
13
15
  declare function extractImports(_sourceFile: string, source: string): string[];
14
16
  /**
15
17
  * Build the Go backend from the registered profile.
@@ -95,6 +95,7 @@ export declare const _internals: {
95
95
  * `args.executable === 'git'`) keeps working for `git`-flavored callers.
96
96
  */
97
97
  resolveGitExecutable: typeof resolveGitExecutable;
98
+ beforeRestoreWrite: () => void;
98
99
  };
99
100
  export declare function executeMutation(patch: MutationPatch, testCommand: string[], testFiles: string[], workingDir: string, options?: MutationExecutionOptions): Promise<MutationResult>;
100
101
  export declare function computeReport(results: MutationResult[], durationMs: number, budgetMs?: number): MutationReport;
@@ -1,4 +1,20 @@
1
1
  import { validateProjectRoot } from '../evidence/manager.js';
2
+ /**
3
+ * Impact analysis is advisory and must never turn a caller's request into an
4
+ * unbounded workspace scan. These limits are deliberately larger than the
5
+ * 50-file execution cap: a normal repository may have more test files than a
6
+ * single invocation may safely execute, but a pathological repository must
7
+ * still fail closed before it consumes unbounded memory or CPU.
8
+ */
9
+ export declare const MAX_IMPACT_TEST_FILES = 4096;
10
+ export declare const MAX_IMPACT_TEST_FILE_BYTES: number;
11
+ export declare const MAX_IMPACT_GO_MOD_BYTES: number;
12
+ export declare const MAX_IMPACT_SCAN_BYTES: number;
13
+ export declare const MAX_IMPACT_WALK_ENTRIES = 100000;
14
+ export declare const MAX_IMPACT_SCAN_DEPTH = 32;
15
+ export declare const MAX_IMPACT_CACHE_BYTES: number;
16
+ export declare const MAX_IMPACT_MAP_SOURCES = 10000;
17
+ export declare const MAX_IMPACT_MAP_REFERENCES = 100000;
2
18
  export interface TestImpactResult {
3
19
  impactedTests: string[];
4
20
  unrelatedTests: string[];
@@ -6,9 +22,24 @@ export interface TestImpactResult {
6
22
  impactMap: Record<string, string[]>;
7
23
  budgetExceeded?: boolean;
8
24
  }
25
+ export type ImpactCacheStatus = 'fresh' | 'missing' | 'corrupt' | 'legacy' | 'stale' | 'rebuilt_missing' | 'rebuilt_corrupt' | 'rebuilt_legacy' | 'rebuilt_stale' | 'overflow' | 'overflow_unverified' | 'missing_unverified' | 'corrupt_unverified' | 'legacy_unverified' | 'fresh_unverified';
26
+ export interface ImpactCacheInspection {
27
+ status: ImpactCacheStatus;
28
+ cachePath: string;
29
+ }
30
+ interface TestFileIdentity {
31
+ path: string;
32
+ size: number;
33
+ mtimeMs: number;
34
+ digest: string;
35
+ }
9
36
  declare function normalizePath(p: string): string;
10
- declare function isCacheStale(impactMap: Record<string, string[]>, generatedAtMs: number): boolean;
37
+ declare function isCacheStale(impactMap: Record<string, string[]>, generatedAtMs: number, testFiles?: TestFileIdentity[], cwd?: string): boolean;
11
38
  declare function resolveRelativeImport(fromDir: string, importPath: string): string | null;
39
+ declare function findGoModule(fromDir: string): {
40
+ moduleRoot: string;
41
+ modulePath: string;
42
+ } | null;
12
43
  /**
13
44
  * Test-only: clear the go-module memoization cache. Production code
14
45
  * should never need this — the cache is per-call-graph scoped, but tests
@@ -17,7 +48,10 @@ declare function resolveRelativeImport(fromDir: string, importPath: string): str
17
48
  declare function _clearGoModuleCache(): void;
18
49
  declare function findTestFilesSync(cwd: string): string[];
19
50
  declare function extractImports(content: string): string[];
20
- declare function buildImpactMapInternal(cwd: string): Promise<Record<string, string[]>>;
51
+ declare function buildImpactMapInternal(cwd: string, testFilesOverride?: string[]): Promise<Record<string, string[]>>;
52
+ export declare function getImpactCacheStatus(cwd: string, options?: {
53
+ verify?: boolean;
54
+ }): ImpactCacheInspection;
21
55
  export declare const _internals: {
22
56
  validateProjectRoot: typeof validateProjectRoot;
23
57
  normalizePath: typeof normalizePath;
@@ -25,11 +59,14 @@ export declare const _internals: {
25
59
  resolveRelativeImport: typeof resolveRelativeImport;
26
60
  findTestFilesSync: typeof findTestFilesSync;
27
61
  extractImports: typeof extractImports;
62
+ findGoModule: typeof findGoModule;
28
63
  buildImpactMapInternal: typeof buildImpactMapInternal;
29
64
  buildImpactMap: typeof buildImpactMap;
30
65
  loadImpactMap: typeof loadImpactMap;
66
+ loadImpactMapWithStatus: typeof loadImpactMapWithStatus;
31
67
  saveImpactMap: typeof saveImpactMap;
32
68
  analyzeImpact: typeof analyzeImpact;
69
+ getImpactCacheStatus: typeof getImpactCacheStatus;
33
70
  _clearGoModuleCache: typeof _clearGoModuleCache;
34
71
  };
35
72
  export declare function buildImpactMap(cwd: string): Promise<Record<string, string[]>>;
@@ -38,7 +75,12 @@ export interface LoadImpactMapOptions {
38
75
  * Use for estimation-only reads where slight staleness is acceptable. */
39
76
  skipRebuild?: boolean;
40
77
  }
78
+ export interface ImpactMapLoadResult {
79
+ map: Record<string, string[]>;
80
+ status: ImpactCacheStatus;
81
+ }
82
+ export declare function loadImpactMapWithStatus(cwd: string, options?: LoadImpactMapOptions): Promise<ImpactMapLoadResult>;
41
83
  export declare function loadImpactMap(cwd: string, options?: LoadImpactMapOptions): Promise<Record<string, string[]>>;
42
- declare function saveImpactMap(cwd: string, impactMap: Record<string, string[]>): Promise<void>;
43
- export declare function analyzeImpact(changedFiles: string[], cwd: string, budget?: number): Promise<TestImpactResult>;
84
+ declare function saveImpactMap(cwd: string, impactMap: Record<string, string[]>, testFiles?: string[]): Promise<void>;
85
+ export declare function analyzeImpact(changedFiles: string[], cwd: string, budget?: number, impactMapOverride?: Record<string, string[]>): Promise<TestImpactResult>;
44
86
  export {};
@@ -0,0 +1,4 @@
1
+ /** Shared cap for any tool that executes a resolved test-file selection. */
2
+ export declare const MAX_SAFE_TEST_FILES = 50;
3
+ /** Version marker for the rebuildable impact-cache envelope. */
4
+ export declare const IMPACT_CACHE_VERSION = 2;
@@ -1,8 +1,14 @@
1
- import { analyzeImpact } from '../test-impact/analyzer.js';
1
+ import * as path from 'node:path';
2
2
  import { createSwarmTool } from './create-tool';
3
- export declare const mutation_test: ReturnType<typeof createSwarmTool>;
3
+ declare function normalizeWorkspaceFile(value: unknown, cwd: string, requireExisting: boolean): {
4
+ value: string;
5
+ absolute: string;
6
+ } | {
7
+ error: string;
8
+ };
4
9
  export declare const _internals: {
5
- mutationInternals: {
6
- analyzeImpact: typeof analyzeImpact;
7
- };
10
+ pathRelative: typeof path.relative;
11
+ normalizeWorkspaceFile: typeof normalizeWorkspaceFile;
8
12
  };
13
+ export declare const mutation_test: ReturnType<typeof createSwarmTool>;
14
+ export {};
@@ -4,7 +4,7 @@ import { resolveLocalNodeTool } from '../build/command-resolution';
4
4
  import { isCommandAvailable } from '../build/discovery';
5
5
  import type { NativeTestTarget, TestScope } from '../lang/backend';
6
6
  import { buildNativeTargetCommand } from '../lang/default-backend';
7
- import { analyzeImpact, loadImpactMap } from '../test-impact/analyzer.js';
7
+ import { analyzeImpact, getImpactCacheStatus, type ImpactCacheStatus, loadImpactMap, loadImpactMapWithStatus } from '../test-impact/analyzer.js';
8
8
  import { getAllHistory, type TestRunRecord } from '../test-impact/history-store.js';
9
9
  import { bunSpawn } from '../utils/bun-compat';
10
10
  export declare const MAX_OUTPUT_BYTES = 512000;
@@ -12,6 +12,10 @@ export declare const MAX_COMMAND_LENGTH = 500;
12
12
  export declare const DEFAULT_TIMEOUT_MS = 60000;
13
13
  export declare const MAX_TIMEOUT_MS = 300000;
14
14
  export declare const MAX_SAFE_TEST_FILES = 50;
15
+ export declare const MAX_SAFE_SOURCE_FILES = 1;
16
+ export declare const MAX_RAW_FILE_ENTRIES = 512;
17
+ export declare const MAX_FILE_PATH_LENGTH = 4096;
18
+ export declare const MAX_GRAPH_FILE_BYTES: number;
15
19
  /**
16
20
  * Estimate the fan-out (number of unique test files) for given source files
17
21
  * by reading the cached impact map without spawning a subprocess.
@@ -22,6 +26,7 @@ export declare const MAX_SAFE_TEST_FILES = 50;
22
26
  */
23
27
  export declare function estimateFanOut(sourceFiles: string[], cwd: string): Promise<{
24
28
  estimatedCount: number;
29
+ status: 'advisory' | 'unavailable';
25
30
  }>;
26
31
  export declare const SUPPORTED_FRAMEWORKS: readonly ["bun", "vitest", "jest", "mocha", "pytest", "cargo", "pester", "go-test", "maven", "gradle", "dotnet-test", "ctest", "swift-test", "dart-test", "rspec", "minitest", "pest", "phpunit", "php-artisan"];
27
32
  export type TestFramework = (typeof SUPPORTED_FRAMEWORKS)[number] | 'none';
@@ -35,12 +40,11 @@ export interface TestRunnerArgs {
35
40
  bail?: boolean;
36
41
  }
37
42
  export type RegressionOutcome = 'pass' | 'skip' | 'no_impacted_tests' | 'regression' | 'scope_exceeded' | 'error';
38
- /** Binding cap decision reported on every discovery-scope test_runner response. */
43
+ /** Binding cap decision reported on every discovery-scope response. */
39
44
  export interface CapDecision {
40
45
  decision: 'within_cap' | 'cap_exceeded';
41
46
  resolved_test_count: number;
42
47
  limit: number;
43
- source_file_count?: number;
44
48
  }
45
49
  export interface TestTotals {
46
50
  passed: number;
@@ -70,11 +74,9 @@ export interface TestSuccessResult {
70
74
  testCases?: ParsedTestCaseResult[];
71
75
  message?: string;
72
76
  outcome?: RegressionOutcome;
73
- /** Post-resolution deduplicated test-file set (discovery scopes only). */
77
+ resolution?: TestResolution;
74
78
  resolved_test_files?: string[];
75
- /** Binding cap decision — the post-resolution count, never an estimate. */
76
79
  cap_decision?: CapDecision;
77
- /** Non-empty exactly when resolution fell back to a narrower discovery scope. */
78
80
  fallback_reason?: string;
79
81
  }
80
82
  export interface TestErrorResult {
@@ -92,11 +94,35 @@ export interface TestErrorResult {
92
94
  message?: string;
93
95
  outcome?: RegressionOutcome;
94
96
  attempted_scope?: 'graph';
97
+ resolution?: TestResolution;
95
98
  resolved_test_files?: string[];
96
99
  cap_decision?: CapDecision;
97
100
  fallback_reason?: string;
98
101
  }
99
102
  export type TestResult = TestSuccessResult | TestErrorResult;
103
+ export interface TestResolution {
104
+ requestedScope: TestScope;
105
+ effectiveScope: TestScope;
106
+ sourceFiles: string[];
107
+ /**
108
+ * Normalized test files. Execute decisions are always capped at `cap`;
109
+ * scope-exceeded decisions may retain one `cap + 1` sentinel for evidence.
110
+ */
111
+ resolvedFiles: string[];
112
+ cap: number;
113
+ decision: 'execute' | 'scope_exceeded' | 'skip';
114
+ /** Structured fan-out estimate; the scalar fields below are compatibility aliases. */
115
+ estimate: {
116
+ count: number;
117
+ status: 'advisory' | 'unavailable' | 'not_run';
118
+ };
119
+ /** Backward-compatible aliases for consumers that predate the structured estimate. */
120
+ estimateCount: number;
121
+ estimateStatus: 'advisory' | 'unavailable' | 'not_run';
122
+ cacheStatus?: ImpactCacheStatus;
123
+ fallbackReason: string | null;
124
+ evaluable: boolean;
125
+ }
100
126
  /**
101
127
  * Phase 3 dispatch path: detect the test framework via the
102
128
  * `LanguageBackend` registry from `src/lang/dispatch.ts`. Currently
@@ -175,6 +201,8 @@ export declare const test_runner: ReturnType<typeof tool>;
175
201
  export declare const _internals: {
176
202
  analyzeImpact: typeof analyzeImpact;
177
203
  loadImpactMap: typeof loadImpactMap;
204
+ loadImpactMapWithStatus: typeof loadImpactMapWithStatus;
205
+ getImpactCacheStatus: typeof getImpactCacheStatus;
178
206
  isCommandAvailable: typeof isCommandAvailable;
179
207
  existsSync: typeof fs.existsSync;
180
208
  readdirSync: typeof fs.readdirSync;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.179.0",
3
+ "version": "7.179.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",