opencode-swarm 7.4.2 → 7.5.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.
- package/dist/cli/index.js +1 -1
- package/dist/index.js +909 -842
- package/dist/state.d.ts +2 -1
- package/dist/tools/repo-graph/builder.d.ts +92 -0
- package/dist/tools/repo-graph/cache.d.ts +48 -0
- package/dist/tools/repo-graph/incremental.d.ts +24 -0
- package/dist/tools/repo-graph/storage.d.ts +56 -0
- package/dist/tools/repo-graph/types.d.ts +87 -0
- package/dist/tools/repo-graph/validation.d.ts +27 -0
- package/dist/tools/repo-graph.d.ts +23 -239
- package/package.json +1 -1
package/dist/state.d.ts
CHANGED
|
@@ -470,7 +470,8 @@ export declare function _resetCouncilDisagreementWarnings(): void;
|
|
|
470
470
|
*/
|
|
471
471
|
/**
|
|
472
472
|
* Reads plan.json + evidence/*.json from the project directory and populates the
|
|
473
|
-
* module-level _rehydrationCache. Called
|
|
473
|
+
* module-level _rehydrationCache. Called at plugin init by loadSnapshot() and
|
|
474
|
+
* refreshed after compaction by the compaction hook (src/hooks/compaction-customizer.ts).
|
|
474
475
|
* Non-fatal: missing/malformed files leave an empty cache.
|
|
475
476
|
*/
|
|
476
477
|
export declare function buildRehydrationCache(directory: string): Promise<void>;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace scanning and graph construction.
|
|
3
|
+
*
|
|
4
|
+
* Provides both synchronous (buildWorkspaceGraph) and async
|
|
5
|
+
* (buildWorkspaceGraphAsync) builders that walk the file tree, extract
|
|
6
|
+
* symbols, and produce a complete RepoGraph. The async variant yields
|
|
7
|
+
* to the event loop between batches so the plugin host can continue
|
|
8
|
+
* processing while a large workspace is scanned.
|
|
9
|
+
*
|
|
10
|
+
* Also exports upsertNode, addEdge, and resolveModuleSpecifier which are
|
|
11
|
+
* used by both the builder and the incremental updater.
|
|
12
|
+
*/
|
|
13
|
+
import type { BuildWorkspaceGraphOptions, GraphEdge, GraphNode, RepoGraph } from './types';
|
|
14
|
+
/**
|
|
15
|
+
* Add or update a node in the graph.
|
|
16
|
+
* @param graph - The graph to modify
|
|
17
|
+
* @param node - The node to add/update
|
|
18
|
+
*/
|
|
19
|
+
export declare function upsertNode(graph: RepoGraph, node: GraphNode): void;
|
|
20
|
+
/**
|
|
21
|
+
* Add an edge to the graph.
|
|
22
|
+
* @param graph - The graph to modify
|
|
23
|
+
* @param edge - The edge to add
|
|
24
|
+
*/
|
|
25
|
+
export declare function addEdge(graph: RepoGraph, edge: GraphEdge): void;
|
|
26
|
+
/**
|
|
27
|
+
* Resolve a module specifier relative to a source file within a workspace.
|
|
28
|
+
*
|
|
29
|
+
* CONTRACT for bare specifiers:
|
|
30
|
+
* - Bare specifiers (e.g., 'lodash', 'zod', '@scope/pkg') return null because
|
|
31
|
+
* they require node_modules traversal to resolve, which is outside the scope
|
|
32
|
+
* of this module's responsibilities.
|
|
33
|
+
* - Callers should treat null as "unresolvable at graph-build time" and may
|
|
34
|
+
* defer resolution to runtime or external tools.
|
|
35
|
+
*
|
|
36
|
+
* CONTRACT for workspace format:
|
|
37
|
+
* - workspaceRoot is normally a relative path (e.g., "my-project") validated by
|
|
38
|
+
* validateWorkspace, but when called by buildWorkspaceGraph it may be an
|
|
39
|
+
* absolute scan root path. Both forms are accepted - the function handles
|
|
40
|
+
* path boundary checks consistently regardless of which form is provided.
|
|
41
|
+
* - sourceFile must be an absolute path
|
|
42
|
+
* - Returns absolute path if resolved, null otherwise
|
|
43
|
+
*
|
|
44
|
+
* @param workspaceRoot - The workspace root directory (relative or absolute path)
|
|
45
|
+
* @param sourceFile - The file containing the import (absolute path)
|
|
46
|
+
* @param specifier - The module specifier from the import statement
|
|
47
|
+
* @returns Resolved absolute path or null if unresolvable
|
|
48
|
+
*/
|
|
49
|
+
export declare function resolveModuleSpecifier(workspaceRoot: string, sourceFile: string, specifier: string): string | null;
|
|
50
|
+
/**
|
|
51
|
+
* Result of scanning a single file for graph updates.
|
|
52
|
+
*/
|
|
53
|
+
export interface ScanResult {
|
|
54
|
+
/** The created node, or null if file was skipped */
|
|
55
|
+
node: GraphNode | null;
|
|
56
|
+
/** The edges created from this file's imports */
|
|
57
|
+
edges: GraphEdge[];
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Scan a single file and extract its graph node and edges.
|
|
61
|
+
* Reuses the same logic from buildWorkspaceGraph for consistency.
|
|
62
|
+
*
|
|
63
|
+
* @param filePath - Absolute path to the file to scan
|
|
64
|
+
* @param absoluteRoot - Absolute path to workspace root
|
|
65
|
+
* @param maxFileSize - Maximum file size in bytes
|
|
66
|
+
* @returns ScanResult with node and edges
|
|
67
|
+
*/
|
|
68
|
+
export declare function scanFile(filePath: string, absoluteRoot: string, maxFileSize: number): ScanResult;
|
|
69
|
+
/**
|
|
70
|
+
* Build a complete dependency graph for a workspace by scanning all source files.
|
|
71
|
+
*
|
|
72
|
+
* The scan is deterministic: files are processed in sorted order, and edges
|
|
73
|
+
* are added in a stable order based on source file and import specifier.
|
|
74
|
+
*
|
|
75
|
+
* @param workspaceRoot - Workspace root directory (absolute or relative path)
|
|
76
|
+
* @param options - Optional scan configuration
|
|
77
|
+
* @param options.maxFileSizeBytes - Maximum file size to scan (default 1MB)
|
|
78
|
+
* @returns Complete RepoGraph with nodes and edges
|
|
79
|
+
* @throws Error if workspace validation fails
|
|
80
|
+
*/
|
|
81
|
+
export declare function buildWorkspaceGraph(workspaceRoot: string, options?: BuildWorkspaceGraphOptions): RepoGraph;
|
|
82
|
+
/**
|
|
83
|
+
* Async, event-loop-safe variant of `buildWorkspaceGraph`. The traversal
|
|
84
|
+
* yields between batches and uses async fs primitives, so callers can run
|
|
85
|
+
* this from plugin init without freezing the host while a large workspace
|
|
86
|
+
* is scanned. The per-file processing remains sync — it is CPU-bound symbol
|
|
87
|
+
* extraction, and the existing per-file caps already prevent runaway work.
|
|
88
|
+
*
|
|
89
|
+
* Returned shape matches `buildWorkspaceGraph`. Same homedir guard, same
|
|
90
|
+
* bounded walk behavior, same deterministic file order.
|
|
91
|
+
*/
|
|
92
|
+
export declare function buildWorkspaceGraphAsync(workspaceRoot: string, options?: BuildWorkspaceGraphOptions): Promise<RepoGraph>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory cache for loaded repo graphs.
|
|
3
|
+
*
|
|
4
|
+
* Three maps keyed by normalized workspace path:
|
|
5
|
+
* - graphCache — the last loaded/saved RepoGraph for each workspace
|
|
6
|
+
* - dirtyFlags — whether the cached graph has been modified since the last save
|
|
7
|
+
* - mtimeCache — the file mtime at the time the graph was last loaded/saved,
|
|
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.
|
|
12
|
+
*/
|
|
13
|
+
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
|
+
*/
|
|
19
|
+
export declare function getCachedGraph(workspace: string): RepoGraph | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Set the cached graph for a workspace.
|
|
22
|
+
* @param workspace - The workspace directory (absolute or relative path)
|
|
23
|
+
* @param graph - The graph to cache
|
|
24
|
+
* @param mtime - Optional file mtime to track for cache invalidation
|
|
25
|
+
*/
|
|
26
|
+
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
|
+
*/
|
|
31
|
+
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
|
+
*/
|
|
37
|
+
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
|
+
*/
|
|
42
|
+
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
|
+
*/
|
|
48
|
+
export declare function getCachedMtime(workspace: string): number | undefined;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Incremental graph updates for changed files.
|
|
3
|
+
*
|
|
4
|
+
* updateGraphForFiles re-scans only the specified changed files, updates
|
|
5
|
+
* their nodes and edges in the existing graph, and saves the result. It
|
|
6
|
+
* includes an optimistic concurrency check (mtime comparison) so that
|
|
7
|
+
* concurrent sessions do not overwrite each other's updates — when a race
|
|
8
|
+
* is detected the function falls back to a full rebuild.
|
|
9
|
+
*/
|
|
10
|
+
import type { RepoGraph } from './types';
|
|
11
|
+
/**
|
|
12
|
+
* Incrementally update the graph for a set of changed files.
|
|
13
|
+
* Re-scans only the specified files, updates their nodes and edges,
|
|
14
|
+
* and falls back to a full rebuild if the incremental pass cannot be validated.
|
|
15
|
+
*
|
|
16
|
+
* @param workspaceRoot - Workspace root directory (relative path)
|
|
17
|
+
* @param filePaths - Array of absolute file paths that changed
|
|
18
|
+
* @param options - Optional configuration
|
|
19
|
+
* @param options.forceRebuild - Force a full rebuild instead of incremental
|
|
20
|
+
* @returns Updated RepoGraph
|
|
21
|
+
*/
|
|
22
|
+
export declare function updateGraphForFiles(workspaceRoot: string, filePaths: string[], options?: {
|
|
23
|
+
forceRebuild?: boolean;
|
|
24
|
+
}): Promise<RepoGraph>;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe load and save operations for repo-graph.json.
|
|
3
|
+
*
|
|
4
|
+
* All writes use an atomic temp-file + rename pattern to prevent partial
|
|
5
|
+
* writes. Reads validate schema and content before updating the in-memory
|
|
6
|
+
* cache. Symlink resolution guards against workspace-escape attacks.
|
|
7
|
+
*/
|
|
8
|
+
import type { RepoGraph } from './types';
|
|
9
|
+
/**
|
|
10
|
+
* Get the validated path for the repo-graph.json file.
|
|
11
|
+
* Resolves symlinks via realpath before validation to prevent
|
|
12
|
+
* workspace-escaping attacks via symlink manipulation.
|
|
13
|
+
*
|
|
14
|
+
* @param workspace - The workspace directory (absolute or relative path)
|
|
15
|
+
* @returns Absolute path to repo-graph.json
|
|
16
|
+
* @throws Error if path validation fails or resolved path escapes workspace
|
|
17
|
+
*/
|
|
18
|
+
export declare function getGraphPath(workspace: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Load the graph from .swarm/repo-graph.json.
|
|
21
|
+
* Uses the in-memory cache if available, not dirty, and file mtime unchanged.
|
|
22
|
+
*
|
|
23
|
+
* @param workspace - The workspace directory (absolute or relative path)
|
|
24
|
+
* @returns The loaded graph or null if not found
|
|
25
|
+
* @throws Error if file exists but is invalid/corrupted
|
|
26
|
+
*/
|
|
27
|
+
export declare function loadGraph(workspace: string): Promise<RepoGraph | null>;
|
|
28
|
+
/**
|
|
29
|
+
* Save the graph to .swarm/repo-graph.json atomically.
|
|
30
|
+
* Uses temp file + rename pattern to prevent partial writes.
|
|
31
|
+
*
|
|
32
|
+
* @param workspace - The workspace directory (absolute or relative path)
|
|
33
|
+
* @param graph - The graph to save
|
|
34
|
+
* @param options.createAtomic - If true, fails if file already exists (for atomic create)
|
|
35
|
+
* @throws Error if validation fails, write fails, or file exists when createAtomic=true
|
|
36
|
+
*/
|
|
37
|
+
export declare function saveGraph(workspace: string, graph: RepoGraph, options?: {
|
|
38
|
+
createAtomic?: boolean;
|
|
39
|
+
}): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Load or create a graph for a workspace atomically.
|
|
42
|
+
* Returns existing graph or creates a new empty one.
|
|
43
|
+
* Handles concurrent creation by treating a create-fail as "graph exists".
|
|
44
|
+
*
|
|
45
|
+
* @param workspace - The workspace directory (absolute or relative path)
|
|
46
|
+
* @returns The existing or new graph
|
|
47
|
+
*/
|
|
48
|
+
export declare function loadOrCreateGraph(workspace: string): Promise<RepoGraph>;
|
|
49
|
+
/**
|
|
50
|
+
* Save the cached graph for a workspace if it's dirty.
|
|
51
|
+
*
|
|
52
|
+
* @param workspace - The workspace directory (absolute or relative path)
|
|
53
|
+
* @throws Error if workspace is dirty but cache is missing (inconsistent state)
|
|
54
|
+
* @throws Error if save fails
|
|
55
|
+
*/
|
|
56
|
+
export declare function saveIfDirty(workspace: string): Promise<void>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types and core utilities for the repo dependency graph.
|
|
3
|
+
*
|
|
4
|
+
* This module is the dependency-free foundation: it contains only type
|
|
5
|
+
* definitions, schema constants, the normalizeGraphPath utility, and
|
|
6
|
+
* basic graph construction helpers that have no further internal dependencies.
|
|
7
|
+
* Every other submodule imports from here.
|
|
8
|
+
*/
|
|
9
|
+
export declare const REPO_GRAPH_FILENAME = "repo-graph.json";
|
|
10
|
+
export declare const GRAPH_SCHEMA_VERSION = "1.0.0";
|
|
11
|
+
/**
|
|
12
|
+
* A node in the dependency graph representing a source file.
|
|
13
|
+
*/
|
|
14
|
+
export interface GraphNode {
|
|
15
|
+
/** Resolved absolute path to the source file */
|
|
16
|
+
filePath: string;
|
|
17
|
+
/** Normalized module name (relative path from workspace root) */
|
|
18
|
+
moduleName: string;
|
|
19
|
+
/** Exported symbols from this file */
|
|
20
|
+
exports: string[];
|
|
21
|
+
/** Imported module specifiers */
|
|
22
|
+
imports: string[];
|
|
23
|
+
/** Language/extension of the file */
|
|
24
|
+
language: string;
|
|
25
|
+
/** Last modified timestamp */
|
|
26
|
+
mtime: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* An edge in the dependency graph representing a dependency relationship.
|
|
30
|
+
*/
|
|
31
|
+
export interface GraphEdge {
|
|
32
|
+
/** Source file path */
|
|
33
|
+
source: string;
|
|
34
|
+
/** Target file path (resolved) */
|
|
35
|
+
target: string;
|
|
36
|
+
/** Import specifier used */
|
|
37
|
+
importSpecifier: string;
|
|
38
|
+
/** Type of import */
|
|
39
|
+
importType: 'default' | 'named' | 'namespace' | 'require' | 'sideeffect';
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The complete dependency graph for a workspace.
|
|
43
|
+
*/
|
|
44
|
+
export interface RepoGraph {
|
|
45
|
+
/** Schema version for future compatibility */
|
|
46
|
+
schema_version: string;
|
|
47
|
+
/** Workspace root directory */
|
|
48
|
+
workspaceRoot: string;
|
|
49
|
+
/** Graph nodes keyed by resolved file path */
|
|
50
|
+
nodes: Record<string, GraphNode>;
|
|
51
|
+
/** Graph edges representing dependencies */
|
|
52
|
+
edges: GraphEdge[];
|
|
53
|
+
/** Graph metadata */
|
|
54
|
+
metadata: {
|
|
55
|
+
generatedAt: string;
|
|
56
|
+
generator: string;
|
|
57
|
+
nodeCount: number;
|
|
58
|
+
edgeCount: number;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Options for building a workspace graph.
|
|
63
|
+
*/
|
|
64
|
+
export interface BuildWorkspaceGraphOptions {
|
|
65
|
+
maxFileSizeBytes?: number;
|
|
66
|
+
maxFiles?: number;
|
|
67
|
+
walkBudgetMs?: number;
|
|
68
|
+
followSymlinks?: boolean;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Normalize a file path for use as a graph key.
|
|
72
|
+
* Uses path.normalize for segment cleanup, then converts all
|
|
73
|
+
* backslashes to forward slashes for cross-platform consistency.
|
|
74
|
+
* This ensures the same file produces the same key on Windows, macOS, and Linux.
|
|
75
|
+
*/
|
|
76
|
+
export declare function normalizeGraphPath(filePath: string): string;
|
|
77
|
+
/**
|
|
78
|
+
* Create an empty graph for a workspace.
|
|
79
|
+
* @param workspaceRoot - The workspace root directory
|
|
80
|
+
* @returns Empty RepoGraph structure
|
|
81
|
+
*/
|
|
82
|
+
export declare function createEmptyGraph(workspaceRoot: string): RepoGraph;
|
|
83
|
+
/**
|
|
84
|
+
* Update graph metadata after modifications.
|
|
85
|
+
* @param graph - The graph to update
|
|
86
|
+
*/
|
|
87
|
+
export declare function updateGraphMetadata(graph: RepoGraph): void;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation functions for workspace paths, graph nodes, and graph edges.
|
|
3
|
+
*
|
|
4
|
+
* All public functions throw descriptive errors on invalid input so callers
|
|
5
|
+
* can surface actionable messages rather than obscure downstream failures.
|
|
6
|
+
*/
|
|
7
|
+
import type { GraphEdge, GraphNode } from './types';
|
|
8
|
+
/**
|
|
9
|
+
* Validate that a workspace directory is safe to use.
|
|
10
|
+
* Accepts both absolute and relative paths.
|
|
11
|
+
*
|
|
12
|
+
* @param workspace - The workspace directory (path, absolute or relative, e.g. "/home/user/project" or "my-project")
|
|
13
|
+
* @throws Error if the workspace is invalid
|
|
14
|
+
*/
|
|
15
|
+
export declare function validateWorkspace(workspace: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* Validate a graph node before adding to the graph.
|
|
18
|
+
* @param node - The node to validate
|
|
19
|
+
* @throws Error if the node is invalid
|
|
20
|
+
*/
|
|
21
|
+
export declare function validateGraphNode(node: GraphNode): void;
|
|
22
|
+
/**
|
|
23
|
+
* Validate a graph edge before adding to the graph.
|
|
24
|
+
* @param edge - The edge to validate
|
|
25
|
+
* @throws Error if the edge is invalid
|
|
26
|
+
*/
|
|
27
|
+
export declare function validateGraphEdge(edge: GraphEdge): void;
|
|
@@ -1,240 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Repo graph
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
*
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* An edge in the dependency graph representing a dependency relationship.
|
|
27
|
-
*/
|
|
28
|
-
export interface GraphEdge {
|
|
29
|
-
/** Source file path */
|
|
30
|
-
source: string;
|
|
31
|
-
/** Target file path (resolved) */
|
|
32
|
-
target: string;
|
|
33
|
-
/** Import specifier used */
|
|
34
|
-
importSpecifier: string;
|
|
35
|
-
/** Type of import */
|
|
36
|
-
importType: 'default' | 'named' | 'namespace' | 'require' | 'sideeffect';
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* The complete dependency graph for a workspace.
|
|
40
|
-
*/
|
|
41
|
-
export interface RepoGraph {
|
|
42
|
-
/** Schema version for future compatibility */
|
|
43
|
-
schema_version: string;
|
|
44
|
-
/** Workspace root directory */
|
|
45
|
-
workspaceRoot: string;
|
|
46
|
-
/** Graph nodes keyed by resolved file path */
|
|
47
|
-
nodes: Record<string, GraphNode>;
|
|
48
|
-
/** Graph edges representing dependencies */
|
|
49
|
-
edges: GraphEdge[];
|
|
50
|
-
/** Graph metadata */
|
|
51
|
-
metadata: {
|
|
52
|
-
generatedAt: string;
|
|
53
|
-
generator: string;
|
|
54
|
-
nodeCount: number;
|
|
55
|
-
edgeCount: number;
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Validate that a workspace directory is safe to use.
|
|
60
|
-
* Accepts both absolute and relative paths.
|
|
61
|
-
*
|
|
62
|
-
* @param workspace - The workspace directory (path, absolute or relative, e.g. "/home/user/project" or "my-project")
|
|
63
|
-
* @throws Error if the workspace is invalid
|
|
64
|
-
*/
|
|
65
|
-
export declare function validateWorkspace(workspace: string): void;
|
|
66
|
-
/**
|
|
67
|
-
* Validate a graph node before adding to the graph.
|
|
68
|
-
* @param node - The node to validate
|
|
69
|
-
* @throws Error if the node is invalid
|
|
70
|
-
*/
|
|
71
|
-
export declare function validateGraphNode(node: GraphNode): void;
|
|
72
|
-
/**
|
|
73
|
-
* Validate a graph edge before adding to the graph.
|
|
74
|
-
* @param edge - The edge to validate
|
|
75
|
-
* @throws Error if the edge is invalid
|
|
76
|
-
*/
|
|
77
|
-
export declare function validateGraphEdge(edge: GraphEdge): void;
|
|
78
|
-
/**
|
|
79
|
-
* Resolve a module specifier relative to a source file within a workspace.
|
|
80
|
-
*
|
|
81
|
-
* CONTRACT for bare specifiers:
|
|
82
|
-
* - Bare specifiers (e.g., 'lodash', 'zod', '@scope/pkg') return null because
|
|
83
|
-
* they require node_modules traversal to resolve, which is outside the scope
|
|
84
|
-
* of this module's responsibilities.
|
|
85
|
-
* - Callers should treat null as "unresolvable at graph-build time" and may
|
|
86
|
-
* defer resolution to runtime or external tools.
|
|
87
|
-
*
|
|
88
|
-
* CONTRACT for workspace format:
|
|
89
|
-
* - workspaceRoot is normally a relative path (e.g., "my-project") validated by
|
|
90
|
-
* validateWorkspace, but when called by buildWorkspaceGraph it may be an
|
|
91
|
-
* absolute scan root path. Both forms are accepted - the function handles
|
|
92
|
-
* path boundary checks consistently regardless of which form is provided.
|
|
93
|
-
* - sourceFile must be an absolute path
|
|
94
|
-
* - Returns absolute path if resolved, null otherwise
|
|
95
|
-
*
|
|
96
|
-
* @param workspaceRoot - The workspace root directory (relative or absolute path)
|
|
97
|
-
* @param sourceFile - The file containing the import (absolute path)
|
|
98
|
-
* @param specifier - The module specifier from the import statement
|
|
99
|
-
* @returns Resolved absolute path or null if unresolvable
|
|
100
|
-
*/
|
|
101
|
-
export declare function resolveModuleSpecifier(workspaceRoot: string, sourceFile: string, specifier: string): string | null;
|
|
102
|
-
/**
|
|
103
|
-
* Create an empty graph for a workspace.
|
|
104
|
-
* @param workspaceRoot - The workspace root directory
|
|
105
|
-
* @returns Empty RepoGraph structure
|
|
106
|
-
*/
|
|
107
|
-
export declare function createEmptyGraph(workspaceRoot: string): RepoGraph;
|
|
108
|
-
/**
|
|
109
|
-
* Add or update a node in the graph.
|
|
110
|
-
* @param graph - The graph to modify
|
|
111
|
-
* @param node - The node to add/update
|
|
112
|
-
*/
|
|
113
|
-
export declare function upsertNode(graph: RepoGraph, node: GraphNode): void;
|
|
114
|
-
/**
|
|
115
|
-
* Add an edge to the graph.
|
|
116
|
-
* @param graph - The graph to modify
|
|
117
|
-
* @param edge - The edge to add
|
|
118
|
-
*/
|
|
119
|
-
export declare function addEdge(graph: RepoGraph, edge: GraphEdge): void;
|
|
120
|
-
/**
|
|
121
|
-
* Get the cached graph for a workspace.
|
|
122
|
-
* @param workspace - The workspace directory (absolute or relative path)
|
|
123
|
-
* @returns The cached graph or undefined if not cached
|
|
124
|
-
*/
|
|
125
|
-
export declare function getCachedGraph(workspace: string): RepoGraph | undefined;
|
|
126
|
-
/**
|
|
127
|
-
* Set the cached graph for a workspace.
|
|
128
|
-
* @param workspace - The workspace directory (absolute or relative path)
|
|
129
|
-
* @param graph - The graph to cache
|
|
130
|
-
* @param mtime - Optional file mtime to track for cache invalidation
|
|
131
|
-
*/
|
|
132
|
-
export declare function setCachedGraph(workspace: string, graph: RepoGraph, mtime?: number): void;
|
|
133
|
-
/**
|
|
134
|
-
* Mark a workspace's cache as dirty (modified since last save).
|
|
135
|
-
* @param workspace - The workspace directory (absolute or relative path)
|
|
136
|
-
*/
|
|
137
|
-
export declare function markDirty(workspace: string): void;
|
|
138
|
-
/**
|
|
139
|
-
* Check if a workspace's cache is dirty.
|
|
140
|
-
* @param workspace - The workspace directory (absolute or relative path)
|
|
141
|
-
* @returns True if the cache has been modified since last save
|
|
142
|
-
*/
|
|
143
|
-
export declare function isDirty(workspace: string): boolean;
|
|
144
|
-
/**
|
|
145
|
-
* Clear the cache for a workspace.
|
|
146
|
-
* @param workspace - The workspace directory (absolute or relative path)
|
|
147
|
-
*/
|
|
148
|
-
export declare function clearCache(workspace: string): void;
|
|
149
|
-
/**
|
|
150
|
-
* Get the validated path for the repo-graph.json file.
|
|
151
|
-
* Resolves symlinks via realpath before validation to prevent
|
|
152
|
-
* workspace-escaping attacks via symlink manipulation.
|
|
153
|
-
*
|
|
154
|
-
* @param workspace - The workspace directory (absolute or relative path)
|
|
155
|
-
* @returns Absolute path to repo-graph.json
|
|
156
|
-
* @throws Error if path validation fails or resolved path escapes workspace
|
|
157
|
-
*/
|
|
158
|
-
export declare function getGraphPath(workspace: string): string;
|
|
159
|
-
/**
|
|
160
|
-
* Load the graph from .swarm/repo-graph.json.
|
|
161
|
-
* Uses the in-memory cache if available, not dirty, and file mtime unchanged.
|
|
162
|
-
*
|
|
163
|
-
* @param workspace - The workspace directory (absolute or relative path)
|
|
164
|
-
* @returns The loaded graph or null if not found
|
|
165
|
-
* @throws Error if file exists but is invalid/corrupted
|
|
166
|
-
*/
|
|
167
|
-
export declare function loadGraph(workspace: string): Promise<RepoGraph | null>;
|
|
168
|
-
/**
|
|
169
|
-
* Save the graph to .swarm/repo-graph.json atomically.
|
|
170
|
-
* Uses temp file + rename pattern to prevent partial writes.
|
|
171
|
-
*
|
|
172
|
-
* @param workspace - The workspace directory (absolute or relative path)
|
|
173
|
-
* @param graph - The graph to save
|
|
174
|
-
* @param options.createAtomic - If true, fails if file already exists (for atomic create)
|
|
175
|
-
* @throws Error if validation fails, write fails, or file exists when createAtomic=true
|
|
176
|
-
*/
|
|
177
|
-
export declare function saveGraph(workspace: string, graph: RepoGraph, options?: {
|
|
178
|
-
createAtomic?: boolean;
|
|
179
|
-
}): Promise<void>;
|
|
180
|
-
/**
|
|
181
|
-
* Load or create a graph for a workspace atomically.
|
|
182
|
-
* Returns existing graph or creates a new empty one.
|
|
183
|
-
* Handles concurrent creation by treating a create-fail as "graph exists".
|
|
184
|
-
*
|
|
185
|
-
* @param workspace - The workspace directory (absolute or relative path)
|
|
186
|
-
* @returns The existing or new graph
|
|
187
|
-
*/
|
|
188
|
-
export declare function loadOrCreateGraph(workspace: string): Promise<RepoGraph>;
|
|
189
|
-
/**
|
|
190
|
-
* Save the cached graph for a workspace if it's dirty.
|
|
191
|
-
*
|
|
192
|
-
* @param workspace - The workspace directory (absolute or relative path)
|
|
193
|
-
* @throws Error if workspace is dirty but cache is missing (inconsistent state)
|
|
194
|
-
* @throws Error if save fails
|
|
195
|
-
*/
|
|
196
|
-
export declare function saveIfDirty(workspace: string): Promise<void>;
|
|
197
|
-
/**
|
|
198
|
-
* Build a complete dependency graph for a workspace by scanning all source files.
|
|
199
|
-
*
|
|
200
|
-
* The scan is deterministic: files are processed in sorted order, and edges
|
|
201
|
-
* are added in a stable order based on source file and import specifier.
|
|
202
|
-
*
|
|
203
|
-
* @param workspaceRoot - Workspace root directory (absolute or relative path)
|
|
204
|
-
* @param options - Optional scan configuration
|
|
205
|
-
* @param options.maxFileSizeBytes - Maximum file size to scan (default 1MB)
|
|
206
|
-
* @returns Complete RepoGraph with nodes and edges
|
|
207
|
-
* @throws Error if workspace validation fails
|
|
208
|
-
*/
|
|
209
|
-
export interface BuildWorkspaceGraphOptions {
|
|
210
|
-
maxFileSizeBytes?: number;
|
|
211
|
-
maxFiles?: number;
|
|
212
|
-
walkBudgetMs?: number;
|
|
213
|
-
followSymlinks?: boolean;
|
|
214
|
-
}
|
|
215
|
-
export declare function buildWorkspaceGraph(workspaceRoot: string, options?: BuildWorkspaceGraphOptions): RepoGraph;
|
|
216
|
-
/**
|
|
217
|
-
* Async, event-loop-safe variant of `buildWorkspaceGraph`. The traversal
|
|
218
|
-
* yields between batches and uses async fs primitives, so callers can run
|
|
219
|
-
* this from plugin init without freezing the host while a large workspace
|
|
220
|
-
* is scanned. The per-file processing remains sync — it is CPU-bound symbol
|
|
221
|
-
* extraction, and the existing per-file caps already prevent runaway work.
|
|
222
|
-
*
|
|
223
|
-
* Returned shape matches `buildWorkspaceGraph`. Same homedir guard, same
|
|
224
|
-
* bounded walk behavior, same deterministic file order.
|
|
225
|
-
*/
|
|
226
|
-
export declare function buildWorkspaceGraphAsync(workspaceRoot: string, options?: BuildWorkspaceGraphOptions): Promise<RepoGraph>;
|
|
227
|
-
/**
|
|
228
|
-
* Incrementally update the graph for a set of changed files.
|
|
229
|
-
* Re-scans only the specified files, updates their nodes and edges,
|
|
230
|
-
* and falls back to a full rebuild if the incremental pass cannot be validated.
|
|
231
|
-
*
|
|
232
|
-
* @param workspaceRoot - Workspace root directory (relative path)
|
|
233
|
-
* @param filePaths - Array of absolute file paths that changed
|
|
234
|
-
* @param options - Optional configuration
|
|
235
|
-
* @param options.forceRebuild - Force a full rebuild instead of incremental
|
|
236
|
-
* @returns Updated RepoGraph
|
|
237
|
-
*/
|
|
238
|
-
export declare function updateGraphForFiles(workspaceRoot: string, filePaths: string[], options?: {
|
|
239
|
-
forceRebuild?: boolean;
|
|
240
|
-
}): Promise<RepoGraph>;
|
|
2
|
+
* Repo graph module — public API barrel.
|
|
3
|
+
*
|
|
4
|
+
* This file re-exports the complete public API of the repo graph system.
|
|
5
|
+
* The implementation has been split into focused submodules under
|
|
6
|
+
* src/tools/repo-graph/ for maintainability:
|
|
7
|
+
*
|
|
8
|
+
* types.ts — types/interfaces, constants, and basic graph helpers
|
|
9
|
+
* validation.ts — path/node/edge validation functions
|
|
10
|
+
* cache.ts — in-memory graph cache operations
|
|
11
|
+
* storage.ts — safe load and save to .swarm/repo-graph.json
|
|
12
|
+
* builder.ts — workspace scanning and full-graph construction
|
|
13
|
+
* incremental.ts — incremental updates for changed files
|
|
14
|
+
*
|
|
15
|
+
* All existing imports of this module continue to work unchanged.
|
|
16
|
+
*/
|
|
17
|
+
export type { ScanResult } from './repo-graph/builder';
|
|
18
|
+
export { addEdge, buildWorkspaceGraph, buildWorkspaceGraphAsync, resolveModuleSpecifier, upsertNode, } from './repo-graph/builder';
|
|
19
|
+
export { clearCache, getCachedGraph, getCachedMtime, isDirty, markDirty, setCachedGraph, } from './repo-graph/cache';
|
|
20
|
+
export { updateGraphForFiles } from './repo-graph/incremental';
|
|
21
|
+
export { getGraphPath, loadGraph, loadOrCreateGraph, saveGraph, saveIfDirty, } from './repo-graph/storage';
|
|
22
|
+
export type { BuildWorkspaceGraphOptions, GraphEdge, GraphNode, RepoGraph, } from './repo-graph/types';
|
|
23
|
+
export { createEmptyGraph, GRAPH_SCHEMA_VERSION, normalizeGraphPath, REPO_GRAPH_FILENAME, updateGraphMetadata, } from './repo-graph/types';
|
|
24
|
+
export { validateGraphEdge, validateGraphNode, validateWorkspace, } from './repo-graph/validation';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.5.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",
|