octie-cli 1.0.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/README.md +523 -0
- package/dist/cli/commands/approve.d.ts +27 -0
- package/dist/cli/commands/approve.d.ts.map +1 -0
- package/dist/cli/commands/approve.js +119 -0
- package/dist/cli/commands/approve.js.map +1 -0
- package/dist/cli/commands/batch.d.ts +15 -0
- package/dist/cli/commands/batch.d.ts.map +1 -0
- package/dist/cli/commands/batch.js +521 -0
- package/dist/cli/commands/batch.js.map +1 -0
- package/dist/cli/commands/create.d.ts +9 -0
- package/dist/cli/commands/create.d.ts.map +1 -0
- package/dist/cli/commands/create.js +321 -0
- package/dist/cli/commands/create.js.map +1 -0
- package/dist/cli/commands/delete.d.ts +9 -0
- package/dist/cli/commands/delete.d.ts.map +1 -0
- package/dist/cli/commands/delete.js +143 -0
- package/dist/cli/commands/delete.js.map +1 -0
- package/dist/cli/commands/export.d.ts +9 -0
- package/dist/cli/commands/export.d.ts.map +1 -0
- package/dist/cli/commands/export.js +66 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/find.d.ts +16 -0
- package/dist/cli/commands/find.d.ts.map +1 -0
- package/dist/cli/commands/find.js +252 -0
- package/dist/cli/commands/find.js.map +1 -0
- package/dist/cli/commands/get.d.ts +9 -0
- package/dist/cli/commands/get.d.ts.map +1 -0
- package/dist/cli/commands/get.js +74 -0
- package/dist/cli/commands/get.js.map +1 -0
- package/dist/cli/commands/graph.d.ts +9 -0
- package/dist/cli/commands/graph.d.ts.map +1 -0
- package/dist/cli/commands/graph.js +200 -0
- package/dist/cli/commands/graph.js.map +1 -0
- package/dist/cli/commands/import.d.ts +9 -0
- package/dist/cli/commands/import.d.ts.map +1 -0
- package/dist/cli/commands/import.js +807 -0
- package/dist/cli/commands/import.js.map +1 -0
- package/dist/cli/commands/init.d.ts +9 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +57 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/list.d.ts +9 -0
- package/dist/cli/commands/list.d.ts.map +1 -0
- package/dist/cli/commands/list.js +175 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/merge.d.ts +9 -0
- package/dist/cli/commands/merge.d.ts.map +1 -0
- package/dist/cli/commands/merge.js +113 -0
- package/dist/cli/commands/merge.js.map +1 -0
- package/dist/cli/commands/serve.d.ts +9 -0
- package/dist/cli/commands/serve.d.ts.map +1 -0
- package/dist/cli/commands/serve.js +94 -0
- package/dist/cli/commands/serve.js.map +1 -0
- package/dist/cli/commands/update.d.ts +9 -0
- package/dist/cli/commands/update.d.ts.map +1 -0
- package/dist/cli/commands/update.js +423 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/commands/wire.d.ts +15 -0
- package/dist/cli/commands/wire.d.ts.map +1 -0
- package/dist/cli/commands/wire.js +164 -0
- package/dist/cli/commands/wire.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +100 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/output/json.d.ts +16 -0
- package/dist/cli/output/json.d.ts.map +1 -0
- package/dist/cli/output/json.js +29 -0
- package/dist/cli/output/json.js.map +1 -0
- package/dist/cli/output/markdown.d.ts +15 -0
- package/dist/cli/output/markdown.d.ts.map +1 -0
- package/dist/cli/output/markdown.js +206 -0
- package/dist/cli/output/markdown.js.map +1 -0
- package/dist/cli/output/table.d.ts +23 -0
- package/dist/cli/output/table.d.ts.map +1 -0
- package/dist/cli/output/table.js +150 -0
- package/dist/cli/output/table.js.map +1 -0
- package/dist/cli/utils/helpers.d.ts +126 -0
- package/dist/cli/utils/helpers.d.ts.map +1 -0
- package/dist/cli/utils/helpers.js +325 -0
- package/dist/cli/utils/helpers.js.map +1 -0
- package/dist/core/graph/algorithms.d.ts +11 -0
- package/dist/core/graph/algorithms.d.ts.map +1 -0
- package/dist/core/graph/algorithms.js +14 -0
- package/dist/core/graph/algorithms.js.map +1 -0
- package/dist/core/graph/cycle.d.ts +155 -0
- package/dist/core/graph/cycle.d.ts.map +1 -0
- package/dist/core/graph/cycle.js +297 -0
- package/dist/core/graph/cycle.js.map +1 -0
- package/dist/core/graph/index.d.ts +223 -0
- package/dist/core/graph/index.d.ts.map +1 -0
- package/dist/core/graph/index.js +475 -0
- package/dist/core/graph/index.js.map +1 -0
- package/dist/core/graph/operations.d.ts +240 -0
- package/dist/core/graph/operations.d.ts.map +1 -0
- package/dist/core/graph/operations.js +503 -0
- package/dist/core/graph/operations.js.map +1 -0
- package/dist/core/graph/sort.d.ts +76 -0
- package/dist/core/graph/sort.d.ts.map +1 -0
- package/dist/core/graph/sort.js +254 -0
- package/dist/core/graph/sort.js.map +1 -0
- package/dist/core/graph/traversal.d.ts +122 -0
- package/dist/core/graph/traversal.d.ts.map +1 -0
- package/dist/core/graph/traversal.js +336 -0
- package/dist/core/graph/traversal.js.map +1 -0
- package/dist/core/models/task-node.d.ts +328 -0
- package/dist/core/models/task-node.d.ts.map +1 -0
- package/dist/core/models/task-node.js +1090 -0
- package/dist/core/models/task-node.js.map +1 -0
- package/dist/core/registry/index.d.ts +102 -0
- package/dist/core/registry/index.d.ts.map +1 -0
- package/dist/core/registry/index.js +249 -0
- package/dist/core/registry/index.js.map +1 -0
- package/dist/core/registry/root-guard.d.ts +19 -0
- package/dist/core/registry/root-guard.d.ts.map +1 -0
- package/dist/core/registry/root-guard.js +28 -0
- package/dist/core/registry/root-guard.js.map +1 -0
- package/dist/core/storage/atomic-write.d.ts +181 -0
- package/dist/core/storage/atomic-write.d.ts.map +1 -0
- package/dist/core/storage/atomic-write.js +379 -0
- package/dist/core/storage/atomic-write.js.map +1 -0
- package/dist/core/storage/file-store.d.ts +148 -0
- package/dist/core/storage/file-store.d.ts.map +1 -0
- package/dist/core/storage/file-store.js +423 -0
- package/dist/core/storage/file-store.js.map +1 -0
- package/dist/core/storage/indexer.d.ts +138 -0
- package/dist/core/storage/indexer.d.ts.map +1 -0
- package/dist/core/storage/indexer.js +350 -0
- package/dist/core/storage/indexer.js.map +1 -0
- package/dist/core/utils/status-helpers.d.ts +59 -0
- package/dist/core/utils/status-helpers.d.ts.map +1 -0
- package/dist/core/utils/status-helpers.js +149 -0
- package/dist/core/utils/status-helpers.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +504 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +182 -0
- package/dist/types/index.js.map +1 -0
- package/dist/web/routes/graph.d.ts +17 -0
- package/dist/web/routes/graph.d.ts.map +1 -0
- package/dist/web/routes/graph.js +277 -0
- package/dist/web/routes/graph.js.map +1 -0
- package/dist/web/routes/projects.d.ts +14 -0
- package/dist/web/routes/projects.d.ts.map +1 -0
- package/dist/web/routes/projects.js +102 -0
- package/dist/web/routes/projects.js.map +1 -0
- package/dist/web/routes/tasks.d.ts +17 -0
- package/dist/web/routes/tasks.d.ts.map +1 -0
- package/dist/web/routes/tasks.js +538 -0
- package/dist/web/routes/tasks.js.map +1 -0
- package/dist/web/server.d.ts +121 -0
- package/dist/web/server.d.ts.map +1 -0
- package/dist/web/server.js +389 -0
- package/dist/web/server.js.map +1 -0
- package/dist/web-ui/assets/index-BB0qvF1y.css +1 -0
- package/dist/web-ui/assets/index-Vmm72oKY.js +34 -0
- package/dist/web-ui/index.html +14 -0
- package/dist/web-ui/vite.svg +1 -0
- package/package.json +94 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph cycle detection algorithms
|
|
3
|
+
*
|
|
4
|
+
* Implements DFS-based cycle detection with three-color marking.
|
|
5
|
+
* Detects all cycles and returns cycle paths for debugging.
|
|
6
|
+
* Time complexity: O(V + E) where V = vertices, E = edges
|
|
7
|
+
*
|
|
8
|
+
* @module core/graph/cycle
|
|
9
|
+
*/
|
|
10
|
+
import { CircularDependencyError } from '../../types/index.js';
|
|
11
|
+
/** Node visitation states for DFS cycle detection */
|
|
12
|
+
var VisitState;
|
|
13
|
+
(function (VisitState) {
|
|
14
|
+
/** Node has not been visited */
|
|
15
|
+
VisitState[VisitState["WHITE"] = 0] = "WHITE";
|
|
16
|
+
/** Node is currently being visited (in recursion stack) */
|
|
17
|
+
VisitState[VisitState["GRAY"] = 1] = "GRAY";
|
|
18
|
+
/** Node and all descendants have been completely visited */
|
|
19
|
+
VisitState[VisitState["BLACK"] = 2] = "BLACK";
|
|
20
|
+
})(VisitState || (VisitState = {}));
|
|
21
|
+
/**
|
|
22
|
+
* Detect cycles using DFS with three-color marking
|
|
23
|
+
*
|
|
24
|
+
* Algorithm:
|
|
25
|
+
* 1. Mark all nodes as WHITE (unvisited)
|
|
26
|
+
* 2. For each WHITE node, start DFS traversal
|
|
27
|
+
* 3. Mark node as GRAY when entering, BLACK when exiting
|
|
28
|
+
* 4. If we encounter a GRAY node during traversal, we found a cycle
|
|
29
|
+
* 5. Check for self-loops (task blocking itself) before DFS
|
|
30
|
+
* 6. Reconstruct cycle path using parent pointers
|
|
31
|
+
*
|
|
32
|
+
* Time Complexity: O(V + E)
|
|
33
|
+
* Space Complexity: O(V) for recursion stack and state tracking
|
|
34
|
+
*
|
|
35
|
+
* @param graph - Task graph store
|
|
36
|
+
* @returns Cycle detection result with all detected cycles
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* const result = detectCycle(graph);
|
|
41
|
+
* if (result.hasCycle) {
|
|
42
|
+
* console.error('Found cycles:', result.cycles);
|
|
43
|
+
* for (const cycle of result.cycles) {
|
|
44
|
+
* console.error('Cycle:', cycle.join(' -> '));
|
|
45
|
+
* }
|
|
46
|
+
* }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export function detectCycle(graph) {
|
|
50
|
+
const cycles = [];
|
|
51
|
+
const color = new Map();
|
|
52
|
+
const parent = new Map();
|
|
53
|
+
// Initialize all nodes as WHITE
|
|
54
|
+
for (const taskId of graph.getAllTaskIds()) {
|
|
55
|
+
color.set(taskId, VisitState.WHITE);
|
|
56
|
+
parent.set(taskId, null);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* DFS traversal to detect cycles
|
|
60
|
+
* @param nodeId - Current node being visited
|
|
61
|
+
* @returns true if a cycle was found (can continue to find more)
|
|
62
|
+
*/
|
|
63
|
+
function dfs(nodeId) {
|
|
64
|
+
// Mark current node as being visited
|
|
65
|
+
color.set(nodeId, VisitState.GRAY);
|
|
66
|
+
// Check for self-loop (task blocks itself)
|
|
67
|
+
const task = graph.getNode(nodeId);
|
|
68
|
+
if (task && task.blockers.includes(nodeId)) {
|
|
69
|
+
cycles.push([nodeId, nodeId]); // Self-loop: A -> A
|
|
70
|
+
// Continue to find more cycles, don't return yet
|
|
71
|
+
}
|
|
72
|
+
// Visit all neighbors
|
|
73
|
+
const neighbors = graph.getOutgoingEdges(nodeId);
|
|
74
|
+
for (const neighbor of neighbors) {
|
|
75
|
+
const neighborState = color.get(neighbor) ?? VisitState.WHITE;
|
|
76
|
+
if (neighborState === VisitState.GRAY) {
|
|
77
|
+
// Found a cycle - reconstruct the path
|
|
78
|
+
const cycle = [neighbor];
|
|
79
|
+
// Backtrack from current node to the neighbor
|
|
80
|
+
let current = nodeId;
|
|
81
|
+
while (current && current !== neighbor) {
|
|
82
|
+
cycle.unshift(current);
|
|
83
|
+
current = parent.get(current) || null;
|
|
84
|
+
}
|
|
85
|
+
// Add neighbor at start to complete the cycle
|
|
86
|
+
cycle.unshift(neighbor);
|
|
87
|
+
cycles.push(cycle);
|
|
88
|
+
return true; // Continue to find more cycles
|
|
89
|
+
}
|
|
90
|
+
if (neighborState === VisitState.WHITE) {
|
|
91
|
+
// Set parent and continue DFS
|
|
92
|
+
parent.set(neighbor, nodeId);
|
|
93
|
+
if (dfs(neighbor)) {
|
|
94
|
+
return true; // Continue searching
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// BLACK nodes are already processed, skip them
|
|
98
|
+
}
|
|
99
|
+
// Mark node as completely visited
|
|
100
|
+
color.set(nodeId, VisitState.BLACK);
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
// Start DFS from all unvisited nodes
|
|
104
|
+
for (const taskId of graph.getAllTaskIds()) {
|
|
105
|
+
if ((color.get(taskId) ?? VisitState.WHITE) === VisitState.WHITE) {
|
|
106
|
+
dfs(taskId);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
hasCycle: cycles.length > 0,
|
|
111
|
+
cycles,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Check if a graph contains any cycles
|
|
116
|
+
* Convenience function that returns a boolean
|
|
117
|
+
*
|
|
118
|
+
* @param graph - Task graph store
|
|
119
|
+
* @returns true if graph contains at least one cycle
|
|
120
|
+
*/
|
|
121
|
+
export function hasCycle(graph) {
|
|
122
|
+
const result = detectCycle(graph);
|
|
123
|
+
return result.hasCycle;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Get all nodes involved in cycles
|
|
127
|
+
*
|
|
128
|
+
* @param graph - Task graph store
|
|
129
|
+
* @returns Set of task IDs that are part of at least one cycle
|
|
130
|
+
*/
|
|
131
|
+
export function getCyclicNodes(graph) {
|
|
132
|
+
const result = detectCycle(graph);
|
|
133
|
+
const cyclicNodes = new Set();
|
|
134
|
+
for (const cycle of result.cycles) {
|
|
135
|
+
for (const nodeId of cycle) {
|
|
136
|
+
cyclicNodes.add(nodeId);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return cyclicNodes;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Find the shortest cycle in the graph
|
|
143
|
+
* Useful for identifying the most critical circular dependency
|
|
144
|
+
*
|
|
145
|
+
* @param graph - Task graph store
|
|
146
|
+
* @returns Shortest cycle array, or empty array if no cycles
|
|
147
|
+
*/
|
|
148
|
+
export function findShortestCycle(graph) {
|
|
149
|
+
const result = detectCycle(graph);
|
|
150
|
+
if (result.cycles.length === 0) {
|
|
151
|
+
return [];
|
|
152
|
+
}
|
|
153
|
+
return result.cycles.reduce((shortest, current) => current.length < shortest.length ? current : shortest);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Find all cycles involving a specific task
|
|
157
|
+
*
|
|
158
|
+
* @param graph - Task graph store
|
|
159
|
+
* @param taskId - Task ID to find cycles for
|
|
160
|
+
* @returns Array of cycles that include the specified task
|
|
161
|
+
*/
|
|
162
|
+
export function findCyclesForTask(graph, taskId) {
|
|
163
|
+
const result = detectCycle(graph);
|
|
164
|
+
return result.cycles.filter(cycle => cycle.includes(taskId));
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Validate that a graph is acyclic (DAG)
|
|
168
|
+
* Throws an error if cycles are detected
|
|
169
|
+
*
|
|
170
|
+
* @param graph - Task graph store
|
|
171
|
+
* @throws {CircularDependencyError} If graph contains cycles
|
|
172
|
+
*/
|
|
173
|
+
export function validateAcyclic(graph) {
|
|
174
|
+
const result = detectCycle(graph);
|
|
175
|
+
if (result.hasCycle) {
|
|
176
|
+
// Use the first cycle found for the error
|
|
177
|
+
const firstCycle = result.cycles[0];
|
|
178
|
+
if (firstCycle) {
|
|
179
|
+
throw new CircularDependencyError(firstCycle);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Get cycle statistics
|
|
185
|
+
*
|
|
186
|
+
* @param graph - Task graph store
|
|
187
|
+
* @returns Object with cycle count and nodes in cycles
|
|
188
|
+
*/
|
|
189
|
+
export function getCycleStatistics(graph) {
|
|
190
|
+
const result = detectCycle(graph);
|
|
191
|
+
const cyclicNodes = getCyclicNodes(graph);
|
|
192
|
+
const cyclesByLength = {};
|
|
193
|
+
for (const cycle of result.cycles) {
|
|
194
|
+
const len = cycle.length;
|
|
195
|
+
cyclesByLength[len] = (cyclesByLength[len] || 0) + 1;
|
|
196
|
+
}
|
|
197
|
+
return {
|
|
198
|
+
cycleCount: result.cycles.length,
|
|
199
|
+
nodesInCycles: cyclicNodes.size,
|
|
200
|
+
totalNodes: graph.size,
|
|
201
|
+
cyclesByLength,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Validate that all blocker references point to existing tasks
|
|
206
|
+
*
|
|
207
|
+
* Checks each task's blockers array to ensure all referenced tasks exist.
|
|
208
|
+
* This catches orphaned references that could occur from:
|
|
209
|
+
* - Manual JSON editing
|
|
210
|
+
* - Bugs in edge manipulation
|
|
211
|
+
* - Incomplete graph operations
|
|
212
|
+
*
|
|
213
|
+
* @param graph - Task graph store
|
|
214
|
+
* @returns Validation result with any invalid references found
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```ts
|
|
218
|
+
* const result = validateReferences(graph);
|
|
219
|
+
* if (result.hasInvalidReferences) {
|
|
220
|
+
* for (const ref of result.invalidReferences) {
|
|
221
|
+
* console.error(`Task ${ref.taskId} has missing blocker: ${ref.invalidBlockerId}`);
|
|
222
|
+
* }
|
|
223
|
+
* }
|
|
224
|
+
* ```
|
|
225
|
+
*/
|
|
226
|
+
export function validateReferences(graph) {
|
|
227
|
+
const invalidReferences = [];
|
|
228
|
+
for (const taskId of graph.getAllTaskIds()) {
|
|
229
|
+
const task = graph.getNode(taskId);
|
|
230
|
+
if (task) {
|
|
231
|
+
for (const blockerId of task.blockers) {
|
|
232
|
+
if (!graph.hasNode(blockerId)) {
|
|
233
|
+
invalidReferences.push({ taskId, invalidBlockerId: blockerId });
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return {
|
|
239
|
+
hasInvalidReferences: invalidReferences.length > 0,
|
|
240
|
+
invalidReferences,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Check if adding an edge would create a cycle
|
|
245
|
+
*
|
|
246
|
+
* When adding a blocker relationship (blockerId → taskId), this function
|
|
247
|
+
* checks if there's already a path from taskId to blockerId. If so,
|
|
248
|
+
* adding the edge would create a cycle.
|
|
249
|
+
*
|
|
250
|
+
* Also rejects self-blocking (taskId === blockerId).
|
|
251
|
+
*
|
|
252
|
+
* @param graph - Task graph store
|
|
253
|
+
* @param blockerId - The task that will block (source of edge)
|
|
254
|
+
* @param taskId - The task being blocked (target of edge)
|
|
255
|
+
* @returns true if adding this edge would create a cycle
|
|
256
|
+
*
|
|
257
|
+
* @example
|
|
258
|
+
* ```ts
|
|
259
|
+
* // Before adding blocker, check for cycle
|
|
260
|
+
* if (wouldCreateCycle(graph, blockerId, taskId)) {
|
|
261
|
+
* console.error('Cannot add blocker: would create a cycle');
|
|
262
|
+
* } else {
|
|
263
|
+
* task.addBlocker(blockerId);
|
|
264
|
+
* graph.addEdge(blockerId, taskId);
|
|
265
|
+
* }
|
|
266
|
+
* ```
|
|
267
|
+
*/
|
|
268
|
+
export function wouldCreateCycle(graph, blockerId, taskId) {
|
|
269
|
+
// Self-blocking is always a cycle
|
|
270
|
+
if (blockerId === taskId) {
|
|
271
|
+
return true;
|
|
272
|
+
}
|
|
273
|
+
// Check if taskId can already reach blockerId through existing edges
|
|
274
|
+
// If so, adding blockerId → taskId would create a cycle
|
|
275
|
+
// We search 'forward' from taskId following outgoing edges
|
|
276
|
+
const visited = new Set();
|
|
277
|
+
const queue = [taskId];
|
|
278
|
+
while (queue.length > 0) {
|
|
279
|
+
const currentId = queue.shift();
|
|
280
|
+
if (currentId === blockerId) {
|
|
281
|
+
return true; // Found path from taskId to blockerId
|
|
282
|
+
}
|
|
283
|
+
if (visited.has(currentId)) {
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
visited.add(currentId);
|
|
287
|
+
// Follow outgoing edges (tasks that this task blocks)
|
|
288
|
+
const neighbors = graph.getOutgoingEdges(currentId);
|
|
289
|
+
for (const neighbor of neighbors) {
|
|
290
|
+
if (!visited.has(neighbor)) {
|
|
291
|
+
queue.push(neighbor);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
//# sourceMappingURL=cycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cycle.js","sourceRoot":"","sources":["../../../src/core/graph/cycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,qDAAqD;AACrD,IAAW,UAOV;AAPD,WAAW,UAAU;IACnB,gCAAgC;IAChC,6CAAS,CAAA;IACT,2DAA2D;IAC3D,2CAAQ,CAAA;IACR,4DAA4D;IAC5D,6CAAS,CAAA;AACX,CAAC,EAPU,UAAU,KAAV,UAAU,QAOpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,UAAU,WAAW,CAAC,KAAqB;IAC/C,MAAM,MAAM,GAAe,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC5C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC;IAEhD,gCAAgC;IAChC,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,aAAa,EAAE,EAAE,CAAC;QAC3C,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED;;;;OAIG;IACH,SAAS,GAAG,CAAC,MAAc;QACzB,qCAAqC;QACrC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;QAEnC,2CAA2C;QAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACnC,IAAI,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3C,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,oBAAoB;YACnD,iDAAiD;QACnD,CAAC;QAED,sBAAsB;QACtB,MAAM,SAAS,GAAG,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACjD,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,MAAM,aAAa,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC;YAE9D,IAAI,aAAa,KAAK,UAAU,CAAC,IAAI,EAAE,CAAC;gBACtC,uCAAuC;gBACvC,MAAM,KAAK,GAAa,CAAC,QAAQ,CAAC,CAAC;gBAEnC,8CAA8C;gBAC9C,IAAI,OAAO,GAAkB,MAAM,CAAC;gBACpC,OAAO,OAAO,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;oBACvC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;oBACvB,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;gBACxC,CAAC;gBAED,8CAA8C;gBAC9C,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBAExB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACnB,OAAO,IAAI,CAAC,CAAC,+BAA+B;YAC9C,CAAC;YAED,IAAI,aAAa,KAAK,UAAU,CAAC,KAAK,EAAE,CAAC;gBACvC,8BAA8B;gBAC9B,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;gBAC7B,IAAI,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAClB,OAAO,IAAI,CAAC,CAAC,qBAAqB;gBACpC,CAAC;YACH,CAAC;YACD,+CAA+C;QACjD,CAAC;QAED,kCAAkC;QAClC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;QACpC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,qCAAqC;IACrC,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,aAAa,EAAE,EAAE,CAAC;QAC3C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,KAAK,UAAU,CAAC,KAAK,EAAE,CAAC;YACjE,GAAG,CAAC,MAAM,CAAC,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC;QAC3B,MAAM;KACP,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAqB;IAC5C,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAClC,OAAO,MAAM,CAAC,QAAQ,CAAC;AACzB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,KAAqB;IAClD,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IAEtC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClC,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE,CAAC;YAC3B,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAqB;IACrD,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAElC,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CAChD,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CACtD,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAqB,EAAE,MAAc;IACrE,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAElC,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,KAAqB;IACnD,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAElC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,0CAA0C;QAC1C,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACpC,IAAI,UAAU,EAAE,CAAC;YACf,MAAM,IAAI,uBAAuB,CAAC,UAAU,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAqB;IAMtD,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IAE1C,MAAM,cAAc,GAA2B,EAAE,CAAC;IAClD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC;QACzB,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACvD,CAAC;IAED,OAAO;QACL,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM;QAChC,aAAa,EAAE,WAAW,CAAC,IAAI;QAC/B,UAAU,EAAE,KAAK,CAAC,IAAI;QACtB,cAAc;KACf,CAAC;AACJ,CAAC;AAiBD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAqB;IACtD,MAAM,iBAAiB,GAAmD,EAAE,CAAC;IAE7E,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,aAAa,EAAE,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACnC,IAAI,IAAI,EAAE,CAAC;YACT,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACtC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;oBAC9B,iBAAiB,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,gBAAgB,EAAE,SAAS,EAAE,CAAC,CAAC;gBAClE,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,oBAAoB,EAAE,iBAAiB,CAAC,MAAM,GAAG,CAAC;QAClD,iBAAiB;KAClB,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAAqB,EACrB,SAAiB,EACjB,MAAc;IAEd,kCAAkC;IAClC,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qEAAqE;IACrE,wDAAwD;IACxD,2DAA2D;IAC3D,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,KAAK,GAAa,CAAC,MAAM,CAAC,CAAC;IAEjC,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,EAAG,CAAC;QAEjC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC,CAAC,sCAAsC;QACrD,CAAC;QAED,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,SAAS;QACX,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAEvB,sDAAsD;QACtD,MAAM,SAAS,GAAG,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QACpD,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC3B,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task Graph data structure
|
|
3
|
+
*
|
|
4
|
+
* Implements a directed graph using adjacency lists for O(1) node lookup
|
|
5
|
+
* and O(k) edge traversal where k is the number of edges.
|
|
6
|
+
*
|
|
7
|
+
* Graph Structure:
|
|
8
|
+
* - nodes: Map<taskId, TaskNode> for O(1) node lookup
|
|
9
|
+
* - outgoingEdges: Map<taskId, Set<targetTaskIds>> for forward traversal
|
|
10
|
+
* - incomingEdges: Map<taskId, Set<sourceTaskIds>> for reverse traversal
|
|
11
|
+
*
|
|
12
|
+
* @module core/graph
|
|
13
|
+
*/
|
|
14
|
+
import type { TaskGraph, ProjectMetadata } from '../../types/index.js';
|
|
15
|
+
import { TaskNode } from '../models/task-node.js';
|
|
16
|
+
/**
|
|
17
|
+
* TaskGraphStore class
|
|
18
|
+
*
|
|
19
|
+
* Manages the task graph data structure with efficient lookup and traversal.
|
|
20
|
+
* Uses Map and Set for optimal performance:
|
|
21
|
+
* - O(1) node lookup by ID
|
|
22
|
+
* - O(k) edge traversal where k = edge count
|
|
23
|
+
* - O(1) edge existence checking
|
|
24
|
+
*/
|
|
25
|
+
export declare class TaskGraphStore {
|
|
26
|
+
/** Primary node storage (hash map for O(1) lookup) */
|
|
27
|
+
private _nodes;
|
|
28
|
+
/** Outgoing edges: node -> nodes it points to */
|
|
29
|
+
private _outgoingEdges;
|
|
30
|
+
/** Incoming edges: node -> nodes pointing to it */
|
|
31
|
+
private _incomingEdges;
|
|
32
|
+
/** Graph metadata */
|
|
33
|
+
private _metadata;
|
|
34
|
+
/**
|
|
35
|
+
* Create a new TaskGraphStore
|
|
36
|
+
* @param metadata - Optional project metadata
|
|
37
|
+
*/
|
|
38
|
+
constructor(metadata?: ProjectMetadata);
|
|
39
|
+
/**
|
|
40
|
+
* Get the number of tasks in the graph
|
|
41
|
+
*/
|
|
42
|
+
get size(): number;
|
|
43
|
+
/**
|
|
44
|
+
* Get the graph metadata
|
|
45
|
+
*/
|
|
46
|
+
get metadata(): ProjectMetadata;
|
|
47
|
+
/**
|
|
48
|
+
* Update graph metadata
|
|
49
|
+
* @param metadata - New metadata values (partial update)
|
|
50
|
+
*/
|
|
51
|
+
setMetadata(metadata: Partial<ProjectMetadata>): void;
|
|
52
|
+
/**
|
|
53
|
+
* Get a task node by ID
|
|
54
|
+
* @param id - Task ID to look up
|
|
55
|
+
* @returns Task node or undefined if not found
|
|
56
|
+
* @complexity O(1)
|
|
57
|
+
*/
|
|
58
|
+
getNode(id: string): TaskNode | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Get a task node by ID or throw error
|
|
61
|
+
* @param id - Task ID to look up
|
|
62
|
+
* @returns Task node
|
|
63
|
+
* @throws {TaskNotFoundError} If task not found
|
|
64
|
+
* @complexity O(1)
|
|
65
|
+
*/
|
|
66
|
+
getNodeOrThrow(id: string): TaskNode;
|
|
67
|
+
/**
|
|
68
|
+
* Check if a task exists
|
|
69
|
+
* @param id - Task ID to check
|
|
70
|
+
* @returns True if task exists
|
|
71
|
+
* @complexity O(1)
|
|
72
|
+
*/
|
|
73
|
+
hasNode(id: string): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Get a task node by short UUID prefix (first 7-8 characters)
|
|
76
|
+
* @param prefix - Short UUID prefix to look up
|
|
77
|
+
* @returns Task node or undefined if not found
|
|
78
|
+
* @throws {AmbiguousIdError} If multiple tasks match the prefix
|
|
79
|
+
* @complexity O(n) where n is the number of tasks
|
|
80
|
+
*/
|
|
81
|
+
getNodeByPrefix(prefix: string): TaskNode | undefined;
|
|
82
|
+
/**
|
|
83
|
+
* Get a task node by ID or prefix
|
|
84
|
+
* @param id - Task ID or short UUID prefix to look up
|
|
85
|
+
* @returns Task node or undefined if not found
|
|
86
|
+
* @complexity O(1) for full ID, O(n) for prefix
|
|
87
|
+
*/
|
|
88
|
+
getNodeByIdOrPrefix(id: string): TaskNode | undefined;
|
|
89
|
+
/**
|
|
90
|
+
* Generate a unique task ID with collision detection
|
|
91
|
+
* Ensures that the first 7 characters of the UUID are unique across all tasks
|
|
92
|
+
* @returns A unique task ID
|
|
93
|
+
* @throws {Error} If unable to generate unique ID after many attempts
|
|
94
|
+
*/
|
|
95
|
+
generateUniqueId(): string;
|
|
96
|
+
/**
|
|
97
|
+
* Get all task IDs in the graph
|
|
98
|
+
* @returns Array of task IDs
|
|
99
|
+
*/
|
|
100
|
+
getAllTaskIds(): string[];
|
|
101
|
+
/**
|
|
102
|
+
* Get all task nodes in the graph
|
|
103
|
+
* @returns Array of task nodes
|
|
104
|
+
*/
|
|
105
|
+
getAllTasks(): TaskNode[];
|
|
106
|
+
/**
|
|
107
|
+
* Add a task node to the graph
|
|
108
|
+
* @param node - Task node to add
|
|
109
|
+
* @throws {ValidationError} If task ID already exists
|
|
110
|
+
* @complexity O(1)
|
|
111
|
+
*/
|
|
112
|
+
addNode(node: TaskNode): void;
|
|
113
|
+
/**
|
|
114
|
+
* Remove a task node from the graph
|
|
115
|
+
* @param id - Task ID to remove
|
|
116
|
+
* @throws {TaskNotFoundError} If task not found
|
|
117
|
+
* @complexity O(k) where k is the number of edges
|
|
118
|
+
*/
|
|
119
|
+
removeNode(id: string): void;
|
|
120
|
+
/**
|
|
121
|
+
* Update a task node in the graph
|
|
122
|
+
* @param node - Task node with updated values
|
|
123
|
+
* @throws {TaskNotFoundError} If task not found
|
|
124
|
+
* @complexity O(1)
|
|
125
|
+
*/
|
|
126
|
+
updateNode(node: TaskNode): void;
|
|
127
|
+
/**
|
|
128
|
+
* Get outgoing edges for a node
|
|
129
|
+
* @param nodeId - Source task ID
|
|
130
|
+
* @returns Array of target task IDs
|
|
131
|
+
* @complexity O(k) where k is the number of outgoing edges
|
|
132
|
+
*/
|
|
133
|
+
getOutgoingEdges(nodeId: string): string[];
|
|
134
|
+
/**
|
|
135
|
+
* Get incoming edges for a node
|
|
136
|
+
* @param nodeId - Target task ID
|
|
137
|
+
* @returns Array of source task IDs
|
|
138
|
+
* @complexity O(k) where k is the number of incoming edges
|
|
139
|
+
*/
|
|
140
|
+
getIncomingEdges(nodeId: string): string[];
|
|
141
|
+
/**
|
|
142
|
+
* Add an edge between two nodes
|
|
143
|
+
* @param fromId - Source task ID
|
|
144
|
+
* @param toId - Target task ID
|
|
145
|
+
* @throws {TaskNotFoundError} If either task not found
|
|
146
|
+
* @throws {ValidationError} If edge already exists
|
|
147
|
+
* @complexity O(1)
|
|
148
|
+
*/
|
|
149
|
+
addEdge(fromId: string, toId: string): void;
|
|
150
|
+
/**
|
|
151
|
+
* Remove an edge between two nodes
|
|
152
|
+
* @param fromId - Source task ID
|
|
153
|
+
* @param toId - Target task ID
|
|
154
|
+
* @throws {TaskNotFoundError} If either task not found
|
|
155
|
+
* @throws {ValidationError} If edge doesn't exist
|
|
156
|
+
* @complexity O(1)
|
|
157
|
+
*/
|
|
158
|
+
removeEdge(fromId: string, toId: string): void;
|
|
159
|
+
/**
|
|
160
|
+
* Check if an edge exists
|
|
161
|
+
* @param fromId - Source task ID
|
|
162
|
+
* @param toId - Target task ID
|
|
163
|
+
* @returns True if edge exists
|
|
164
|
+
* @complexity O(1)
|
|
165
|
+
*/
|
|
166
|
+
hasEdge(fromId: string, toId: string): boolean;
|
|
167
|
+
/**
|
|
168
|
+
* Get root tasks (tasks with no incoming edges)
|
|
169
|
+
* @returns Array of root task IDs
|
|
170
|
+
* @complexity O(n) where n is the number of tasks
|
|
171
|
+
*/
|
|
172
|
+
getRootTasks(): string[];
|
|
173
|
+
/**
|
|
174
|
+
* Get orphan tasks (tasks with no edges at all)
|
|
175
|
+
* @returns Array of orphan task IDs
|
|
176
|
+
* @complexity O(n) where n is the number of tasks
|
|
177
|
+
*/
|
|
178
|
+
getOrphanTasks(): string[];
|
|
179
|
+
/**
|
|
180
|
+
* Get leaf tasks (tasks with no outgoing edges)
|
|
181
|
+
* @returns Array of leaf task IDs
|
|
182
|
+
* @complexity O(n) where n is the number of tasks
|
|
183
|
+
*/
|
|
184
|
+
getLeafTasks(): string[];
|
|
185
|
+
/**
|
|
186
|
+
* Clear all tasks and edges from the graph
|
|
187
|
+
* Keeps metadata but resets the graph structure
|
|
188
|
+
*/
|
|
189
|
+
clear(): void;
|
|
190
|
+
/**
|
|
191
|
+
* Convert graph to TaskGraph interface
|
|
192
|
+
* @returns TaskGraph interface representation
|
|
193
|
+
*/
|
|
194
|
+
toInterface(): TaskGraph;
|
|
195
|
+
/**
|
|
196
|
+
* Create TaskGraphStore from TaskGraph interface
|
|
197
|
+
* @param graph - TaskGraph interface
|
|
198
|
+
* @returns New TaskGraphStore instance
|
|
199
|
+
*/
|
|
200
|
+
static fromInterface(graph: TaskGraph): TaskGraphStore;
|
|
201
|
+
/**
|
|
202
|
+
* Serialize graph to JSON-compatible object
|
|
203
|
+
* @returns JSON-serializable object
|
|
204
|
+
*/
|
|
205
|
+
toJSON(): {
|
|
206
|
+
nodes: Record<string, TaskNode>;
|
|
207
|
+
outgoingEdges: Record<string, string[]>;
|
|
208
|
+
incomingEdges: Record<string, string[]>;
|
|
209
|
+
metadata: ProjectMetadata;
|
|
210
|
+
};
|
|
211
|
+
/**
|
|
212
|
+
* Deserialize graph from JSON object
|
|
213
|
+
* @param json - JSON object from toJSON()
|
|
214
|
+
* @returns New TaskGraphStore instance
|
|
215
|
+
*/
|
|
216
|
+
static fromJSON(json: {
|
|
217
|
+
nodes: Record<string, TaskNode>;
|
|
218
|
+
outgoingEdges: Record<string, string[]>;
|
|
219
|
+
incomingEdges: Record<string, string[]>;
|
|
220
|
+
metadata: ProjectMetadata;
|
|
221
|
+
}): TaskGraphStore;
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/graph/index.ts"],"names":[],"mappings":"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"}
|