opencode-swarm 7.135.5 → 7.136.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.
- package/.opencode/skills/swarm-pr-review/SKILL.md +11 -0
- package/dist/background/candidate-contract.d.ts +13 -0
- package/dist/cli/{config-doctor-exj26ryt.js → config-doctor-6fphg5xm.js} +2 -2
- package/dist/cli/{curation-policy-mbv3b27c.js → curation-policy-m24jbyag.js} +2 -2
- package/dist/cli/{curator-llm-factory-4d5pzh47.js → curator-llm-factory-w5arq7tr.js} +12 -12
- package/dist/cli/{curator-7ycd6x29.js → curator-zrt5sqj2.js} +12 -12
- package/dist/cli/{guardrail-explain-2jrqv2zf.js → guardrail-explain-462jwhbh.js} +13 -13
- package/dist/cli/{guardrail-log-c843gxnm.js → guardrail-log-ax21jd9e.js} +3 -3
- package/dist/cli/{hive-promoter-epnj14q8.js → hive-promoter-2vacnbws.js} +12 -12
- package/dist/cli/{index-8et4bx6j.js → index-1sq47n6t.js} +3 -3
- package/dist/cli/{index-0csbx1wc.js → index-9gxp450h.js} +1 -1
- package/dist/cli/{index-t1gszcwg.js → index-dyy3hvk3.js} +2 -2
- package/dist/cli/{index-jnemjn16.js → index-f4cmtd89.js} +2 -2
- package/dist/cli/{index-qyn0b2jj.js → index-g7g4hqh3.js} +1 -1
- package/dist/cli/{index-db52969t.js → index-gf7hqbmz.js} +1 -1
- package/dist/cli/{index-ym516a9a.js → index-h3bweb88.js} +5 -5
- package/dist/cli/{index-hw6yt4rs.js → index-hzkvbycn.js} +4 -4
- package/dist/cli/{index-09w3ezq2.js → index-jwrydqjp.js} +1 -1
- package/dist/cli/{index-bx10dq60.js → index-kzc2ygea.js} +1 -1
- package/dist/cli/{index-kjg6vgqs.js → index-p1pqqwgp.js} +1 -1
- package/dist/cli/{index-9s5b8wrs.js → index-prnjt2jr.js} +61 -54
- package/dist/cli/{index-k8arazbb.js → index-r9v98d0y.js} +7 -2
- package/dist/cli/{index-kq9zb1cv.js → index-rhgctfn3.js} +14 -14
- package/dist/cli/{index-6yk6ezvj.js → index-tfa40hwb.js} +1 -1
- package/dist/cli/{index-gvfw2y6v.js → index-zkddc5ye.js} +2 -2
- package/dist/cli/index.js +12 -12
- package/dist/cli/{knowledge-escalator-3tjhpwjf.js → knowledge-escalator-1zt8qy1c.js} +3 -3
- package/dist/cli/{knowledge-events-0akk3p15.js → knowledge-events-ej3s9tsm.js} +1 -1
- package/dist/cli/{knowledge-store-7nvfh2n3.js → knowledge-store-ey4cbkp4.js} +1 -1
- package/dist/cli/{knowledge-validator-z618vhda.js → knowledge-validator-zwmq7s2c.js} +4 -4
- package/dist/cli/{scan-cursor-5zqr3afj.js → scan-cursor-809hf2n1.js} +2 -2
- package/dist/cli/{schema-n1cj94m0.js → schema-mhd7xqwr.js} +1 -1
- package/dist/cli/{skill-generator-560ksca8.js → skill-generator-yyc8zd9j.js} +5 -5
- package/dist/config/schema.d.ts +11 -1
- package/dist/hooks/repo-graph-builder.d.ts +17 -11
- package/dist/hooks/repo-graph-injection.d.ts +20 -9
- package/dist/hooks/semantic-diff-injection.d.ts +2 -2
- package/dist/index.js +141 -140
- package/dist/tools/repo-graph/builder.d.ts +55 -1
- package/dist/tools/repo-graph/cache.d.ts +12 -36
- package/dist/tools/repo-graph/freshness.d.ts +54 -0
- package/dist/tools/repo-graph/incremental.d.ts +17 -8
- package/dist/tools/repo-graph/query.d.ts +7 -1
- package/dist/tools/repo-graph/storage.d.ts +3 -1
- package/dist/tools/repo-graph/types.d.ts +31 -1
- package/dist/tools/repo-graph.d.ts +5 -3
- package/dist/tools/repo-map.d.ts +8 -0
- package/dist/utils/path-security.d.ts +22 -0
- package/package.json +1 -1
|
@@ -14,7 +14,7 @@ import { extractFileSymbols } from '../../lang/symbol-graph';
|
|
|
14
14
|
import { extractGoSymbols, extractPythonSymbols, extractRustSymbols, extractTSSymbols } from '../symbols';
|
|
15
15
|
import { extractFileOntology } from './ontology';
|
|
16
16
|
import { safeRealpathSync } from './safe-realpath';
|
|
17
|
-
import type { BuildWorkspaceGraphOptions, GraphEdge, GraphNode, RepoGraph, RepoGraphDiagnostics, SymbolEdge } from './types';
|
|
17
|
+
import type { BuildWorkspaceGraphOptions, GraphEdge, GraphExtractorInputWitness, GraphNode, RepoGraph, RepoGraphDiagnostics, SymbolEdge } from './types';
|
|
18
18
|
/**
|
|
19
19
|
* _internals DI seam for the walk clock and graph helpers.
|
|
20
20
|
* Defaults to the real implementations. Tests can override these to inject
|
|
@@ -52,6 +52,8 @@ export declare function isScannableSourcePath(p: string): boolean;
|
|
|
52
52
|
* queries.
|
|
53
53
|
*/
|
|
54
54
|
export declare function isAssetEdge(edge: GraphEdge): boolean;
|
|
55
|
+
/** Correctness witnesses are not display diagnostics and must cover the full walk. */
|
|
56
|
+
export declare const MAX_EXTRACTOR_INPUT_WITNESSES = 100256;
|
|
55
57
|
/**
|
|
56
58
|
* Add or update a node in the graph.
|
|
57
59
|
* @param graph - The graph to modify
|
|
@@ -144,6 +146,56 @@ declare function parseFileImports(rawContent: string, sourceFile?: string, works
|
|
|
144
146
|
* @returns the *exported* names (binding.imported) judged to be used.
|
|
145
147
|
*/
|
|
146
148
|
declare function computeUsedSymbols(strippedContent: string, bindings: readonly ImportBinding[]): string[];
|
|
149
|
+
/**
|
|
150
|
+
* Return whether a path is a graph-wide extractor input. Changes to these
|
|
151
|
+
* manifests can alter package-boundary ontology for many nodes, so consumers
|
|
152
|
+
* must rebuild rather than treating them as an ordinary one-file refresh.
|
|
153
|
+
*/
|
|
154
|
+
export declare function isGraphWideInputPath(filePath: string): boolean;
|
|
155
|
+
/**
|
|
156
|
+
* Async, chunked, cycle-safe equivalent of `findSourceFiles`.
|
|
157
|
+
*
|
|
158
|
+
* Yields to the event loop every `ASYNC_WALK_YIELD_INTERVAL` entries so the
|
|
159
|
+
* Node/Bun macrotask queue continues to drain while the walk runs. This is
|
|
160
|
+
* the variant called from the plugin init path; the sync variant remains
|
|
161
|
+
* available for non-init callers (tools, tests) for compatibility.
|
|
162
|
+
*/
|
|
163
|
+
export interface RepoGraphInputMetadata {
|
|
164
|
+
absolutePath: string;
|
|
165
|
+
kind: 'source' | 'manifest';
|
|
166
|
+
sizeBytes: number;
|
|
167
|
+
mtimeMs: number;
|
|
168
|
+
}
|
|
169
|
+
export interface RepoGraphInputWalkResult {
|
|
170
|
+
sourceFiles: string[];
|
|
171
|
+
manifestFiles: string[];
|
|
172
|
+
metadata: RepoGraphInputMetadata[];
|
|
173
|
+
manifestDirs: Set<string>;
|
|
174
|
+
truncated: boolean;
|
|
175
|
+
truncationReason?: 'budget' | 'cap';
|
|
176
|
+
incomplete: boolean;
|
|
177
|
+
unreadableDirectories: string[];
|
|
178
|
+
unreadableFiles: string[];
|
|
179
|
+
probedFiles: number;
|
|
180
|
+
elapsedMs: number;
|
|
181
|
+
}
|
|
182
|
+
export interface RepoGraphInputWalkOptions {
|
|
183
|
+
walkBudgetMs?: number;
|
|
184
|
+
maxFiles?: number;
|
|
185
|
+
followSymlinks?: boolean;
|
|
186
|
+
excludeDirs?: readonly string[];
|
|
187
|
+
/** Capture size/mtime for every source and manifest during this same walk. */
|
|
188
|
+
captureMetadata?: boolean;
|
|
189
|
+
/** Capture only graph-wide manifest metadata (used by the graph builder). */
|
|
190
|
+
captureManifestMetadata?: boolean;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Enumerate every input used by repository-graph extraction with the same
|
|
194
|
+
* bounded, deterministic, cycle-safe traversal as the async graph builder.
|
|
195
|
+
* Directory and metadata I/O failures are surfaced through `incomplete` so a
|
|
196
|
+
* caller can refuse removals/certification instead of guessing.
|
|
197
|
+
*/
|
|
198
|
+
export declare function walkRepoGraphInputs(dir: string, options?: RepoGraphInputWalkOptions): Promise<RepoGraphInputWalkResult>;
|
|
147
199
|
/**
|
|
148
200
|
* Result of scanning a single file for graph updates.
|
|
149
201
|
*/
|
|
@@ -164,6 +216,8 @@ export interface AsyncScanResult {
|
|
|
164
216
|
symbolEdges: SymbolEdge[];
|
|
165
217
|
/** Optional file-level diagnostics collected during async scanning. */
|
|
166
218
|
diagnostics?: RepoGraphDiagnostics;
|
|
219
|
+
/** Build-time witness for a deterministic non-node skip. */
|
|
220
|
+
inputWitness?: GraphExtractorInputWitness;
|
|
167
221
|
}
|
|
168
222
|
/**
|
|
169
223
|
* Scan a single file and extract its graph node and edges.
|
|
@@ -1,48 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Bounded in-memory cache for loaded repo graphs.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* used by the optimistic concurrency check in incremental.ts
|
|
9
|
-
*
|
|
10
|
-
* All public functions normalize the workspace path before use so callers
|
|
11
|
-
* are not required to pre-normalize.
|
|
4
|
+
* Graph, dirty, and mtime state intentionally share one entry so eviction can
|
|
5
|
+
* never leave one piece of workspace state behind. Entries are keyed by an
|
|
6
|
+
* absolute normalized workspace path and maintained as a true LRU: every read
|
|
7
|
+
* moves the entry to the newest position and insertion evicts the oldest.
|
|
12
8
|
*/
|
|
13
9
|
import type { RepoGraph } from './types';
|
|
14
|
-
/**
|
|
15
|
-
* Get the cached graph for a workspace.
|
|
16
|
-
* @param workspace - The workspace directory (absolute or relative path)
|
|
17
|
-
* @returns The cached graph or undefined if not cached
|
|
18
|
-
*/
|
|
10
|
+
/** Return the cached graph for a workspace, if present. */
|
|
19
11
|
export declare function getCachedGraph(workspace: string): RepoGraph | undefined;
|
|
20
12
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* @param graph - The graph to cache
|
|
24
|
-
* @param mtime - Optional file mtime to track for cache invalidation
|
|
13
|
+
* Cache a graph and mark it clean. Omitting mtime clears any previous mtime so
|
|
14
|
+
* an old optimistic-concurrency witness cannot survive a new graph value.
|
|
25
15
|
*/
|
|
26
16
|
export declare function setCachedGraph(workspace: string, graph: RepoGraph, mtime?: number): void;
|
|
27
|
-
/**
|
|
28
|
-
* Mark a workspace's cache as dirty (modified since last save).
|
|
29
|
-
* @param workspace - The workspace directory (absolute or relative path)
|
|
30
|
-
*/
|
|
17
|
+
/** Mark a workspace's cached state dirty, preserving its graph and mtime. */
|
|
31
18
|
export declare function markDirty(workspace: string): void;
|
|
32
|
-
/**
|
|
33
|
-
* Check if a workspace's cache is dirty.
|
|
34
|
-
* @param workspace - The workspace directory (absolute or relative path)
|
|
35
|
-
* @returns True if the cache has been modified since last save
|
|
36
|
-
*/
|
|
19
|
+
/** Return whether the workspace's cached state is dirty. */
|
|
37
20
|
export declare function isDirty(workspace: string): boolean;
|
|
38
|
-
/**
|
|
39
|
-
* Clear the cache for a workspace.
|
|
40
|
-
* @param workspace - The workspace directory (absolute or relative path)
|
|
41
|
-
*/
|
|
21
|
+
/** Remove all cached state for one workspace. */
|
|
42
22
|
export declare function clearCache(workspace: string): void;
|
|
43
|
-
/**
|
|
44
|
-
* Get the cached file mtime for a workspace (used for optimistic concurrency).
|
|
45
|
-
* @param workspace - The workspace directory (absolute or relative path)
|
|
46
|
-
* @returns The cached mtime in milliseconds, or undefined if not cached
|
|
47
|
-
*/
|
|
23
|
+
/** Return the graph-file mtime captured with the cached graph, if present. */
|
|
48
24
|
export declare function getCachedMtime(workspace: string): number | undefined;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounded content-freshness certification for repository graphs.
|
|
3
|
+
*
|
|
4
|
+
* A probe is one bounded readdir+stat directory walk, not a stat pass over
|
|
5
|
+
* already-known graph nodes. It reads no source contents and performs no
|
|
6
|
+
* parsing, so it is much cheaper than graph construction while still finding
|
|
7
|
+
* additions and removals. The sidecar deliberately fingerprints metadata
|
|
8
|
+
* (byte size + numeric mtime), not file bytes, so a tool that preserves both
|
|
9
|
+
* values can evade detection. Results may also be cached for up to 30 seconds.
|
|
10
|
+
* Callers must therefore treat `inconclusive` as unknown and may mutate/delete
|
|
11
|
+
* only after a complete `drifted` probe.
|
|
12
|
+
*/
|
|
13
|
+
import * as fsPromises from 'node:fs/promises';
|
|
14
|
+
import { bunWrite } from '../../utils/bun-compat';
|
|
15
|
+
import { walkRepoGraphInputs } from './builder';
|
|
16
|
+
import type { FreshnessProbeState, RepoGraph } from './types';
|
|
17
|
+
export declare const REPO_GRAPH_FINGERPRINT_FILENAME = "repo-graph.fingerprint.json";
|
|
18
|
+
export declare const FINGERPRINT_SCHEMA_VERSION = 1;
|
|
19
|
+
export declare const EXTRACTOR_STAMP: string;
|
|
20
|
+
export interface FreshnessOptions {
|
|
21
|
+
walkBudgetMs?: number;
|
|
22
|
+
maxFiles?: number;
|
|
23
|
+
followSymlinks?: boolean;
|
|
24
|
+
excludeDirs?: readonly string[];
|
|
25
|
+
}
|
|
26
|
+
export interface FreshnessProbe {
|
|
27
|
+
state: FreshnessProbeState;
|
|
28
|
+
/** Absolute paths positively observed as new or metadata-changed. */
|
|
29
|
+
changed: string[];
|
|
30
|
+
/** Absolute paths absent from a complete walk. Empty when inconclusive. */
|
|
31
|
+
removed: string[];
|
|
32
|
+
truncated: boolean;
|
|
33
|
+
probedFiles: number;
|
|
34
|
+
elapsedMs: number;
|
|
35
|
+
}
|
|
36
|
+
export declare const _internals: {
|
|
37
|
+
now: () => number;
|
|
38
|
+
walkRepoGraphInputs: typeof walkRepoGraphInputs;
|
|
39
|
+
open: typeof fsPromises.open;
|
|
40
|
+
bunWrite: typeof bunWrite;
|
|
41
|
+
fsRename: typeof fsPromises.rename;
|
|
42
|
+
fsUnlink: typeof fsPromises.unlink;
|
|
43
|
+
retryDelayMs: number;
|
|
44
|
+
};
|
|
45
|
+
/** Invalidate one project's probe cache, or every entry when root is omitted. */
|
|
46
|
+
export declare function invalidateFreshnessCache(root?: string): void;
|
|
47
|
+
/** Probe workspace metadata using a bounded per-directory 16-entry LRU cache. */
|
|
48
|
+
export declare function probeFreshness(root: string, options?: FreshnessOptions): Promise<FreshnessProbe>;
|
|
49
|
+
/**
|
|
50
|
+
* Atomically persist a sidecar only when a complete walk certifies that the
|
|
51
|
+
* graph and every intentional stable skip match current metadata. Never
|
|
52
|
+
* throws; `false` means the graph remains deliberately uncertified.
|
|
53
|
+
*/
|
|
54
|
+
export declare function writeFingerprint(root: string, graph: RepoGraph, options?: FreshnessOptions): Promise<boolean>;
|
|
@@ -15,16 +15,27 @@
|
|
|
15
15
|
* rebuild on every incremental update.
|
|
16
16
|
*/
|
|
17
17
|
import { type Stats } from 'node:fs';
|
|
18
|
+
import { buildWorkspaceGraphAsync, scanFileAsync } from './builder';
|
|
19
|
+
import { writeFingerprint } from './freshness';
|
|
20
|
+
import { saveGraph } from './storage';
|
|
21
|
+
import type { BuildWorkspaceGraphOptions, RepoGraph } from './types';
|
|
22
|
+
/** Public options shared by hook, read-repair, and direct callers. */
|
|
23
|
+
export interface IncrementalUpdateOptions {
|
|
24
|
+
forceRebuild?: boolean;
|
|
25
|
+
/** Bounds and exclusions used by both direct and fallback full builds. */
|
|
26
|
+
buildOptions?: BuildWorkspaceGraphOptions;
|
|
27
|
+
}
|
|
18
28
|
/**
|
|
19
|
-
* DI seam for
|
|
20
|
-
*
|
|
21
|
-
* re-check, exercising the reload-and-replay branch without races. Defaults to
|
|
22
|
-
* the real `fsPromises.stat`. Restore in afterEach.
|
|
29
|
+
* DI seam for concurrency, scan-failure, and paired-persistence tests. Tests
|
|
30
|
+
* must restore every replaced entry in afterEach.
|
|
23
31
|
*/
|
|
24
32
|
export declare const _internals: {
|
|
25
33
|
stat: (path: string) => Promise<Stats>;
|
|
34
|
+
scanFileAsync: typeof scanFileAsync;
|
|
35
|
+
buildWorkspaceGraphAsync: typeof buildWorkspaceGraphAsync;
|
|
36
|
+
saveGraph: typeof saveGraph;
|
|
37
|
+
writeFingerprint: typeof writeFingerprint;
|
|
26
38
|
};
|
|
27
|
-
import type { RepoGraph } from './types';
|
|
28
39
|
/**
|
|
29
40
|
* Incrementally update the graph for a set of changed files.
|
|
30
41
|
* Re-scans only the specified files, updates their nodes and edges,
|
|
@@ -36,6 +47,4 @@ import type { RepoGraph } from './types';
|
|
|
36
47
|
* @param options.forceRebuild - Force a full rebuild instead of incremental
|
|
37
48
|
* @returns Updated RepoGraph
|
|
38
49
|
*/
|
|
39
|
-
export declare function updateGraphForFiles(workspaceRoot: string, filePaths: string[], options?:
|
|
40
|
-
forceRebuild?: boolean;
|
|
41
|
-
}): Promise<RepoGraph>;
|
|
50
|
+
export declare function updateGraphForFiles(workspaceRoot: string, filePaths: string[], options?: IncrementalUpdateOptions): Promise<RepoGraph>;
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
+
import type { FreshnessProbe } from './freshness';
|
|
1
2
|
import type { BlastRadiusResult, CallerReference, ContextPackResult, DeadExportsResult, FileOntology, FileReference, GraphHealthResult, GraphNode, LocalizationBlock, PackageBoundarySummary, RepoGraph, SymbolReference } from './types';
|
|
2
3
|
export declare function getGraphNode(graph: RepoGraph, input: string): GraphNode | undefined;
|
|
3
4
|
export declare function resetQueryCache(): void;
|
|
5
|
+
/**
|
|
6
|
+
* @deprecated Graph age is not a content-freshness signal. Internal consumers
|
|
7
|
+
* use {@link probeFreshness}; this compatibility helper intentionally retains
|
|
8
|
+
* its historical five-minute TTL semantics for external callers.
|
|
9
|
+
*/
|
|
4
10
|
export declare function isGraphFresh(graph: RepoGraph | null, maxAgeMs?: number): boolean;
|
|
5
|
-
export declare function getGraphHealth(graph: RepoGraph | null, workspaceRoot?: string): GraphHealthResult;
|
|
11
|
+
export declare function getGraphHealth(graph: RepoGraph | null, workspaceRoot?: string, probe?: FreshnessProbe): GraphHealthResult;
|
|
6
12
|
export declare function getImporters(graph: RepoGraph, filePath: string): FileReference[];
|
|
7
13
|
export declare function getDependencies(graph: RepoGraph, filePath: string): FileReference[];
|
|
8
14
|
export declare function getSymbolConsumers(graph: RepoGraph, filePath: string, symbolName: string): SymbolReference[];
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* cache. Symlink resolution guards against workspace-escape attacks.
|
|
7
7
|
*/
|
|
8
8
|
import * as fsPromises from 'node:fs/promises';
|
|
9
|
+
import { type FreshnessOptions, writeFingerprint } from './freshness';
|
|
9
10
|
import { safeRealpathSync } from './safe-realpath';
|
|
10
11
|
import type { RepoGraph } from './types';
|
|
11
12
|
/**
|
|
@@ -20,6 +21,7 @@ export declare const _internals: {
|
|
|
20
21
|
safeRealpathSync: typeof safeRealpathSync;
|
|
21
22
|
fsRename: typeof fsPromises.rename;
|
|
22
23
|
retryDelayMs: number;
|
|
24
|
+
writeFingerprint: typeof writeFingerprint;
|
|
23
25
|
};
|
|
24
26
|
/**
|
|
25
27
|
* Get the validated path for the repo-graph.json file.
|
|
@@ -75,4 +77,4 @@ export declare function loadOrCreateGraph(workspace: string): Promise<RepoGraph>
|
|
|
75
77
|
* @throws Error if workspace is dirty but cache is missing (inconsistent state)
|
|
76
78
|
* @throws Error if save fails
|
|
77
79
|
*/
|
|
78
|
-
export declare function saveIfDirty(workspace: string): Promise<void>;
|
|
80
|
+
export declare function saveIfDirty(workspace: string, freshnessOptions?: FreshnessOptions): Promise<void>;
|
|
@@ -35,8 +35,14 @@ export declare const REPO_GRAPH_FILENAME = "repo-graph.json";
|
|
|
35
35
|
* Diagnostics are additive and optional on all schema versions. Old graphs
|
|
36
36
|
* without diagnostics remain readable; graph-health queries surface empty
|
|
37
37
|
* diagnostics with an explicit rebuild note.
|
|
38
|
+
*
|
|
39
|
+
* 1.4.0 adds optional numeric `sizeBytes` and `mtimeMs` witnesses to each
|
|
40
|
+
* node. Builders capture them from the same stat used immediately before the
|
|
41
|
+
* source read. The content-freshness sidecar requires both witnesses before
|
|
42
|
+
* it will certify a graph; older graphs remain readable but are intentionally
|
|
43
|
+
* treated as needing a rebuild before certification.
|
|
38
44
|
*/
|
|
39
|
-
export declare const GRAPH_SCHEMA_VERSION = "1.
|
|
45
|
+
export declare const GRAPH_SCHEMA_VERSION = "1.4.0";
|
|
40
46
|
/**
|
|
41
47
|
* Compare dotted numeric version strings (e.g. '1.1.0' >= '1.1.0').
|
|
42
48
|
* Missing/non-numeric segments are treated as 0. Returns true when `version`
|
|
@@ -132,6 +138,10 @@ export interface GraphNode {
|
|
|
132
138
|
language: string;
|
|
133
139
|
/** Last modified timestamp */
|
|
134
140
|
mtime: string;
|
|
141
|
+
/** Exact byte size captured by the stat that preceded the source read. */
|
|
142
|
+
sizeBytes?: number;
|
|
143
|
+
/** Numeric mtime captured with `sizeBytes`; avoids ISO precision loss. */
|
|
144
|
+
mtimeMs?: number;
|
|
135
145
|
/** Optional code ontology facts for agent context/preflight packets */
|
|
136
146
|
ontology?: FileOntology;
|
|
137
147
|
}
|
|
@@ -280,6 +290,14 @@ export interface GraphUnresolvedImport {
|
|
|
280
290
|
file: string;
|
|
281
291
|
specifier: string;
|
|
282
292
|
}
|
|
293
|
+
/** Build-time metadata witness for a non-node extractor input. */
|
|
294
|
+
export interface GraphExtractorInputWitness {
|
|
295
|
+
/** Normalized workspace-relative path. */
|
|
296
|
+
file: string;
|
|
297
|
+
kind: 'manifest' | 'stable-skip';
|
|
298
|
+
sizeBytes: number;
|
|
299
|
+
mtimeMs: number;
|
|
300
|
+
}
|
|
283
301
|
export interface RepoGraphDiagnostics {
|
|
284
302
|
extractionFailures?: GraphExtractionFailure[];
|
|
285
303
|
unresolvedImports?: GraphUnresolvedImport[];
|
|
@@ -287,6 +305,14 @@ export interface RepoGraphDiagnostics {
|
|
|
287
305
|
unsupportedFiles?: string[];
|
|
288
306
|
binaryFiles?: string[];
|
|
289
307
|
unreadableFiles?: string[];
|
|
308
|
+
/** Source files intentionally skipped because their extracted node failed validation. */
|
|
309
|
+
validationSkippedFiles?: string[];
|
|
310
|
+
/**
|
|
311
|
+
* Build-time witnesses for manifests and deterministic non-node skips.
|
|
312
|
+
* Persistence compares them against its live walk so an edit between graph
|
|
313
|
+
* extraction and sidecar persistence cannot be blessed as clean.
|
|
314
|
+
*/
|
|
315
|
+
extractorInputWitnesses?: GraphExtractorInputWitness[];
|
|
290
316
|
lowConfidenceEdgeCount?: number;
|
|
291
317
|
/**
|
|
292
318
|
* True when the last workspace walk was truncated by the file cap or wall-
|
|
@@ -306,6 +332,7 @@ export interface RepoGraphDiagnostics {
|
|
|
306
332
|
export interface GraphHealthResult {
|
|
307
333
|
schemaVersion: string | null;
|
|
308
334
|
fresh: boolean;
|
|
335
|
+
probeState: FreshnessProbeState;
|
|
309
336
|
staleFiles: string[];
|
|
310
337
|
extractionFailures: GraphExtractionFailure[];
|
|
311
338
|
unresolvedImports: GraphUnresolvedImport[];
|
|
@@ -313,12 +340,15 @@ export interface GraphHealthResult {
|
|
|
313
340
|
unsupportedFiles: string[];
|
|
314
341
|
binaryFiles: string[];
|
|
315
342
|
unreadableFiles: string[];
|
|
343
|
+
validationSkippedFiles: string[];
|
|
316
344
|
lowConfidenceEdgeCount: number;
|
|
317
345
|
walkTruncated: boolean;
|
|
318
346
|
walkTruncationReason: 'budget' | 'cap' | null;
|
|
319
347
|
incrementalFallbacks: number;
|
|
320
348
|
notes: string[];
|
|
321
349
|
}
|
|
350
|
+
/** Authoritative states returned by the bounded repository freshness probe. */
|
|
351
|
+
export type FreshnessProbeState = 'clean' | 'drifted' | 'no-fingerprint' | 'inconclusive';
|
|
322
352
|
export interface BlastRadiusResult {
|
|
323
353
|
target: string[];
|
|
324
354
|
directDependents: string[];
|
|
@@ -14,15 +14,17 @@
|
|
|
14
14
|
*
|
|
15
15
|
* All existing imports of this module continue to work unchanged.
|
|
16
16
|
*/
|
|
17
|
-
export type { ScanResult } from './repo-graph/builder';
|
|
18
|
-
export { addEdge, buildWorkspaceGraph, buildWorkspaceGraphAsync, isScannableSourcePath, resolveModuleSpecifier, upsertNode, } from './repo-graph/builder';
|
|
17
|
+
export type { RepoGraphInputMetadata, RepoGraphInputWalkOptions, RepoGraphInputWalkResult, ScanResult, } from './repo-graph/builder';
|
|
18
|
+
export { addEdge, buildWorkspaceGraph, buildWorkspaceGraphAsync, isGraphWideInputPath, isScannableSourcePath, resolveModuleSpecifier, upsertNode, walkRepoGraphInputs, } from './repo-graph/builder';
|
|
19
19
|
export { clearCache, getCachedGraph, getCachedMtime, isDirty, markDirty, setCachedGraph, } from './repo-graph/cache';
|
|
20
|
+
export type { FreshnessOptions, FreshnessProbe, } from './repo-graph/freshness';
|
|
21
|
+
export { EXTRACTOR_STAMP, FINGERPRINT_SCHEMA_VERSION, invalidateFreshnessCache, probeFreshness, REPO_GRAPH_FINGERPRINT_FILENAME, writeFingerprint, } from './repo-graph/freshness';
|
|
20
22
|
export { updateGraphForFiles } from './repo-graph/incremental';
|
|
21
23
|
export type { ExtractFileOntologyInput } from './repo-graph/ontology';
|
|
22
24
|
export { extractFileOntology } from './repo-graph/ontology';
|
|
23
25
|
export type { DeadExportsOptions } from './repo-graph/query';
|
|
24
26
|
export { buildOntologyPreflightPacket, getBlastRadius, getCallers, getContextPack, getDeadExports, getDependencies, getFileOntology, getGraphHealth, getGraphNode, getImporters, getKeyFiles, getLocalizationContext, getPackageBoundaries, getSymbolConsumers, isGraphFresh, resetQueryCache, } from './repo-graph/query';
|
|
25
27
|
export { getGraphPath, loadGraph, loadGraphSync, loadOrCreateGraph, saveGraph, saveIfDirty, } from './repo-graph/storage';
|
|
26
|
-
export type { BlastRadiusResult, BuildWorkspaceGraphOptions, CallerReference, ContextPackResult, ContextPackSpan, ConventionFact, DataOperationFact, DeadExportCandidate, DeadExportsResult, FileOntology, FileReference, FileRole, GraphEdge, GraphExtractionFailure, GraphHealthResult, GraphNode, GraphUnresolvedImport, LocalizationBlock, OntologyFinding, PackageBoundarySummary, RepoGraph, RepoGraphDiagnostics, RouteFact, RouteMethod, SecurityFact, SymbolEdge, SymbolReference, } from './repo-graph/types';
|
|
28
|
+
export type { BlastRadiusResult, BuildWorkspaceGraphOptions, CallerReference, ContextPackResult, ContextPackSpan, ConventionFact, DataOperationFact, DeadExportCandidate, DeadExportsResult, FileOntology, FileReference, FileRole, FreshnessProbeState, GraphEdge, GraphExtractionFailure, GraphExtractorInputWitness, GraphHealthResult, GraphNode, GraphUnresolvedImport, LocalizationBlock, OntologyFinding, PackageBoundarySummary, RepoGraph, RepoGraphDiagnostics, RouteFact, RouteMethod, SecurityFact, SymbolEdge, SymbolReference, } from './repo-graph/types';
|
|
27
29
|
export { createEmptyGraph, GRAPH_SCHEMA_VERSION, isSchemaVersionAtLeast, normalizeGraphPath, REPO_GRAPH_FILENAME, updateGraphMetadata, } from './repo-graph/types';
|
|
28
30
|
export { validateGraphEdge, validateGraphNode, validateWorkspace, } from './repo-graph/validation';
|
package/dist/tools/repo-map.d.ts
CHANGED
|
@@ -1,2 +1,10 @@
|
|
|
1
|
+
import { loadPluginConfigWithMeta } from '../config/loader';
|
|
1
2
|
import { createSwarmTool } from './create-tool';
|
|
3
|
+
import { probeFreshness, updateGraphForFiles, writeFingerprint } from './repo-graph';
|
|
4
|
+
export declare const _internals: {
|
|
5
|
+
loadPluginConfigWithMeta: typeof loadPluginConfigWithMeta;
|
|
6
|
+
probeFreshness: typeof probeFreshness;
|
|
7
|
+
updateGraphForFiles: typeof updateGraphForFiles;
|
|
8
|
+
writeFingerprint: typeof writeFingerprint;
|
|
9
|
+
};
|
|
2
10
|
export declare const repo_map: ReturnType<typeof createSwarmTool>;
|
|
@@ -43,6 +43,28 @@ export declare function validateDirectory(directory: string): void;
|
|
|
43
43
|
* both fallback branches keeps the comparison basis consistent whether
|
|
44
44
|
* realpathSync succeeds or not, independent of incidental filesystem state.
|
|
45
45
|
*
|
|
46
|
+
* Not-yet-existing targets (e.g. a file about to be created by an atomic
|
|
47
|
+
* write) are handled the same way: realpathSync on the full target throws
|
|
48
|
+
* ENOENT, so resolution falls back to `resolveNearestExistingCanonical`,
|
|
49
|
+
* which walks up to the nearest existing ancestor, resolves symlinks on
|
|
50
|
+
* that ancestor (and everything above it), and rejoins the not-yet-existing
|
|
51
|
+
* tail. Without this, a target under a workspace root that itself sits
|
|
52
|
+
* behind a symlink (e.g. macOS `/tmp` and `/var`, which are symlinks to
|
|
53
|
+
* `/private/tmp` and `/private/var`) would resolve to its unresolved literal
|
|
54
|
+
* path while the (already-existing) root resolves to its `/private/...`
|
|
55
|
+
* form, producing a spurious boundary-escape error even though the target
|
|
56
|
+
* is genuinely inside the root. See issue #1986.
|
|
57
|
+
*
|
|
58
|
+
* This also TIGHTENS containment versus the pre-#1986-fix behavior in one
|
|
59
|
+
* case: if `.swarm/` or any other ancestor between the target and the
|
|
60
|
+
* workspace root is itself a symlink/junction pointing outside the
|
|
61
|
+
* workspace, the old fallback (unresolved `path.resolve`) could let a
|
|
62
|
+
* not-yet-existing target through on its first write; the ancestor walk now
|
|
63
|
+
* resolves that symlinked ancestor and correctly throws. If a deployment
|
|
64
|
+
* relies on a symlinked `.swarm/` (or similar) pointing outside the
|
|
65
|
+
* workspace root, that setup will now be rejected — this is the intended,
|
|
66
|
+
* correct behavior, not a regression.
|
|
67
|
+
*
|
|
46
68
|
* @param targetPath - The path to validate (absolute)
|
|
47
69
|
* @param rootPath - The root directory boundary (absolute)
|
|
48
70
|
* @throws Error if the resolved target escapes the root boundary
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.136.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",
|