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,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph topological sort algorithms
|
|
3
|
+
*
|
|
4
|
+
* Implements Kahn's algorithm for topological sorting with cycle detection.
|
|
5
|
+
* Time complexity: O(V + E) where V = vertices, E = edges
|
|
6
|
+
*
|
|
7
|
+
* @module core/graph/sort
|
|
8
|
+
*/
|
|
9
|
+
import { CircularDependencyError } from '../../types/index.js';
|
|
10
|
+
/** Cache for topological sort results */
|
|
11
|
+
const sortCache = new Map();
|
|
12
|
+
/** Cache TTL in milliseconds (5 seconds) */
|
|
13
|
+
const CACHE_TTL = 5000;
|
|
14
|
+
/**
|
|
15
|
+
* Generate a cache key for the graph
|
|
16
|
+
* @param graph - Task graph store
|
|
17
|
+
* @returns Cache key string
|
|
18
|
+
*/
|
|
19
|
+
function generateCacheKey(graph) {
|
|
20
|
+
const taskIds = graph.getAllTaskIds().sort().join(',');
|
|
21
|
+
const metadata = graph.metadata;
|
|
22
|
+
return `${metadata.project_name}:${metadata.version}:${taskIds}:${graph.size}`;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Clear the topological sort cache
|
|
26
|
+
* Call this after modifying the graph structure
|
|
27
|
+
*/
|
|
28
|
+
export function clearSortCache() {
|
|
29
|
+
sortCache.clear();
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Perform topological sort using Kahn's algorithm
|
|
33
|
+
*
|
|
34
|
+
* Algorithm steps:
|
|
35
|
+
* 1. Calculate in-degree for all nodes
|
|
36
|
+
* 2. Initialize queue with nodes having zero in-degree
|
|
37
|
+
* 3. Process queue: remove node, add to result, reduce neighbors' in-degree
|
|
38
|
+
* 4. Add any neighbors with zero in-degree to queue
|
|
39
|
+
* 5. Detect cycle if result doesn't contain all nodes
|
|
40
|
+
*
|
|
41
|
+
* Time Complexity: O(V + E)
|
|
42
|
+
* Space Complexity: O(V)
|
|
43
|
+
*
|
|
44
|
+
* @param graph - Task graph store
|
|
45
|
+
* @param useCache - Whether to use memoization cache (default: true)
|
|
46
|
+
* @returns Topological sort result with sorted order and cycle detection
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* const result = topologicalSort(graph);
|
|
51
|
+
* if (result.hasCycle) {
|
|
52
|
+
* console.error('Cycle detected:', result.cycleNodes);
|
|
53
|
+
* } else {
|
|
54
|
+
* console.log('Execution order:', result.sorted);
|
|
55
|
+
* }
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export function topologicalSort(graph, useCache = true) {
|
|
59
|
+
// Check cache
|
|
60
|
+
if (useCache) {
|
|
61
|
+
const cacheKey = generateCacheKey(graph);
|
|
62
|
+
const cached = sortCache.get(cacheKey);
|
|
63
|
+
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
|
|
64
|
+
return cached.result;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const result = kahnSort(graph);
|
|
68
|
+
// Update cache
|
|
69
|
+
if (useCache) {
|
|
70
|
+
const cacheKey = generateCacheKey(graph);
|
|
71
|
+
sortCache.set(cacheKey, { result, timestamp: Date.now() });
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Internal implementation of Kahn's algorithm
|
|
77
|
+
* @param graph - Task graph store
|
|
78
|
+
* @returns Topological sort result
|
|
79
|
+
*/
|
|
80
|
+
function kahnSort(graph) {
|
|
81
|
+
// Step 1: Initialize in-degree map
|
|
82
|
+
const inDegree = new Map();
|
|
83
|
+
const allTaskIds = graph.getAllTaskIds();
|
|
84
|
+
for (const taskId of allTaskIds) {
|
|
85
|
+
inDegree.set(taskId, 0);
|
|
86
|
+
}
|
|
87
|
+
// Step 2: Calculate in-degrees from outgoing edges
|
|
88
|
+
for (const taskId of allTaskIds) {
|
|
89
|
+
const outgoingEdges = graph.getOutgoingEdges(taskId);
|
|
90
|
+
for (const targetId of outgoingEdges) {
|
|
91
|
+
inDegree.set(targetId, (inDegree.get(targetId) || 0) + 1);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Step 3: Initialize queue with zero in-degree nodes
|
|
95
|
+
const queue = [];
|
|
96
|
+
for (const [taskId, degree] of inDegree) {
|
|
97
|
+
if (degree === 0) {
|
|
98
|
+
queue.push(taskId);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Step 4: Process queue
|
|
102
|
+
const sorted = [];
|
|
103
|
+
while (queue.length > 0) {
|
|
104
|
+
// Remove first node from queue
|
|
105
|
+
const nodeId = queue.shift();
|
|
106
|
+
sorted.push(nodeId);
|
|
107
|
+
// Reduce in-degree of all neighbors
|
|
108
|
+
const neighbors = graph.getOutgoingEdges(nodeId);
|
|
109
|
+
for (const neighbor of neighbors) {
|
|
110
|
+
const newDegree = (inDegree.get(neighbor) || 0) - 1;
|
|
111
|
+
inDegree.set(neighbor, newDegree);
|
|
112
|
+
// Add to queue if in-degree becomes zero
|
|
113
|
+
if (newDegree === 0) {
|
|
114
|
+
queue.push(neighbor);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Step 5: Detect cycle
|
|
119
|
+
const hasCycle = sorted.length !== graph.size;
|
|
120
|
+
const cycleNodes = hasCycle
|
|
121
|
+
? allTaskIds.filter(id => !sorted.includes(id))
|
|
122
|
+
: [];
|
|
123
|
+
return {
|
|
124
|
+
sorted,
|
|
125
|
+
hasCycle,
|
|
126
|
+
cycleNodes,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Find the critical path (longest path) in the DAG
|
|
131
|
+
* Uses topological sort and dynamic programming
|
|
132
|
+
*
|
|
133
|
+
* Time Complexity: O(V + E)
|
|
134
|
+
*
|
|
135
|
+
* @param graph - Task graph store
|
|
136
|
+
* @param taskDuration - Duration for each task (default: 1)
|
|
137
|
+
* @returns Object with path array and total duration
|
|
138
|
+
* @throws {CircularDependencyError} If graph contains cycles
|
|
139
|
+
*/
|
|
140
|
+
export function findCriticalPath(graph, taskDuration = 1) {
|
|
141
|
+
// First, verify no cycles exist
|
|
142
|
+
const sortResult = topologicalSort(graph, false);
|
|
143
|
+
if (sortResult.hasCycle) {
|
|
144
|
+
throw new CircularDependencyError(sortResult.cycleNodes);
|
|
145
|
+
}
|
|
146
|
+
// Calculate earliest start times using DP
|
|
147
|
+
const earliestStart = new Map();
|
|
148
|
+
const getDuration = typeof taskDuration === 'number'
|
|
149
|
+
? () => taskDuration
|
|
150
|
+
: (id) => taskDuration.get(id) || 1;
|
|
151
|
+
// Initialize all start times to 0
|
|
152
|
+
for (const taskId of graph.getAllTaskIds()) {
|
|
153
|
+
earliestStart.set(taskId, 0);
|
|
154
|
+
}
|
|
155
|
+
// Process in topological order
|
|
156
|
+
for (const nodeId of sortResult.sorted) {
|
|
157
|
+
const predecessors = graph.getIncomingEdges(nodeId);
|
|
158
|
+
const maxPredFinish = predecessors.length === 0
|
|
159
|
+
? 0
|
|
160
|
+
: Math.max(...predecessors.map(p => (earliestStart.get(p) || 0) + getDuration(p)));
|
|
161
|
+
earliestStart.set(nodeId, maxPredFinish);
|
|
162
|
+
}
|
|
163
|
+
// Find node with maximum finish time
|
|
164
|
+
let maxFinish = 0;
|
|
165
|
+
let endNode = '';
|
|
166
|
+
for (const [nodeId, start] of earliestStart) {
|
|
167
|
+
const finish = start + getDuration(nodeId);
|
|
168
|
+
if (finish > maxFinish) {
|
|
169
|
+
maxFinish = finish;
|
|
170
|
+
endNode = nodeId;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// Backtrack to find critical path
|
|
174
|
+
const criticalPath = [endNode];
|
|
175
|
+
let current = endNode;
|
|
176
|
+
while (true) {
|
|
177
|
+
const predecessors = graph.getIncomingEdges(current);
|
|
178
|
+
if (predecessors.length === 0)
|
|
179
|
+
break;
|
|
180
|
+
// Find predecessor on critical path
|
|
181
|
+
const currentStart = earliestStart.get(current) || 0;
|
|
182
|
+
const criticalPred = predecessors.find(p => {
|
|
183
|
+
const predFinish = (earliestStart.get(p) || 0) + getDuration(p);
|
|
184
|
+
return predFinish === currentStart;
|
|
185
|
+
});
|
|
186
|
+
if (!criticalPred)
|
|
187
|
+
break;
|
|
188
|
+
criticalPath.unshift(criticalPred);
|
|
189
|
+
current = criticalPred;
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
path: criticalPath,
|
|
193
|
+
duration: maxFinish,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Validate that a graph is a valid DAG
|
|
198
|
+
* Convenience wrapper around topologicalSort
|
|
199
|
+
*
|
|
200
|
+
* @param graph - Task graph store
|
|
201
|
+
* @returns true if graph is a valid DAG, false otherwise
|
|
202
|
+
*/
|
|
203
|
+
export function isValidDAG(graph) {
|
|
204
|
+
const result = topologicalSort(graph, false);
|
|
205
|
+
return !result.hasCycle;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Get task execution levels (parallelizable stages)
|
|
209
|
+
* Tasks at the same level have no dependencies between them
|
|
210
|
+
*
|
|
211
|
+
* @param graph - Task graph store
|
|
212
|
+
* @returns Array of task ID arrays (each level is a parallelizable stage)
|
|
213
|
+
* @throws {CircularDependencyError} If graph contains cycles
|
|
214
|
+
*/
|
|
215
|
+
export function getExecutionLevels(graph) {
|
|
216
|
+
const sortResult = topologicalSort(graph, false);
|
|
217
|
+
if (sortResult.hasCycle) {
|
|
218
|
+
const { CircularDependencyError } = require('../../types/index.js');
|
|
219
|
+
throw new CircularDependencyError(sortResult.cycleNodes);
|
|
220
|
+
}
|
|
221
|
+
const levels = [];
|
|
222
|
+
const inDegree = new Map();
|
|
223
|
+
const remaining = new Set(sortResult.sorted);
|
|
224
|
+
// Calculate initial in-degrees
|
|
225
|
+
for (const taskId of sortResult.sorted) {
|
|
226
|
+
inDegree.set(taskId, graph.getIncomingEdges(taskId).length);
|
|
227
|
+
}
|
|
228
|
+
// Process level by level
|
|
229
|
+
while (remaining.size > 0) {
|
|
230
|
+
const currentLevel = [];
|
|
231
|
+
// Find all nodes with zero in-degree from remaining nodes
|
|
232
|
+
for (const taskId of remaining) {
|
|
233
|
+
if ((inDegree.get(taskId) || 0) === 0) {
|
|
234
|
+
currentLevel.push(taskId);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
if (currentLevel.length === 0) {
|
|
238
|
+
// This shouldn't happen if graph is valid
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
levels.push(currentLevel);
|
|
242
|
+
// Remove current level and update in-degrees
|
|
243
|
+
for (const taskId of currentLevel) {
|
|
244
|
+
remaining.delete(taskId);
|
|
245
|
+
for (const neighbor of graph.getOutgoingEdges(taskId)) {
|
|
246
|
+
if (remaining.has(neighbor)) {
|
|
247
|
+
inDegree.set(neighbor, (inDegree.get(neighbor) || 0) - 1);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return levels;
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=sort.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sort.js","sourceRoot":"","sources":["../../../src/core/graph/sort.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph traversal algorithms
|
|
3
|
+
*
|
|
4
|
+
* Implements BFS and DFS traversal methods for path finding and
|
|
5
|
+
* reachable node discovery.
|
|
6
|
+
* Time complexity: O(V + E) where V = vertices, E = edges
|
|
7
|
+
*
|
|
8
|
+
* @module core/graph/traversal
|
|
9
|
+
*/
|
|
10
|
+
import type { TaskGraphStore } from './index.js';
|
|
11
|
+
/**
|
|
12
|
+
* Breadth-First Search traversal
|
|
13
|
+
*
|
|
14
|
+
* Explores nodes layer by layer, finding all reachable nodes from a start node.
|
|
15
|
+
* Useful for finding all descendants (forward) or ancestors (backward).
|
|
16
|
+
*
|
|
17
|
+
* Time Complexity: O(V + E) in worst case
|
|
18
|
+
* Space Complexity: O(V) for visited set and queue
|
|
19
|
+
*
|
|
20
|
+
* @param graph - Task graph store
|
|
21
|
+
* @param startId - Starting task ID
|
|
22
|
+
* @param direction - Traversal direction: 'forward' (outgoing) or 'backward' (incoming)
|
|
23
|
+
* @returns Array of reachable task IDs in order of discovery
|
|
24
|
+
* @throws {TaskNotFoundError} If start node doesn't exist
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* // Find all tasks that depend on the start task
|
|
29
|
+
* const descendants = bfsTraversal(graph, 'task-001', 'forward');
|
|
30
|
+
*
|
|
31
|
+
* // Find all tasks that the start task depends on
|
|
32
|
+
* const ancestors = bfsTraversal(graph, 'task-001', 'backward');
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare function bfsTraversal(graph: TaskGraphStore, startId: string, direction?: 'forward' | 'backward'): string[];
|
|
36
|
+
/**
|
|
37
|
+
* Depth-First Search to find path between two nodes
|
|
38
|
+
*
|
|
39
|
+
* Attempts to find a path from start to end using DFS with backtracking.
|
|
40
|
+
* Returns the first path found, or null if no path exists.
|
|
41
|
+
*
|
|
42
|
+
* Time Complexity: O(V + E) in worst case
|
|
43
|
+
* Space Complexity: O(V) for recursion stack and visited set
|
|
44
|
+
*
|
|
45
|
+
* @param graph - Task graph store
|
|
46
|
+
* @param startId - Starting task ID
|
|
47
|
+
* @param endId - Target task ID
|
|
48
|
+
* @param direction - Search direction: 'forward' (follow outgoing) or 'backward' (follow incoming)
|
|
49
|
+
* @returns Path array from start to end, or null if no path exists
|
|
50
|
+
* @throws {TaskNotFoundError} If either node doesn't exist
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* // Find path from task-001 to task-005
|
|
55
|
+
* const path = dfsFindPath(graph, 'task-001', 'task-005');
|
|
56
|
+
* if (path) {
|
|
57
|
+
* console.log('Path:', path.join(' -> '));
|
|
58
|
+
* // Output: Path: task-001 -> task-002 -> task-004 -> task-005
|
|
59
|
+
* }
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export declare function dfsFindPath(graph: TaskGraphStore, startId: string, endId: string, direction?: 'forward' | 'backward'): string[] | null;
|
|
63
|
+
/**
|
|
64
|
+
* Find all paths between two nodes
|
|
65
|
+
*
|
|
66
|
+
* Uses DFS to find all possible paths from start to end.
|
|
67
|
+
* Warning: Can be expensive on dense graphs with many paths.
|
|
68
|
+
*
|
|
69
|
+
* @param graph - Task graph store
|
|
70
|
+
* @param startId - Starting task ID
|
|
71
|
+
* @param endId - Target task ID
|
|
72
|
+
* @param direction - Search direction: 'forward' or 'backward'
|
|
73
|
+
* @param maxPaths - Maximum number of paths to find (default: 100, prevents explosion)
|
|
74
|
+
* @returns Array of paths (each path is an array of task IDs)
|
|
75
|
+
* @throws {TaskNotFoundError} If either node doesn't exist
|
|
76
|
+
*/
|
|
77
|
+
export declare function findAllPaths(graph: TaskGraphStore, startId: string, endId: string, direction?: 'forward' | 'backward', maxPaths?: number): string[][];
|
|
78
|
+
/**
|
|
79
|
+
* Get shortest path between two nodes using BFS
|
|
80
|
+
*
|
|
81
|
+
* BFS naturally finds the shortest path in unweighted graphs.
|
|
82
|
+
*
|
|
83
|
+
* @param graph - Task graph store
|
|
84
|
+
* @param startId - Starting task ID
|
|
85
|
+
* @param endId - Target task ID
|
|
86
|
+
* @param direction - Search direction: 'forward' or 'backward'
|
|
87
|
+
* @returns Shortest path array, or null if no path exists
|
|
88
|
+
* @throws {TaskNotFoundError} If either node doesn't exist
|
|
89
|
+
*/
|
|
90
|
+
export declare function findShortestPath(graph: TaskGraphStore, startId: string, endId: string, direction?: 'forward' | 'backward'): string[] | null;
|
|
91
|
+
/**
|
|
92
|
+
* Check if two nodes are connected (path exists)
|
|
93
|
+
*
|
|
94
|
+
* @param graph - Task graph store
|
|
95
|
+
* @param fromId - Source task ID
|
|
96
|
+
* @param toId - Target task ID
|
|
97
|
+
* @param direction - Search direction: 'forward' or 'backward'
|
|
98
|
+
* @returns true if a path exists between the nodes
|
|
99
|
+
*/
|
|
100
|
+
export declare function areConnected(graph: TaskGraphStore, fromId: string, toId: string, direction?: 'forward' | 'backward'): boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Get distance (number of edges) between two nodes
|
|
103
|
+
*
|
|
104
|
+
* @param graph - Task graph store
|
|
105
|
+
* @param fromId - Source task ID
|
|
106
|
+
* @param toId - Target task ID
|
|
107
|
+
* @param direction - Search direction: 'forward' or 'backward'
|
|
108
|
+
* @returns Number of edges in shortest path, or -1 if no path exists
|
|
109
|
+
*/
|
|
110
|
+
export declare function getDistance(graph: TaskGraphStore, fromId: string, toId: string, direction?: 'forward' | 'backward'): number;
|
|
111
|
+
/**
|
|
112
|
+
* Get connected components in the graph
|
|
113
|
+
*
|
|
114
|
+
* Identifies groups of nodes that are reachable from each other.
|
|
115
|
+
* For directed graphs, uses weakly connected components
|
|
116
|
+
* (treating edges as undirected).
|
|
117
|
+
*
|
|
118
|
+
* @param graph - Task graph store
|
|
119
|
+
* @returns Array of connected components (each is an array of task IDs)
|
|
120
|
+
*/
|
|
121
|
+
export declare function getConnectedComponents(graph: TaskGraphStore): string[][];
|
|
122
|
+
//# sourceMappingURL=traversal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traversal.d.ts","sourceRoot":"","sources":["../../../src/core/graph/traversal.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGjD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,SAAS,GAAG,UAAsB,GAC5C,MAAM,EAAE,CA4CV;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,SAAS,GAAG,UAAsB,GAC5C,MAAM,EAAE,GAAG,IAAI,CAyDjB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,SAAS,GAAG,UAAsB,EAC7C,QAAQ,SAAM,GACb,MAAM,EAAE,EAAE,CAsDZ;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,SAAS,GAAG,UAAsB,GAC5C,MAAM,EAAE,GAAG,IAAI,CA2CjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,SAAS,GAAE,SAAS,GAAG,UAAsB,GAC5C,OAAO,CAOT;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,SAAS,GAAE,SAAS,GAAG,UAAsB,GAC5C,MAAM,CAGR;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,EAAE,EAAE,CAyCxE"}
|