opencode-swarm 7.146.5 → 7.147.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 (99) hide show
  1. package/dist/cli/{ast-diff-wbjcazfx.js → ast-diff-ekd9v10f.js} +3 -3
  2. package/dist/cli/{config-doctor-28e6h9ex.js → config-doctor-8nskdpgd.js} +2 -2
  3. package/dist/cli/{core-n57ssze0.js → core-9rt6kbk1.js} +2 -2
  4. package/dist/cli/{curation-policy-g353f457.js → curation-policy-9d7jx7cg.js} +4 -4
  5. package/dist/cli/{curator-drift-r50x1rac.js → curator-drift-fv4rttf4.js} +2 -2
  6. package/dist/cli/curator-llm-factory-8xdxbmnz.js +64 -0
  7. package/dist/cli/{curator-e6p9vysv.js → curator-xvymjgan.js} +32 -32
  8. package/dist/cli/{dispatch-ndxbsk98.js → dispatch-w0rzasz3.js} +2 -2
  9. package/dist/cli/{evidence-summary-service-b2xp0m26.js → evidence-summary-service-k7a2s8f8.js} +11 -11
  10. package/dist/cli/{gate-evidence-fmbx6hp1.js → gate-evidence-bbpvx28c.js} +6 -6
  11. package/dist/cli/guardrail-explain-qz2hfyb2.js +65 -0
  12. package/dist/cli/{guardrail-log-1bbg0vx4.js → guardrail-log-6098jxes.js} +4 -4
  13. package/dist/cli/guardrail-reset-2bcccwmx.js +90 -0
  14. package/dist/cli/{hive-promoter-trew6apr.js → hive-promoter-9xzf0r98.js} +32 -32
  15. package/dist/cli/{index-0pya01vw.js → index-014mntpw.js} +6 -6
  16. package/dist/cli/{index-ktpj357z.js → index-1k41c7kt.js} +2 -2
  17. package/dist/cli/{index-p3k155dv.js → index-1xvxd02x.js} +1 -1
  18. package/dist/cli/{index-hn0hvgtt.js → index-2qapn7fk.js} +1 -1
  19. package/dist/cli/{index-w8pgjr75.js → index-4cgee5vh.js} +1 -1
  20. package/dist/cli/{index-cp8jp4cv.js → index-59q7jma6.js} +6 -6
  21. package/dist/cli/{index-zqmzn9hk.js → index-5qfp2kt4.js} +6 -6
  22. package/dist/cli/{index-p4ar0k0n.js → index-6cxb7ng4.js} +4 -4
  23. package/dist/cli/{index-gqx0rq53.js → index-7tvbvecm.js} +1 -1
  24. package/dist/cli/{index-npw2xm46.js → index-8861hfbt.js} +32316 -30496
  25. package/dist/cli/{index-vjkfhqef.js → index-8k9hw17k.js} +4 -4
  26. package/dist/cli/{index-cpzra8my.js → index-9b50bt13.js} +2 -2
  27. package/dist/cli/{index-52460nma.js → index-aahyrzmm.js} +2 -2
  28. package/dist/cli/{index-tp5ytzzg.js → index-avcqq7xc.js} +1 -1
  29. package/dist/cli/{index-hw1yghpg.js → index-axcvb5kf.js} +1 -1
  30. package/dist/cli/{index-7sy3aa9m.js → index-b43rt5ph.js} +3 -3
  31. package/dist/cli/{index-aybph866.js → index-b7qzwv3t.js} +3 -3
  32. package/dist/cli/{index-hcb25p12.js → index-b834mas0.js} +2 -2
  33. package/dist/cli/{index-ymyv4d36.js → index-b99vp668.js} +34 -34
  34. package/dist/cli/{index-8py21zn6.js → index-bp5n93w5.js} +1 -1
  35. package/dist/cli/{index-d3t7q4b8.js → index-by1f9ghd.js} +1 -1
  36. package/dist/cli/{index-rpy0bent.js → index-d3bdr78h.js} +2 -2
  37. package/dist/cli/{index-e1pxav9g.js → index-fxvgaeq4.js} +1 -1
  38. package/dist/cli/{index-z9yhhk6q.js → index-g8wwj0sz.js} +1 -1
  39. package/dist/cli/{index-7pggq9ys.js → index-gkhx2vkh.js} +1 -1
  40. package/dist/cli/{index-53asfj0j.js → index-kbp4xssa.js} +4 -4
  41. package/dist/cli/{index-fymrwjak.js → index-n5wzwz8x.js} +8 -5
  42. package/dist/cli/{index-abtrcs16.js → index-nj6rmyeh.js} +1 -1
  43. package/dist/cli/{index-3p4wgm0d.js → index-pgvx3rkq.js} +1 -1
  44. package/dist/cli/index-q7sjgr1y.js +52 -0
  45. package/dist/cli/{index-fjhc8mk2.js → index-q85xv7t6.js} +10 -2
  46. package/dist/cli/{index-rqgnad5w.js → index-qy5yz7fn.js} +10 -4
  47. package/dist/cli/{index-zj6t9zgx.js → index-r3mvsbtq.js} +8 -1
  48. package/dist/cli/{index-ddpkwdcb.js → index-r9wnyq0v.js} +1 -1
  49. package/dist/cli/{index-55g08cg2.js → index-t4xa2yss.js} +5 -5
  50. package/dist/cli/{index-cyxdm0v3.js → index-vpzvmp21.js} +2 -2
  51. package/dist/cli/{index-f75qjtn5.js → index-zwc96x0a.js} +1 -1
  52. package/dist/cli/index.js +32 -32
  53. package/dist/cli/{knowledge-escalator-dyrrftth.js → knowledge-escalator-300p0bvr.js} +11 -11
  54. package/dist/cli/{knowledge-events-hqrwgn29.js → knowledge-events-5ncg5xv1.js} +9 -9
  55. package/dist/cli/{knowledge-link-jkx8xjxp.js → knowledge-link-stzsjagk.js} +3 -3
  56. package/dist/cli/{knowledge-store-fn7whe2j.js → knowledge-store-mn75hsww.js} +4 -4
  57. package/dist/cli/{knowledge-validator-6zb1j8c4.js → knowledge-validator-763r7qpn.js} +6 -6
  58. package/dist/cli/{pending-delegations-k2yqg1sj.js → pending-delegations-k4x00mqc.js} +3 -3
  59. package/dist/cli/{pr-subscriptions-js5v2xr6.js → pr-subscriptions-x2mqc3f1.js} +3 -3
  60. package/dist/cli/{runner-q7d22d1w.js → runner-26bc3x73.js} +5 -5
  61. package/dist/cli/{runtime-x10qb3z1.js → runtime-wjwbpp9j.js} +2 -2
  62. package/dist/cli/{scan-cursor-m04qgx82.js → scan-cursor-b7kyjefy.js} +5 -5
  63. package/dist/cli/{schema-40w13gdv.js → schema-zjhwka27.js} +1 -1
  64. package/dist/cli/{scope-persistence-fz2r889v.js → scope-persistence-aa7gkgz0.js} +7 -7
  65. package/dist/cli/{skill-generator-413k36q9.js → skill-generator-nsa7ay0c.js} +14 -13
  66. package/dist/cli/{workspace-snapshot-kznz5e13.js → workspace-snapshot-nq25j94x.js} +2 -2
  67. package/dist/cli/{worktree-collision-ownership-xj0bsg92.js → worktree-collision-ownership-q2gswg16.js} +4 -4
  68. package/dist/cli/{worktree-isolation-50afhbga.js → worktree-isolation-3pw7nwnh.js} +32 -32
  69. package/dist/cli/{worktree-provisioning-owner-72cyddz5.js → worktree-provisioning-owner-cve95q4f.js} +3 -3
  70. package/dist/commands/guardrail-reset.d.ts +2 -0
  71. package/dist/commands/registry.d.ts +16 -3
  72. package/dist/config/schema.d.ts +2 -0
  73. package/dist/failures/action-circuit.d.ts +69 -0
  74. package/dist/failures/action-identity.d.ts +33 -0
  75. package/dist/failures/invocation-failure.d.ts +77 -0
  76. package/dist/full-auto/oversight.d.ts +21 -0
  77. package/dist/full-auto/policy.d.ts +22 -0
  78. package/dist/full-auto/recovery.d.ts +43 -0
  79. package/dist/full-auto/severe-result.d.ts +86 -0
  80. package/dist/full-auto/state.d.ts +18 -0
  81. package/dist/hooks/full-auto-intercept.d.ts +1 -1
  82. package/dist/hooks/gate-denial-tracker.d.ts +1 -1
  83. package/dist/hooks/guardrails/nontransient-circuit.d.ts +19 -5
  84. package/dist/index.js +2827 -2803
  85. package/dist/lang/symbol-visibility.d.ts +13 -0
  86. package/dist/learning/admission.d.ts +1 -1
  87. package/dist/models/model-override-state.d.ts +47 -0
  88. package/dist/models/task-model-routing.d.ts +71 -0
  89. package/dist/services/diagnose-service.d.ts +2 -2
  90. package/dist/tools/dispatch-lanes.d.ts +8 -0
  91. package/dist/tools/repo-graph/builder.d.ts +19 -0
  92. package/dist/tools/repo-graph/ontology.d.ts +23 -0
  93. package/dist/tools/repo-graph/types.d.ts +34 -6
  94. package/dist/utils/model-dispatch-fallback.d.ts +31 -10
  95. package/dist/utils/timeout.d.ts +18 -4
  96. package/package.json +1 -1
  97. package/dist/cli/curator-llm-factory-bzvv3grb.js +0 -64
  98. package/dist/cli/guardrail-explain-g1nqbz0j.js +0 -65
  99. package/dist/cli/index-wx8zdh4a.js +0 -24
@@ -34,6 +34,19 @@ export interface SymbolVisibilityContext {
34
34
  pythonAllNames?: Set<string> | null;
35
35
  /** For Python methods: true if the enclosing class is exported (in __all__ or public naming convention) */
36
36
  pythonParentClassExported?: boolean;
37
+ /**
38
+ * Tree-sitter node type of the nearest enclosing type container
39
+ * (`class_declaration`, `interface_declaration`, `enum_declaration`,
40
+ * `record_declaration`, `struct_declaration`, `object_declaration`), or
41
+ * `undefined` when the declaration has no enclosing type container.
42
+ *
43
+ * Only populated for the JVM/.NET grammars (java/kotlin/csharp), where the
44
+ * *kind* of container decides the implicit visibility of a member that
45
+ * carries no explicit modifier (an interface member is implicitly public in
46
+ * both Java and C#, a C# class member is implicitly private, a Java class
47
+ * member is implicitly package-private).
48
+ */
49
+ parentContainerType?: string;
37
50
  }
38
51
  export declare function collectCommonJsExports(source: string): Map<string, CommonJsExportInfo>;
39
52
  export declare function collectPythonAllNames(source: string): Set<string> | null;
@@ -19,7 +19,7 @@
19
19
  * - only genuinely cancellable work (the optional LLM screening call) is
20
20
  * bounded, via a manual `AbortController` + `setTimeout` (see
21
21
  * `timeoutSignal` below) + `isAbortError`. This deliberately does NOT use
22
- * `AbortSignal.timeout(...)` (unlike `micro-reflector.ts`): Bun on Windows
22
+ * the host's built-in timeout signal: Bun on Windows
23
23
  * has a native bug where that signal's `abort` event never fires when
24
24
  * awaited by a plain JS Promise (oven-sh/bun#29546) — exactly the shape
25
25
  * `screenCandidate`'s caller uses — which hung this file's own tests for
@@ -0,0 +1,47 @@
1
+ export interface ModelOverrideParts {
2
+ providerID: string;
3
+ modelID: string;
4
+ }
5
+ export interface ScopedModelOverrideKey {
6
+ sessionID: string;
7
+ invocationID: string;
8
+ role: string;
9
+ swarmID?: string;
10
+ }
11
+ export interface NormalizedModelChain {
12
+ readonly primary?: {
13
+ modelString: string;
14
+ override: ModelOverrideParts;
15
+ };
16
+ readonly fallbacks: readonly {
17
+ modelString: string;
18
+ override: ModelOverrideParts;
19
+ }[];
20
+ readonly signature: string;
21
+ readonly totalModels: number;
22
+ }
23
+ export interface ScopedModelSelection {
24
+ readonly generation: number;
25
+ readonly fallbackIndex: number;
26
+ readonly modelString?: string;
27
+ readonly model?: ModelOverrideParts;
28
+ readonly exhausted: boolean;
29
+ readonly totalModels: number;
30
+ }
31
+ export interface ScopedModelAdvanceResult {
32
+ readonly accepted: boolean;
33
+ readonly selection: ScopedModelSelection;
34
+ }
35
+ export interface ScopedModelSelectionSnapshotEntry {
36
+ readonly key: ScopedModelOverrideKey;
37
+ readonly generation: number;
38
+ readonly fallbackIndex: number;
39
+ readonly updatedAt: number;
40
+ }
41
+ export declare function normalizeModelChain(primaryModel: string | undefined, fallbackModels: Iterable<string | null | undefined>): NormalizedModelChain;
42
+ export declare function resolveScopedModelSelection(scope: ScopedModelOverrideKey, chain: NormalizedModelChain, now?: number): ScopedModelSelection;
43
+ export declare function advanceScopedModelSelection(scope: ScopedModelOverrideKey, chain: NormalizedModelChain, expectedGeneration: number, now?: number): ScopedModelAdvanceResult;
44
+ export declare function resetScopedModelSelection(scope: ScopedModelOverrideKey, expectedGeneration?: number): boolean;
45
+ export declare function clearScopedModelSelectionsForSession(sessionID: string): void;
46
+ export declare function getScopedModelSelectionSnapshot(): readonly ScopedModelSelectionSnapshotEntry[];
47
+ export declare function resetScopedModelSelectionStateForTests(): void;
@@ -0,0 +1,71 @@
1
+ import { getScopedModelSelectionSnapshot, type ModelOverrideParts, type ScopedModelOverrideKey } from './model-override-state.js';
2
+ export interface PendingTaskModelRouteInput {
3
+ parentSessionID: string;
4
+ invocationID: string;
5
+ callID: string;
6
+ role: string;
7
+ actionDigest: string;
8
+ swarmID?: string;
9
+ }
10
+ export interface BindTaskModelRouteChildInput {
11
+ parentSessionID: string;
12
+ callID: string;
13
+ childSessionID: string;
14
+ }
15
+ export interface AdvanceTaskModelRouteInput {
16
+ childSessionID: string;
17
+ role: string;
18
+ actionDigest: string;
19
+ primaryModel?: string;
20
+ fallbackModels?: Iterable<string | null | undefined>;
21
+ expectedGeneration?: number;
22
+ now?: number;
23
+ }
24
+ export interface ResolveTaskChatModelOverrideInput {
25
+ childSessionID: string;
26
+ role: string;
27
+ primaryModel?: string;
28
+ fallbackModels?: Iterable<string | null | undefined>;
29
+ actionDigest?: string;
30
+ lookupParentSessionID?: (childSessionID: string) => Promise<string | undefined>;
31
+ now?: number;
32
+ }
33
+ export interface TaskChatModelOverrideResolution {
34
+ status: 'override' | 'primary' | 'exhausted' | 'missing' | 'ambiguous' | 'mismatch';
35
+ model?: ModelOverrideParts;
36
+ modelString?: string;
37
+ fallbackIndex?: number;
38
+ generation?: number;
39
+ scope?: ScopedModelOverrideKey;
40
+ route?: PendingTaskModelRouteSnapshotEntry;
41
+ }
42
+ export interface TaskModelRouteAdvanceResult {
43
+ accepted: boolean;
44
+ exhausted: boolean;
45
+ fallbackIndex: number;
46
+ generation: number;
47
+ scope: ScopedModelOverrideKey;
48
+ route?: PendingTaskModelRouteSnapshotEntry;
49
+ }
50
+ export interface PendingTaskModelRouteSnapshotEntry {
51
+ parentSessionID: string;
52
+ invocationID: string;
53
+ callID: string;
54
+ role: string;
55
+ actionDigest: string;
56
+ swarmID?: string;
57
+ childSessionID?: string;
58
+ updatedAt: number;
59
+ }
60
+ export declare function registerPendingTaskModelRoute(input: PendingTaskModelRouteInput, now?: number): PendingTaskModelRouteSnapshotEntry;
61
+ export declare function bindPendingTaskModelRouteChild(input: BindTaskModelRouteChildInput, now?: number): PendingTaskModelRouteSnapshotEntry | undefined;
62
+ export declare function advancePendingTaskModelRoute(input: AdvanceTaskModelRouteInput): TaskModelRouteAdvanceResult | undefined;
63
+ export declare function resolveTaskChatModelOverride(input: ResolveTaskChatModelOverrideInput): Promise<TaskChatModelOverrideResolution>;
64
+ export declare function clearPendingTaskModelRoutesForSession(sessionID: string): void;
65
+ export declare function getPendingTaskModelRouteSnapshot(): readonly PendingTaskModelRouteSnapshotEntry[];
66
+ export declare function getTaskModelRoutingStateSnapshot(): {
67
+ routes: readonly PendingTaskModelRouteSnapshotEntry[];
68
+ scopedSelections: ReturnType<typeof getScopedModelSelectionSnapshot>;
69
+ };
70
+ export declare function clearAllTaskModelRoutingState(): void;
71
+ export declare const resetTaskModelRoutingStateForTests: typeof clearAllTaskModelRoutingState;
@@ -35,7 +35,7 @@ export declare function resolveGrammarDir(thisDir: string): string;
35
35
  * Get diagnose data from the swarm directory.
36
36
  * Returns structured health checks for GUI, background flows, or commands.
37
37
  */
38
- export declare function getDiagnoseData(directory: string): Promise<DiagnoseData>;
38
+ export declare function getDiagnoseData(directory: string, sessionID?: string): Promise<DiagnoseData>;
39
39
  /**
40
40
  * Format diagnose data as markdown for command output.
41
41
  */
@@ -44,4 +44,4 @@ export declare function formatDiagnoseMarkdown(diagnose: DiagnoseData): string;
44
44
  * Handle diagnose command - delegates to service and formats output.
45
45
  * Kept for backward compatibility - thin adapter.
46
46
  */
47
- export declare function handleDiagnoseCommand(directory: string, _args: string[]): Promise<string>;
47
+ export declare function handleDiagnoseCommand(directory: string, _args: string[], sessionID?: string): Promise<string>;
@@ -217,6 +217,10 @@ export interface SessionOps {
217
217
  };
218
218
  body: {
219
219
  agent: string;
220
+ model?: {
221
+ providerID: string;
222
+ modelID: string;
223
+ };
220
224
  tools: ReadOnlyToolPermissions;
221
225
  parts: Array<{
222
226
  type: 'text';
@@ -242,6 +246,10 @@ export interface SessionOps {
242
246
  };
243
247
  body: {
244
248
  agent: string;
249
+ model?: {
250
+ providerID: string;
251
+ modelID: string;
252
+ };
245
253
  tools: ReadOnlyToolPermissions;
246
254
  parts: Array<{
247
255
  type: 'text';
@@ -258,6 +258,25 @@ export declare function scanFileAsync(filePath: string, absoluteRoot: string, ma
258
258
  * @returns Complete RepoGraph with nodes and edges
259
259
  * @throws Error if workspace validation fails
260
260
  */
261
+ /**
262
+ * Restore the documented `targetKind` invariant: a `'node'` target is a file
263
+ * that actually became a graph node.
264
+ *
265
+ * Import resolution and the workspace walker apply different filters. The
266
+ * walker prunes `SKIP_DIRECTORIES` (`node_modules`, `dist`, `vendor`, ...) and
267
+ * unfollowed symlinks; `resolveModuleSpecifier` consults neither, so a real
268
+ * file inside a skipped directory resolves happily and produced an edge marked
269
+ * `targetKind: 'node'` pointing at a node that does not exist. Measured on both
270
+ * the dotted JVM/.NET path (`import node_modules.com.example.Foo;`) and the
271
+ * pre-existing relative path (`import '../node_modules/pkg/index'`).
272
+ *
273
+ * The edge is a real dependency, so it is kept rather than dropped — it is
274
+ * reclassified to `'asset'`, which already means "a real file that never
275
+ * becomes a node" and is correctly excluded from in-degree ranking, importer
276
+ * and dependent queries, and node-existence checks during incremental
277
+ * validation. Returns the number of edges reclassified.
278
+ */
279
+ export declare function reconcileEdgeTargetKinds(graph: RepoGraph): number;
261
280
  export declare function buildWorkspaceGraph(workspaceRoot: string, options?: BuildWorkspaceGraphOptions): RepoGraph;
262
281
  /**
263
282
  * Async, event-loop-safe variant of `buildWorkspaceGraph`. The traversal
@@ -15,4 +15,27 @@ export interface ExtractFileOntologyInput {
15
15
  */
16
16
  hasManifest?: (relDir: string) => boolean;
17
17
  }
18
+ /**
19
+ * Blank the CONTENTS of multi-line string literals, preserving newlines and
20
+ * length so line-anchored matching still lines up.
21
+ *
22
+ * `stripComments` removes comments but keeps string literals verbatim, so a
23
+ * line-initial `package` / `namespace` token inside a C# verbatim string
24
+ * (`@"…"`), a C# raw string, or a Java/Kotlin text block (`"""…"""`) matched the
25
+ * anchored regexes below and won the boundary — the real declaration lost,
26
+ * because `String.match` takes the first hit. That is legal, compilable source
27
+ * (a `@"…"` block holding SQL or config is ordinary C#), not a crafted spoof.
28
+ *
29
+ * Single-line string literals are not masked: their literal TEXT cannot contain
30
+ * a raw newline, so no interior line can be line-initial. The one exception is a
31
+ * C# interpolated string, which may span lines inside an interpolation hole —
32
+ * but a hole contains code, not literal text, so leaving it unmasked is correct.
33
+ * Only the multi-line forms are masked, which keeps the change narrow.
34
+ */
35
+ /**
36
+ * @internal Exported only so the scanner's structural invariants (termination,
37
+ * length preservation, line-count preservation) can be fuzzed directly. Not
38
+ * re-exported from the package index; call `extractFileOntology` instead.
39
+ */
40
+ export declare function maskMultilineStringLiterals(text: string, language: string): string;
18
41
  export declare function extractFileOntology(input: ExtractFileOntologyInput): FileOntology;
@@ -17,8 +17,10 @@ export declare const REPO_GRAPH_FILENAME = "repo-graph.json";
17
17
  * self-gates via {@link isSchemaVersionAtLeast} rather than relying on the
18
18
  * loader (which only checks that a version string is present, not its value).
19
19
  *
20
- * 1.2.0 adds per-node `exportRanges` (1-based inclusive line spans for each
21
- * exported symbol) and the top-level `symbolEdges` array (direct symbol-to-
20
+ * 1.2.0 adds per-node `exportRanges` (1-based inclusive line spans keyed by
21
+ * symbol name exported symbols for every grammar, plus non-exported member
22
+ * defs for java/kotlin/csharp; see the field docs) and the top-level
23
+ * `symbolEdges` array (direct symbol-to-
22
24
  * symbol reference edges). Both fields are optional, so 1.0.0 and 1.1.0 graphs
23
25
  * still load without corruption. New queries may use these fields to provide
24
26
  * more precise context-packing and symbol-level navigation.
@@ -122,11 +124,22 @@ export interface GraphNode {
122
124
  */
123
125
  exportLines?: Record<string, number>;
124
126
  /**
125
- * 1-based inclusive line span for each exported symbol, keyed by symbol
126
- * name. Present on graphs built at schema >= 1.2.0; absent on older
127
- * graphs. Used for precise context-packing around a symbol.
127
+ * 1-based inclusive line span per symbol, keyed by symbol name. Present on
128
+ * graphs built at schema >= 1.2.0; absent on older graphs. Used for precise
129
+ * context-packing around a symbol.
128
130
  * Each span value uses `startLine` / `endLine` to match the codebase
129
131
  * convention (see `ContextPackSpan` and `FileSymbolFacts`).
132
+ *
133
+ * SCOPE (issue #1529): exported symbols for every grammar, PLUS
134
+ * non-exported member defs for java/kotlin/csharp. A JVM/.NET member is
135
+ * deliberately never a file-level export, so without that widening
136
+ * `context_pack` could return no span at all for a Java method.
137
+ * `exports` and `exportLines` stay exported-only in every language.
138
+ *
139
+ * Duplicate names resolve so this map cannot disagree with `exportLines`:
140
+ * an exported def outranks a non-exported one; two exported defs take the
141
+ * last (as `exportLines` does); two non-exported defs take the first, and
142
+ * never appear in `exportLines` at all.
130
143
  */
131
144
  exportRanges?: Record<string, {
132
145
  startLine: number;
@@ -172,7 +185,22 @@ export interface GraphEdge {
172
185
  /**
173
186
  * Whether the resolved target is a graph node or an asset. `'node'` targets
174
187
  * are scannable source files that become graph nodes; `'asset'` targets are
175
- * real files (JSON/CSS/etc.) that never become nodes (schema >= 1.3.0).
188
+ * real files that never become nodes (schema >= 1.3.0).
189
+ *
190
+ * `'asset'` covers TWO cases, and the second is easy to miss:
191
+ * 1. a non-source file (JSON/CSS/etc.), which was never scannable; and
192
+ * 2. a file that IS scannable but the walker never indexed — it sits under a
193
+ * `SKIP_DIRECTORIES` entry (`node_modules`, `dist`, `vendor`, …) or behind
194
+ * an unfollowed symlink. Import resolution does not consult those rules,
195
+ * so it can resolve a real `.ts`/`.java` file the graph has no node for.
196
+ * Such edges are demoted to `'asset'` at graph assembly (see
197
+ * `reconcileEdgeTargetKinds`) so that `'node'` always means "a node exists
198
+ * for this target". The demotion is language-agnostic: it applies to any
199
+ * source file the walker skipped, not only to JVM/.NET ones.
200
+ *
201
+ * Consequence for consumers: `targetKind: 'asset'` no longer implies "not
202
+ * source code". Use `isScannableSourcePath(edge.target)` if that is what you
203
+ * actually need to know.
176
204
  * Absent on older graphs — callers fall back to `isScannableSourcePath` on
177
205
  * the target path. Asset edges only require their source node to exist
178
206
  * during incremental validation, and are excluded from in-degree ranking /
@@ -1,3 +1,4 @@
1
+ import { type ScopedModelOverrideKey } from '../models/model-override-state.js';
1
2
  /**
2
3
  * Issue #1896 (sub-issue 3): shared model-fallback dispatch helper.
3
4
  *
@@ -10,14 +11,7 @@
10
11
  * All those stages dispatch via `client.session.prompt({ body: { agent, model }})`,
11
12
  * which accepts a per-call `model: {providerID, modelID}` override. This helper
12
13
  * wraps such a dispatch with (a) bounded, per-model transient retry and (b)
13
- * model-fallback advance — kept INDEPENDENT per AGENTS.md invariant #9. The
14
- * fallback index is owned LOCALLY here: every stage dispatches into an ephemeral
15
- * child session, so the only reachable `session.model_fallback_index` belongs to
16
- * the parent orchestrator (a different agent) and must not be reused.
17
- *
18
- * The helper does NOT import `src/agents/index.ts` (avoids a heavy import cycle);
19
- * the caller injects a `resolveFallback(index)` closure that wraps
20
- * `resolveFallbackModel(baseRole, index, getSwarmAgents(swarmId))`.
14
+ * model-fallback advance — kept INDEPENDENT per AGENTS.md invariant #9.
21
15
  */
22
16
  /** Per-call model override shape accepted by `client.session.prompt` body. */
23
17
  export interface ModelOverride {
@@ -41,19 +35,29 @@ export interface ModelFallbackResult<T> {
41
35
  }
42
36
  export interface DispatchWithModelFallbackOptions<T> {
43
37
  /** Dispatch using `model` (undefined = the agent's registered/primary model). */
44
- dispatch: (model: ModelOverride | undefined) => Promise<T>;
38
+ dispatch: (model: ModelOverride | undefined, context: {
39
+ attemptNumber: number;
40
+ fallbackIndex: number;
41
+ modelString?: string;
42
+ remainingMs?: number;
43
+ generation?: number;
44
+ }) => Promise<T>;
45
45
  /**
46
46
  * Resolve the 1-based fallback model as a `provider/model` string, or null
47
47
  * when the fallback chain is exhausted. Typically wraps
48
48
  * `resolveFallbackModel(baseRole, index, getSwarmAgents(swarmId))`.
49
49
  */
50
- resolveFallback: (fallbackIndex: number) => string | null;
50
+ resolveFallback?: (fallbackIndex: number) => string | null;
51
51
  /** Classify a dispatch error: 'transient' → retry/failover; 'permanent' → throw immediately. */
52
52
  classify: (error: unknown) => 'transient' | 'permanent';
53
53
  /** Bounded transient retries on the SAME model before advancing (invariant #9 — independent of fallback). Default 1. */
54
54
  maxTransientRetriesPerModel?: number;
55
55
  /** Backoff before a same-model retry (NOT before a fallback advance). Default 2**(n-1)*1000 ms. */
56
56
  backoffMs?: (retryAttempt: number) => number;
57
+ /** Absolute wall-clock deadline in Unix ms shared across dispatch, retry, and backoff. */
58
+ deadlineAtMs?: number;
59
+ /** Hard cap across all attempts, independent of retry/fallback structure. */
60
+ maxAttempts?: number;
57
61
  /** Notified when advancing to a fallback model (for advisory/telemetry). */
58
62
  onFallback?: (info: {
59
63
  toModel: string;
@@ -61,7 +65,24 @@ export interface DispatchWithModelFallbackOptions<T> {
61
65
  }) => void;
62
66
  /** DI for tests (avoid real waits). */
63
67
  sleep?: (ms: number) => Promise<void>;
68
+ /** Clock injection for deadline tests. */
69
+ now?: () => number;
70
+ /**
71
+ * Optional scoped override contract for direct role-bound dispatch paths.
72
+ * When supplied together with a primary model and fallback chain, model
73
+ * selection is keyed by session/invocation/swarm/role and reset on success.
74
+ */
75
+ scope?: ScopedModelOverrideKey;
76
+ primaryModel?: string;
77
+ fallbackModels?: Iterable<string | null | undefined>;
78
+ }
79
+ export declare class ModelDispatchTimeoutError extends Error {
80
+ constructor(message?: string);
64
81
  }
82
+ export declare const _internals: {
83
+ setTimeout: typeof setTimeout;
84
+ clearTimeout: typeof clearTimeout;
85
+ };
65
86
  /**
66
87
  * Try the primary model, then each configured fallback, retrying transient
67
88
  * failures a bounded number of times per model. A permanent failure throws
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * Timeout primitives used by the plugin init path.
3
3
  *
4
- * Deadline timers must call `unref()` and every Promise.race must clear its
5
- * timer in `finally`, so timeouts never pin or leak a process handle. Awaited
6
- * cooperative-yield timers are deliberately ref'ed: unref'ing the only handle
7
- * can strand their caller before the awaited promise resolves.
4
+ * Every Promise.race clears its timer in `finally`, so completed operations do
5
+ * not leak a process handle. A timer that is itself required to settle an
6
+ * awaited promise remains ref'ed: Bun can strand that caller when its only
7
+ * settlement handle is unref'ed.
8
8
  */
9
9
  /**
10
10
  * Race a promise against a timeout. The timer is cleared in `finally` so the
@@ -17,6 +17,20 @@
17
17
  * @param timeoutError Error thrown when the deadline elapses.
18
18
  */
19
19
  export declare function withTimeout<T>(promise: Promise<T>, ms: number, timeoutError: Error): Promise<T>;
20
+ /**
21
+ * Race a cancellable operation against a timeout while also supplying an
22
+ * `AbortSignal` that is tripped when the deadline elapses.
23
+ *
24
+ * This is the shared helper for cross-platform request/LLM timeouts: callers
25
+ * get a real abort signal for cooperative cancellation, but the outer race
26
+ * still returns if the callee ignores that signal.
27
+ */
28
+ export declare function withTimeoutSignal<T>(operation: (signal: AbortSignal) => Promise<T>, ms: number, timeoutError: Error): Promise<T>;
29
+ /** Dependency-injection seam for deterministic timer-cleanup tests. */
30
+ export declare const _internals: {
31
+ setTimeout: typeof setTimeout;
32
+ clearTimeout: typeof clearTimeout;
33
+ };
20
34
  /**
21
35
  * Yield to the macrotask queue. Works under both Node and Bun runtimes,
22
36
  * unlike `setImmediate` which is Node-only. The timer intentionally remains
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.146.5",
3
+ "version": "7.147.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",
@@ -1,64 +0,0 @@
1
- // @bun
2
- import {
3
- createCuratorLLMDelegate
4
- } from "./index-npw2xm46.js";
5
- import"./index-hcb25p12.js";
6
- import"./index-fjhc8mk2.js";
7
- import"./index-d3t7q4b8.js";
8
- import"./index-0pya01vw.js";
9
- import"./index-p3k155dv.js";
10
- import"./index-134d35c1.js";
11
- import"./index-abtrcs16.js";
12
- import"./index-y8552snf.js";
13
- import"./index-55g08cg2.js";
14
- import"./index-ktpj357z.js";
15
- import"./index-70ha9e09.js";
16
- import"./index-c8s9a3zh.js";
17
- import"./index-9ss2m4rs.js";
18
- import"./index-z9yhhk6q.js";
19
- import"./index-3p4wgm0d.js";
20
- import"./index-fymrwjak.js";
21
- import"./index-53asfj0j.js";
22
- import"./index-tp5ytzzg.js";
23
- import"./index-rtry5xyf.js";
24
- import"./index-zsrtt42s.js";
25
- import"./index-rpy0bent.js";
26
- import"./index-e1pxav9g.js";
27
- import"./index-vjkfhqef.js";
28
- import"./index-cpzra8my.js";
29
- import"./index-p4ar0k0n.js";
30
- import"./index-hn0hvgtt.js";
31
- import"./index-556ja8an.js";
32
- import"./index-7sy3aa9m.js";
33
- import"./index-wx8zdh4a.js";
34
- import"./index-3g0xk6tk.js";
35
- import"./index-85gkedsf.js";
36
- import"./index-zqmzn9hk.js";
37
- import"./index-cp8jp4cv.js";
38
- import"./index-cyxdm0v3.js";
39
- import"./index-gprxjmm7.js";
40
- import"./index-n832052r.js";
41
- import"./index-gqx0rq53.js";
42
- import"./index-rqgnad5w.js";
43
- import"./index-cpg98bh1.js";
44
- import"./index-9e6fdz2h.js";
45
- import"./index-4rhhvd1a.js";
46
- import"./index-w8pgjr75.js";
47
- import"./index-z6xqpmqg.js";
48
- import"./index-zj6t9zgx.js";
49
- import"./index-zjygnfay.js";
50
- import"./index-ae75rja9.js";
51
- import"./index-f75qjtn5.js";
52
- import"./index-8py21zn6.js";
53
- import"./index-bk5tah7q.js";
54
- import"./index-hw1yghpg.js";
55
- import"./index-6q35swn2.js";
56
- import"./index-q81s0m8k.js";
57
- import"./index-7g4c7s5r.js";
58
- import"./index-bpmtbmy9.js";
59
- import"./index-ed5ykebp.js";
60
- import"./index-zgwm4ryv.js";
61
- import"./index-a76rekgs.js";
62
- export {
63
- createCuratorLLMDelegate
64
- };
@@ -1,65 +0,0 @@
1
- // @bun
2
- import {
3
- handleGuardrailExplain
4
- } from "./index-52460nma.js";
5
- import"./index-npw2xm46.js";
6
- import"./index-hcb25p12.js";
7
- import"./index-fjhc8mk2.js";
8
- import"./index-d3t7q4b8.js";
9
- import"./index-0pya01vw.js";
10
- import"./index-p3k155dv.js";
11
- import"./index-134d35c1.js";
12
- import"./index-abtrcs16.js";
13
- import"./index-y8552snf.js";
14
- import"./index-55g08cg2.js";
15
- import"./index-ktpj357z.js";
16
- import"./index-70ha9e09.js";
17
- import"./index-c8s9a3zh.js";
18
- import"./index-9ss2m4rs.js";
19
- import"./index-z9yhhk6q.js";
20
- import"./index-3p4wgm0d.js";
21
- import"./index-fymrwjak.js";
22
- import"./index-53asfj0j.js";
23
- import"./index-tp5ytzzg.js";
24
- import"./index-rtry5xyf.js";
25
- import"./index-zsrtt42s.js";
26
- import"./index-rpy0bent.js";
27
- import"./index-e1pxav9g.js";
28
- import"./index-vjkfhqef.js";
29
- import"./index-cpzra8my.js";
30
- import"./index-p4ar0k0n.js";
31
- import"./index-hn0hvgtt.js";
32
- import"./index-556ja8an.js";
33
- import"./index-7sy3aa9m.js";
34
- import"./index-wx8zdh4a.js";
35
- import"./index-3g0xk6tk.js";
36
- import"./index-85gkedsf.js";
37
- import"./index-zqmzn9hk.js";
38
- import"./index-cp8jp4cv.js";
39
- import"./index-cyxdm0v3.js";
40
- import"./index-gprxjmm7.js";
41
- import"./index-n832052r.js";
42
- import"./index-gqx0rq53.js";
43
- import"./index-rqgnad5w.js";
44
- import"./index-cpg98bh1.js";
45
- import"./index-9e6fdz2h.js";
46
- import"./index-4rhhvd1a.js";
47
- import"./index-w8pgjr75.js";
48
- import"./index-z6xqpmqg.js";
49
- import"./index-zj6t9zgx.js";
50
- import"./index-zjygnfay.js";
51
- import"./index-ae75rja9.js";
52
- import"./index-f75qjtn5.js";
53
- import"./index-8py21zn6.js";
54
- import"./index-bk5tah7q.js";
55
- import"./index-hw1yghpg.js";
56
- import"./index-6q35swn2.js";
57
- import"./index-q81s0m8k.js";
58
- import"./index-7g4c7s5r.js";
59
- import"./index-bpmtbmy9.js";
60
- import"./index-ed5ykebp.js";
61
- import"./index-zgwm4ryv.js";
62
- import"./index-a76rekgs.js";
63
- export {
64
- handleGuardrailExplain
65
- };
@@ -1,24 +0,0 @@
1
- // @bun
2
- // src/utils/timeout.ts
3
- async function withTimeout(promise, ms, timeoutError) {
4
- let timer;
5
- const timeoutPromise = new Promise((_, reject) => {
6
- timer = setTimeout(() => reject(timeoutError), ms);
7
- if (typeof timer.unref === "function") {
8
- timer.unref();
9
- }
10
- });
11
- try {
12
- return await Promise.race([promise, timeoutPromise]);
13
- } finally {
14
- if (timer !== undefined)
15
- clearTimeout(timer);
16
- }
17
- }
18
- function yieldToEventLoop() {
19
- return new Promise((resolve) => {
20
- setTimeout(resolve, 0);
21
- });
22
- }
23
-
24
- export { withTimeout, yieldToEventLoop };