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.
Files changed (162) hide show
  1. package/README.md +523 -0
  2. package/dist/cli/commands/approve.d.ts +27 -0
  3. package/dist/cli/commands/approve.d.ts.map +1 -0
  4. package/dist/cli/commands/approve.js +119 -0
  5. package/dist/cli/commands/approve.js.map +1 -0
  6. package/dist/cli/commands/batch.d.ts +15 -0
  7. package/dist/cli/commands/batch.d.ts.map +1 -0
  8. package/dist/cli/commands/batch.js +521 -0
  9. package/dist/cli/commands/batch.js.map +1 -0
  10. package/dist/cli/commands/create.d.ts +9 -0
  11. package/dist/cli/commands/create.d.ts.map +1 -0
  12. package/dist/cli/commands/create.js +321 -0
  13. package/dist/cli/commands/create.js.map +1 -0
  14. package/dist/cli/commands/delete.d.ts +9 -0
  15. package/dist/cli/commands/delete.d.ts.map +1 -0
  16. package/dist/cli/commands/delete.js +143 -0
  17. package/dist/cli/commands/delete.js.map +1 -0
  18. package/dist/cli/commands/export.d.ts +9 -0
  19. package/dist/cli/commands/export.d.ts.map +1 -0
  20. package/dist/cli/commands/export.js +66 -0
  21. package/dist/cli/commands/export.js.map +1 -0
  22. package/dist/cli/commands/find.d.ts +16 -0
  23. package/dist/cli/commands/find.d.ts.map +1 -0
  24. package/dist/cli/commands/find.js +252 -0
  25. package/dist/cli/commands/find.js.map +1 -0
  26. package/dist/cli/commands/get.d.ts +9 -0
  27. package/dist/cli/commands/get.d.ts.map +1 -0
  28. package/dist/cli/commands/get.js +74 -0
  29. package/dist/cli/commands/get.js.map +1 -0
  30. package/dist/cli/commands/graph.d.ts +9 -0
  31. package/dist/cli/commands/graph.d.ts.map +1 -0
  32. package/dist/cli/commands/graph.js +200 -0
  33. package/dist/cli/commands/graph.js.map +1 -0
  34. package/dist/cli/commands/import.d.ts +9 -0
  35. package/dist/cli/commands/import.d.ts.map +1 -0
  36. package/dist/cli/commands/import.js +807 -0
  37. package/dist/cli/commands/import.js.map +1 -0
  38. package/dist/cli/commands/init.d.ts +9 -0
  39. package/dist/cli/commands/init.d.ts.map +1 -0
  40. package/dist/cli/commands/init.js +57 -0
  41. package/dist/cli/commands/init.js.map +1 -0
  42. package/dist/cli/commands/list.d.ts +9 -0
  43. package/dist/cli/commands/list.d.ts.map +1 -0
  44. package/dist/cli/commands/list.js +175 -0
  45. package/dist/cli/commands/list.js.map +1 -0
  46. package/dist/cli/commands/merge.d.ts +9 -0
  47. package/dist/cli/commands/merge.d.ts.map +1 -0
  48. package/dist/cli/commands/merge.js +113 -0
  49. package/dist/cli/commands/merge.js.map +1 -0
  50. package/dist/cli/commands/serve.d.ts +9 -0
  51. package/dist/cli/commands/serve.d.ts.map +1 -0
  52. package/dist/cli/commands/serve.js +94 -0
  53. package/dist/cli/commands/serve.js.map +1 -0
  54. package/dist/cli/commands/update.d.ts +9 -0
  55. package/dist/cli/commands/update.d.ts.map +1 -0
  56. package/dist/cli/commands/update.js +423 -0
  57. package/dist/cli/commands/update.js.map +1 -0
  58. package/dist/cli/commands/wire.d.ts +15 -0
  59. package/dist/cli/commands/wire.d.ts.map +1 -0
  60. package/dist/cli/commands/wire.js +164 -0
  61. package/dist/cli/commands/wire.js.map +1 -0
  62. package/dist/cli/index.d.ts +7 -0
  63. package/dist/cli/index.d.ts.map +1 -0
  64. package/dist/cli/index.js +100 -0
  65. package/dist/cli/index.js.map +1 -0
  66. package/dist/cli/output/json.d.ts +16 -0
  67. package/dist/cli/output/json.d.ts.map +1 -0
  68. package/dist/cli/output/json.js +29 -0
  69. package/dist/cli/output/json.js.map +1 -0
  70. package/dist/cli/output/markdown.d.ts +15 -0
  71. package/dist/cli/output/markdown.d.ts.map +1 -0
  72. package/dist/cli/output/markdown.js +206 -0
  73. package/dist/cli/output/markdown.js.map +1 -0
  74. package/dist/cli/output/table.d.ts +23 -0
  75. package/dist/cli/output/table.d.ts.map +1 -0
  76. package/dist/cli/output/table.js +150 -0
  77. package/dist/cli/output/table.js.map +1 -0
  78. package/dist/cli/utils/helpers.d.ts +126 -0
  79. package/dist/cli/utils/helpers.d.ts.map +1 -0
  80. package/dist/cli/utils/helpers.js +325 -0
  81. package/dist/cli/utils/helpers.js.map +1 -0
  82. package/dist/core/graph/algorithms.d.ts +11 -0
  83. package/dist/core/graph/algorithms.d.ts.map +1 -0
  84. package/dist/core/graph/algorithms.js +14 -0
  85. package/dist/core/graph/algorithms.js.map +1 -0
  86. package/dist/core/graph/cycle.d.ts +155 -0
  87. package/dist/core/graph/cycle.d.ts.map +1 -0
  88. package/dist/core/graph/cycle.js +297 -0
  89. package/dist/core/graph/cycle.js.map +1 -0
  90. package/dist/core/graph/index.d.ts +223 -0
  91. package/dist/core/graph/index.d.ts.map +1 -0
  92. package/dist/core/graph/index.js +475 -0
  93. package/dist/core/graph/index.js.map +1 -0
  94. package/dist/core/graph/operations.d.ts +240 -0
  95. package/dist/core/graph/operations.d.ts.map +1 -0
  96. package/dist/core/graph/operations.js +503 -0
  97. package/dist/core/graph/operations.js.map +1 -0
  98. package/dist/core/graph/sort.d.ts +76 -0
  99. package/dist/core/graph/sort.d.ts.map +1 -0
  100. package/dist/core/graph/sort.js +254 -0
  101. package/dist/core/graph/sort.js.map +1 -0
  102. package/dist/core/graph/traversal.d.ts +122 -0
  103. package/dist/core/graph/traversal.d.ts.map +1 -0
  104. package/dist/core/graph/traversal.js +336 -0
  105. package/dist/core/graph/traversal.js.map +1 -0
  106. package/dist/core/models/task-node.d.ts +328 -0
  107. package/dist/core/models/task-node.d.ts.map +1 -0
  108. package/dist/core/models/task-node.js +1090 -0
  109. package/dist/core/models/task-node.js.map +1 -0
  110. package/dist/core/registry/index.d.ts +102 -0
  111. package/dist/core/registry/index.d.ts.map +1 -0
  112. package/dist/core/registry/index.js +249 -0
  113. package/dist/core/registry/index.js.map +1 -0
  114. package/dist/core/registry/root-guard.d.ts +19 -0
  115. package/dist/core/registry/root-guard.d.ts.map +1 -0
  116. package/dist/core/registry/root-guard.js +28 -0
  117. package/dist/core/registry/root-guard.js.map +1 -0
  118. package/dist/core/storage/atomic-write.d.ts +181 -0
  119. package/dist/core/storage/atomic-write.d.ts.map +1 -0
  120. package/dist/core/storage/atomic-write.js +379 -0
  121. package/dist/core/storage/atomic-write.js.map +1 -0
  122. package/dist/core/storage/file-store.d.ts +148 -0
  123. package/dist/core/storage/file-store.d.ts.map +1 -0
  124. package/dist/core/storage/file-store.js +423 -0
  125. package/dist/core/storage/file-store.js.map +1 -0
  126. package/dist/core/storage/indexer.d.ts +138 -0
  127. package/dist/core/storage/indexer.d.ts.map +1 -0
  128. package/dist/core/storage/indexer.js +350 -0
  129. package/dist/core/storage/indexer.js.map +1 -0
  130. package/dist/core/utils/status-helpers.d.ts +59 -0
  131. package/dist/core/utils/status-helpers.d.ts.map +1 -0
  132. package/dist/core/utils/status-helpers.js +149 -0
  133. package/dist/core/utils/status-helpers.js.map +1 -0
  134. package/dist/index.d.ts +10 -0
  135. package/dist/index.d.ts.map +1 -0
  136. package/dist/index.js +10 -0
  137. package/dist/index.js.map +1 -0
  138. package/dist/types/index.d.ts +504 -0
  139. package/dist/types/index.d.ts.map +1 -0
  140. package/dist/types/index.js +182 -0
  141. package/dist/types/index.js.map +1 -0
  142. package/dist/web/routes/graph.d.ts +17 -0
  143. package/dist/web/routes/graph.d.ts.map +1 -0
  144. package/dist/web/routes/graph.js +277 -0
  145. package/dist/web/routes/graph.js.map +1 -0
  146. package/dist/web/routes/projects.d.ts +14 -0
  147. package/dist/web/routes/projects.d.ts.map +1 -0
  148. package/dist/web/routes/projects.js +102 -0
  149. package/dist/web/routes/projects.js.map +1 -0
  150. package/dist/web/routes/tasks.d.ts +17 -0
  151. package/dist/web/routes/tasks.d.ts.map +1 -0
  152. package/dist/web/routes/tasks.js +538 -0
  153. package/dist/web/routes/tasks.js.map +1 -0
  154. package/dist/web/server.d.ts +121 -0
  155. package/dist/web/server.d.ts.map +1 -0
  156. package/dist/web/server.js +389 -0
  157. package/dist/web/server.js.map +1 -0
  158. package/dist/web-ui/assets/index-BB0qvF1y.css +1 -0
  159. package/dist/web-ui/assets/index-Vmm72oKY.js +34 -0
  160. package/dist/web-ui/index.html +14 -0
  161. package/dist/web-ui/vite.svg +1 -0
  162. package/package.json +94 -0
@@ -0,0 +1,126 @@
1
+ /**
2
+ * CLI utility functions
3
+ */
4
+ import type { TaskGraphStore } from '../../core/graph/index.js';
5
+ /**
6
+ * Get the project path from options or auto-detect
7
+ */
8
+ export declare function getProjectPath(projectOption?: string): Promise<string>;
9
+ /**
10
+ * Load the project graph
11
+ */
12
+ export declare function loadGraph(projectPath: string): Promise<TaskGraphStore>;
13
+ /**
14
+ * Save the project graph
15
+ */
16
+ export declare function saveGraph(projectPath: string, graph: TaskGraphStore): Promise<void>;
17
+ /**
18
+ * Format success message
19
+ */
20
+ export declare function success(message: string): void;
21
+ /**
22
+ * Format error message
23
+ */
24
+ export declare function error(message: string): void;
25
+ /**
26
+ * Format warning message
27
+ */
28
+ export declare function warning(message: string): void;
29
+ /**
30
+ * Format info message
31
+ */
32
+ export declare function info(message: string): void;
33
+ /**
34
+ * Format verbose message (only shown if --verbose flag is set)
35
+ */
36
+ export declare function verbose(message: string, verbose: boolean): void;
37
+ /**
38
+ * Create a spinner for long-running operations
39
+ */
40
+ export declare function createSpinner(message: string, enabled: boolean): {
41
+ start: () => void;
42
+ stop: (finalMessage: string) => void;
43
+ fail: (finalMessage: string) => void;
44
+ };
45
+ /**
46
+ * Parse comma-separated list
47
+ */
48
+ export declare function parseList(value: string): string[];
49
+ /**
50
+ * Parse multiple IDs from various formats
51
+ * Supports:
52
+ * - "id1","id2","id3" (quoted CSV format)
53
+ * - id1,id2,id3 (simple comma-separated)
54
+ * - Single ID (backward compatible)
55
+ *
56
+ * Used with Commander.js collector pattern:
57
+ * .option('--ids <id>', 'IDs to process', parseMultipleIds, [])
58
+ */
59
+ export declare function parseMultipleIds(value: string, previous: string[]): string[];
60
+ /**
61
+ * Validate UUID format
62
+ */
63
+ export declare function isValidUUID(id: string): boolean;
64
+ /**
65
+ * Format task ID for display
66
+ */
67
+ export declare function formatTaskId(id: string): string;
68
+ /**
69
+ * Format status for display
70
+ */
71
+ export declare function formatStatus(status: string): string;
72
+ /**
73
+ * Format priority for display
74
+ */
75
+ export declare function formatPriority(priority: string): string;
76
+ /**
77
+ * Truncate text to fit width
78
+ */
79
+ export declare function truncate(text: string, maxWidth: number): string;
80
+ /**
81
+ * Format error for CLI output
82
+ * Provides consistent error formatting with code, message, and suggestion
83
+ */
84
+ export declare function formatError(error: unknown, verbose?: boolean): string;
85
+ /**
86
+ * Get suggestion for an error code
87
+ * Returns a suggestion string for the given error code
88
+ */
89
+ export declare function getErrorSuggestion(code: string): string | undefined;
90
+ /**
91
+ * Exit with error message
92
+ * Formats and displays error, then exits with code 1
93
+ */
94
+ export declare function exitWithError(error: unknown, verbose?: boolean): never;
95
+ /**
96
+ * Retry options for recovery operations
97
+ */
98
+ export interface RetryOptions {
99
+ /** Maximum number of retry attempts */
100
+ maxRetries: number;
101
+ /** Delay between retries in milliseconds */
102
+ delayMs: number;
103
+ /** Exponential backoff multiplier */
104
+ backoffMultiplier?: number;
105
+ /** Operation name for error messages */
106
+ operationName?: string;
107
+ }
108
+ /**
109
+ * Retry a function with exponential backoff
110
+ * Useful for file operations that may fail due to concurrent access
111
+ */
112
+ export declare function withRetry<T>(fn: () => Promise<T>, options: RetryOptions): Promise<T>;
113
+ /**
114
+ * Prompt user for confirmation
115
+ * Returns true if user confirms (y/yes), false otherwise
116
+ */
117
+ export declare function confirmPrompt(message: string): Promise<boolean>;
118
+ /**
119
+ * Attempt to recover from a corrupted project file
120
+ * Tries to restore from backup and provides actionable suggestions
121
+ */
122
+ export declare function attemptRecovery(projectPath: string): Promise<{
123
+ success: boolean;
124
+ message: string;
125
+ }>;
126
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,325 @@
1
+ /**
2
+ * CLI utility functions
3
+ */
4
+ import chalk from 'chalk';
5
+ import path from 'node:path';
6
+ import { findProjectPath, TaskStorage } from '../../core/storage/file-store.js';
7
+ import { OctieError, ERROR_SUGGESTIONS } from '../../types/index.js';
8
+ /**
9
+ * Get the project path from options or auto-detect
10
+ */
11
+ export async function getProjectPath(projectOption) {
12
+ if (projectOption) {
13
+ return path.resolve(projectOption);
14
+ }
15
+ // Auto-detect project path
16
+ const detectedPath = await findProjectPath();
17
+ if (detectedPath) {
18
+ return detectedPath;
19
+ }
20
+ throw new Error('No Octie project found. Run `octie init` first or specify --project <path>');
21
+ }
22
+ /**
23
+ * Load the project graph
24
+ */
25
+ export async function loadGraph(projectPath) {
26
+ const storage = new TaskStorage({ projectDir: projectPath });
27
+ if (!(await storage.exists())) {
28
+ throw new Error(`No Octie project found at ${projectPath}`);
29
+ }
30
+ return await storage.load();
31
+ }
32
+ /**
33
+ * Save the project graph
34
+ */
35
+ export async function saveGraph(projectPath, graph) {
36
+ const storage = new TaskStorage({ projectDir: projectPath });
37
+ await storage.save(graph);
38
+ }
39
+ /**
40
+ * Format success message
41
+ */
42
+ export function success(message) {
43
+ console.log(chalk.green('✓'), message);
44
+ }
45
+ /**
46
+ * Format error message
47
+ */
48
+ export function error(message) {
49
+ console.error(chalk.red('✗'), message);
50
+ }
51
+ /**
52
+ * Format warning message
53
+ */
54
+ export function warning(message) {
55
+ console.warn(chalk.yellow('⚠'), message);
56
+ }
57
+ /**
58
+ * Format info message
59
+ */
60
+ export function info(message) {
61
+ console.log(chalk.blue('ℹ'), message);
62
+ }
63
+ /**
64
+ * Format verbose message (only shown if --verbose flag is set)
65
+ */
66
+ export function verbose(message, verbose) {
67
+ if (verbose) {
68
+ console.log(chalk.gray(message));
69
+ }
70
+ }
71
+ /**
72
+ * Create a spinner for long-running operations
73
+ */
74
+ export function createSpinner(message, enabled) {
75
+ // Simple spinner implementation
76
+ let dots = 0;
77
+ let interval = null;
78
+ return {
79
+ start: () => {
80
+ if (!enabled)
81
+ return;
82
+ process.stdout.write(`\r${chalk.cyan('○')} ${message}`);
83
+ interval = setInterval(() => {
84
+ dots = (dots + 1) % 4;
85
+ const dotStr = '.'.repeat(dots);
86
+ process.stdout.write(`\r${chalk.cyan('○')} ${message}${dotStr}`);
87
+ }, 100);
88
+ },
89
+ stop: (finalMessage) => {
90
+ if (interval) {
91
+ clearInterval(interval);
92
+ interval = null;
93
+ }
94
+ if (enabled) {
95
+ process.stdout.write(`\r${chalk.green('✓')} ${finalMessage}\n`);
96
+ }
97
+ },
98
+ fail: (finalMessage) => {
99
+ if (interval) {
100
+ clearInterval(interval);
101
+ interval = null;
102
+ }
103
+ if (enabled) {
104
+ process.stdout.write(`\r${chalk.red('✗')} ${finalMessage}\n`);
105
+ }
106
+ },
107
+ };
108
+ }
109
+ /**
110
+ * Parse comma-separated list
111
+ */
112
+ export function parseList(value) {
113
+ if (!value)
114
+ return [];
115
+ return value.split(',').map(item => item.trim()).filter(Boolean);
116
+ }
117
+ /**
118
+ * Parse multiple IDs from various formats
119
+ * Supports:
120
+ * - "id1","id2","id3" (quoted CSV format)
121
+ * - id1,id2,id3 (simple comma-separated)
122
+ * - Single ID (backward compatible)
123
+ *
124
+ * Used with Commander.js collector pattern:
125
+ * .option('--ids <id>', 'IDs to process', parseMultipleIds, [])
126
+ */
127
+ export function parseMultipleIds(value, previous) {
128
+ if (!value)
129
+ return previous;
130
+ // Check for quoted CSV format: "id1","id2","id3"
131
+ // This happens when user wraps in quotes to prevent shell parsing
132
+ const quotedCsvMatch = value.match(/^"([^"]+)"(?:,"([^"]+)")*/);
133
+ if (quotedCsvMatch) {
134
+ // Extract all quoted values
135
+ const quotedValues = value.match(/"([^"]+)"/g);
136
+ if (quotedValues) {
137
+ const ids = quotedValues.map(v => v.replace(/"/g, '').trim()).filter(Boolean);
138
+ return previous.concat(ids);
139
+ }
140
+ }
141
+ // Fall back to simple comma-separated: id1,id2,id3
142
+ if (value.includes(',')) {
143
+ const ids = value.split(',').map(item => item.trim()).filter(Boolean);
144
+ return previous.concat(ids);
145
+ }
146
+ // Single ID (backward compatible)
147
+ return previous.concat([value.trim()]);
148
+ }
149
+ /**
150
+ * Validate UUID format
151
+ */
152
+ export function isValidUUID(id) {
153
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
154
+ return uuidRegex.test(id);
155
+ }
156
+ /**
157
+ * Format task ID for display
158
+ */
159
+ export function formatTaskId(id) {
160
+ return chalk.cyan(id);
161
+ }
162
+ /**
163
+ * Format status for display
164
+ */
165
+ export function formatStatus(status) {
166
+ const statusColors = {
167
+ ready: chalk.cyan,
168
+ in_progress: chalk.blue,
169
+ in_review: chalk.magenta,
170
+ completed: chalk.green,
171
+ blocked: chalk.red,
172
+ // Legacy status support (for backward compatibility with old data)
173
+ not_started: chalk.gray,
174
+ pending: chalk.yellow,
175
+ };
176
+ const colorFn = statusColors[status] || chalk.white;
177
+ return colorFn(status.replace('_', ' '));
178
+ }
179
+ /**
180
+ * Format priority for display
181
+ */
182
+ export function formatPriority(priority) {
183
+ const priorityColors = {
184
+ top: chalk.red,
185
+ second: chalk.yellow,
186
+ later: chalk.gray,
187
+ };
188
+ const colorFn = priorityColors[priority] || chalk.white;
189
+ return colorFn(priority);
190
+ }
191
+ /**
192
+ * Truncate text to fit width
193
+ */
194
+ export function truncate(text, maxWidth) {
195
+ if (text.length <= maxWidth)
196
+ return text;
197
+ return text.substring(0, maxWidth - 3) + '...';
198
+ }
199
+ /**
200
+ * Format error for CLI output
201
+ * Provides consistent error formatting with code, message, and suggestion
202
+ */
203
+ export function formatError(error, verbose = false) {
204
+ // Handle OctieError with suggestion
205
+ if (error instanceof OctieError) {
206
+ const lines = [];
207
+ // Error header with code
208
+ lines.push(chalk.red.bold(`Error [${error.code}]:`) + ' ' + chalk.red(error.message));
209
+ // Add suggestion if available
210
+ if (error.suggestion) {
211
+ lines.push('');
212
+ lines.push(chalk.yellow('Suggestion:') + ' ' + error.suggestion);
213
+ }
214
+ // Add stack trace in verbose mode
215
+ if (verbose && error.stack) {
216
+ lines.push('');
217
+ lines.push(chalk.gray('Stack trace:'));
218
+ lines.push(chalk.gray(error.stack.split('\n').slice(1).join('\n')));
219
+ }
220
+ return lines.join('\n');
221
+ }
222
+ // Handle standard Error
223
+ if (error instanceof Error) {
224
+ const lines = [];
225
+ lines.push(chalk.red.bold('Error:') + ' ' + chalk.red(error.message));
226
+ if (verbose && error.stack) {
227
+ lines.push('');
228
+ lines.push(chalk.gray('Stack trace:'));
229
+ lines.push(chalk.gray(error.stack.split('\n').slice(1).join('\n')));
230
+ }
231
+ return lines.join('\n');
232
+ }
233
+ // Handle unknown error types
234
+ return chalk.red.bold('Error:') + ' ' + chalk.red(String(error));
235
+ }
236
+ /**
237
+ * Get suggestion for an error code
238
+ * Returns a suggestion string for the given error code
239
+ */
240
+ export function getErrorSuggestion(code) {
241
+ return ERROR_SUGGESTIONS[code];
242
+ }
243
+ /**
244
+ * Exit with error message
245
+ * Formats and displays error, then exits with code 1
246
+ */
247
+ export function exitWithError(error, verbose = false) {
248
+ console.error(formatError(error, verbose));
249
+ process.exit(1);
250
+ }
251
+ /**
252
+ * Retry a function with exponential backoff
253
+ * Useful for file operations that may fail due to concurrent access
254
+ */
255
+ export async function withRetry(fn, options) {
256
+ const { maxRetries, delayMs, backoffMultiplier = 2, operationName = 'operation' } = options;
257
+ let lastError;
258
+ let currentDelay = delayMs;
259
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
260
+ try {
261
+ return await fn();
262
+ }
263
+ catch (error) {
264
+ lastError = error instanceof Error ? error : new Error(String(error));
265
+ if (attempt < maxRetries) {
266
+ if (process.env.VERBOSE === 'true') {
267
+ console.log(chalk.yellow(`Retry ${attempt}/${maxRetries} for ${operationName} after ${currentDelay}ms...`));
268
+ }
269
+ await new Promise(resolve => setTimeout(resolve, currentDelay));
270
+ currentDelay *= backoffMultiplier;
271
+ }
272
+ }
273
+ }
274
+ throw new Error(`${operationName} failed after ${maxRetries} attempts. Last error: ${lastError?.message}`);
275
+ }
276
+ /**
277
+ * Prompt user for confirmation
278
+ * Returns true if user confirms (y/yes), false otherwise
279
+ */
280
+ export async function confirmPrompt(message) {
281
+ const readline = await import('node:readline/promises');
282
+ const { stdin, stdout } = await import('node:process');
283
+ const rl = readline.createInterface({
284
+ input: stdin,
285
+ output: stdout,
286
+ });
287
+ try {
288
+ const answer = await rl.question(message + ' ');
289
+ const normalized = answer.trim().toLowerCase();
290
+ return normalized === 'y' || normalized === 'yes';
291
+ }
292
+ finally {
293
+ rl.close();
294
+ }
295
+ }
296
+ /**
297
+ * Attempt to recover from a corrupted project file
298
+ * Tries to restore from backup and provides actionable suggestions
299
+ */
300
+ export async function attemptRecovery(projectPath) {
301
+ const storage = new TaskStorage({ projectDir: projectPath });
302
+ try {
303
+ // Check if backup exists
304
+ const backups = await storage.listBackups();
305
+ if (backups.length === 0) {
306
+ return {
307
+ success: false,
308
+ message: 'No backup files available for recovery. You may need to re-initialize the project.',
309
+ };
310
+ }
311
+ // Attempt to restore
312
+ await storage.restoreFromBackup();
313
+ return {
314
+ success: true,
315
+ message: `Successfully restored from backup: ${backups[0]}`,
316
+ };
317
+ }
318
+ catch (error) {
319
+ return {
320
+ success: false,
321
+ message: `Recovery failed: ${error instanceof Error ? error.message : String(error)}`,
322
+ };
323
+ }
324
+ }
325
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/cli/utils/helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Graph algorithms entry point
3
+ *
4
+ * Exports all graph algorithm functions for convenient importing.
5
+ *
6
+ * @module core/graph/algorithms
7
+ */
8
+ export { topologicalSort, findCriticalPath, isValidDAG, getExecutionLevels, clearSortCache, } from './sort.js';
9
+ export { detectCycle, hasCycle, getCyclicNodes, findShortestCycle, findCyclesForTask, validateAcyclic, getCycleStatistics, wouldCreateCycle, } from './cycle.js';
10
+ export { bfsTraversal, dfsFindPath, findAllPaths, findShortestPath, areConnected, getDistance, getConnectedComponents, } from './traversal.js';
11
+ //# sourceMappingURL=algorithms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"algorithms.d.ts","sourceRoot":"","sources":["../../../src/core/graph/algorithms.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,kBAAkB,EAClB,cAAc,GACf,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,WAAW,EACX,QAAQ,EACR,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,sBAAsB,GACvB,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Graph algorithms entry point
3
+ *
4
+ * Exports all graph algorithm functions for convenient importing.
5
+ *
6
+ * @module core/graph/algorithms
7
+ */
8
+ // Topological sort
9
+ export { topologicalSort, findCriticalPath, isValidDAG, getExecutionLevels, clearSortCache, } from './sort.js';
10
+ // Cycle detection
11
+ export { detectCycle, hasCycle, getCyclicNodes, findShortestCycle, findCyclesForTask, validateAcyclic, getCycleStatistics, wouldCreateCycle, } from './cycle.js';
12
+ // Traversal
13
+ export { bfsTraversal, dfsFindPath, findAllPaths, findShortestPath, areConnected, getDistance, getConnectedComponents, } from './traversal.js';
14
+ //# sourceMappingURL=algorithms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"algorithms.js","sourceRoot":"","sources":["../../../src/core/graph/algorithms.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,mBAAmB;AACnB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,kBAAkB,EAClB,cAAc,GACf,MAAM,WAAW,CAAC;AAEnB,kBAAkB;AAClB,OAAO,EACL,WAAW,EACX,QAAQ,EACR,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAEpB,YAAY;AACZ,OAAO,EACL,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,sBAAsB,GACvB,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,155 @@
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 type { TaskGraphStore } from './index.js';
11
+ import type { CycleDetectionResult } from '../../types/index.js';
12
+ /**
13
+ * Detect cycles using DFS with three-color marking
14
+ *
15
+ * Algorithm:
16
+ * 1. Mark all nodes as WHITE (unvisited)
17
+ * 2. For each WHITE node, start DFS traversal
18
+ * 3. Mark node as GRAY when entering, BLACK when exiting
19
+ * 4. If we encounter a GRAY node during traversal, we found a cycle
20
+ * 5. Check for self-loops (task blocking itself) before DFS
21
+ * 6. Reconstruct cycle path using parent pointers
22
+ *
23
+ * Time Complexity: O(V + E)
24
+ * Space Complexity: O(V) for recursion stack and state tracking
25
+ *
26
+ * @param graph - Task graph store
27
+ * @returns Cycle detection result with all detected cycles
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * const result = detectCycle(graph);
32
+ * if (result.hasCycle) {
33
+ * console.error('Found cycles:', result.cycles);
34
+ * for (const cycle of result.cycles) {
35
+ * console.error('Cycle:', cycle.join(' -> '));
36
+ * }
37
+ * }
38
+ * ```
39
+ */
40
+ export declare function detectCycle(graph: TaskGraphStore): CycleDetectionResult;
41
+ /**
42
+ * Check if a graph contains any cycles
43
+ * Convenience function that returns a boolean
44
+ *
45
+ * @param graph - Task graph store
46
+ * @returns true if graph contains at least one cycle
47
+ */
48
+ export declare function hasCycle(graph: TaskGraphStore): boolean;
49
+ /**
50
+ * Get all nodes involved in cycles
51
+ *
52
+ * @param graph - Task graph store
53
+ * @returns Set of task IDs that are part of at least one cycle
54
+ */
55
+ export declare function getCyclicNodes(graph: TaskGraphStore): Set<string>;
56
+ /**
57
+ * Find the shortest cycle in the graph
58
+ * Useful for identifying the most critical circular dependency
59
+ *
60
+ * @param graph - Task graph store
61
+ * @returns Shortest cycle array, or empty array if no cycles
62
+ */
63
+ export declare function findShortestCycle(graph: TaskGraphStore): string[];
64
+ /**
65
+ * Find all cycles involving a specific task
66
+ *
67
+ * @param graph - Task graph store
68
+ * @param taskId - Task ID to find cycles for
69
+ * @returns Array of cycles that include the specified task
70
+ */
71
+ export declare function findCyclesForTask(graph: TaskGraphStore, taskId: string): string[][];
72
+ /**
73
+ * Validate that a graph is acyclic (DAG)
74
+ * Throws an error if cycles are detected
75
+ *
76
+ * @param graph - Task graph store
77
+ * @throws {CircularDependencyError} If graph contains cycles
78
+ */
79
+ export declare function validateAcyclic(graph: TaskGraphStore): void;
80
+ /**
81
+ * Get cycle statistics
82
+ *
83
+ * @param graph - Task graph store
84
+ * @returns Object with cycle count and nodes in cycles
85
+ */
86
+ export declare function getCycleStatistics(graph: TaskGraphStore): {
87
+ cycleCount: number;
88
+ nodesInCycles: number;
89
+ totalNodes: number;
90
+ cyclesByLength: Record<number, number>;
91
+ };
92
+ /**
93
+ * Result of reference validation
94
+ */
95
+ export interface ReferenceValidationResult {
96
+ /** True if any invalid references were found */
97
+ hasInvalidReferences: boolean;
98
+ /** List of invalid references found */
99
+ invalidReferences: Array<{
100
+ /** Task ID that has the invalid reference */
101
+ taskId: string;
102
+ /** Blocker ID that doesn't exist */
103
+ invalidBlockerId: string;
104
+ }>;
105
+ }
106
+ /**
107
+ * Validate that all blocker references point to existing tasks
108
+ *
109
+ * Checks each task's blockers array to ensure all referenced tasks exist.
110
+ * This catches orphaned references that could occur from:
111
+ * - Manual JSON editing
112
+ * - Bugs in edge manipulation
113
+ * - Incomplete graph operations
114
+ *
115
+ * @param graph - Task graph store
116
+ * @returns Validation result with any invalid references found
117
+ *
118
+ * @example
119
+ * ```ts
120
+ * const result = validateReferences(graph);
121
+ * if (result.hasInvalidReferences) {
122
+ * for (const ref of result.invalidReferences) {
123
+ * console.error(`Task ${ref.taskId} has missing blocker: ${ref.invalidBlockerId}`);
124
+ * }
125
+ * }
126
+ * ```
127
+ */
128
+ export declare function validateReferences(graph: TaskGraphStore): ReferenceValidationResult;
129
+ /**
130
+ * Check if adding an edge would create a cycle
131
+ *
132
+ * When adding a blocker relationship (blockerId → taskId), this function
133
+ * checks if there's already a path from taskId to blockerId. If so,
134
+ * adding the edge would create a cycle.
135
+ *
136
+ * Also rejects self-blocking (taskId === blockerId).
137
+ *
138
+ * @param graph - Task graph store
139
+ * @param blockerId - The task that will block (source of edge)
140
+ * @param taskId - The task being blocked (target of edge)
141
+ * @returns true if adding this edge would create a cycle
142
+ *
143
+ * @example
144
+ * ```ts
145
+ * // Before adding blocker, check for cycle
146
+ * if (wouldCreateCycle(graph, blockerId, taskId)) {
147
+ * console.error('Cannot add blocker: would create a cycle');
148
+ * } else {
149
+ * task.addBlocker(blockerId);
150
+ * graph.addEdge(blockerId, taskId);
151
+ * }
152
+ * ```
153
+ */
154
+ export declare function wouldCreateCycle(graph: TaskGraphStore, blockerId: string, taskId: string): boolean;
155
+ //# sourceMappingURL=cycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cycle.d.ts","sourceRoot":"","sources":["../../../src/core/graph/cycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAajE;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,oBAAoB,CA4EvE;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAGvD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,GAAG,GAAG,CAAC,MAAM,CAAC,CAWjE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,EAAE,CAUjE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,CAInF;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAU3D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,GAAG;IACzD,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC,CAgBA;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,gDAAgD;IAChD,oBAAoB,EAAE,OAAO,CAAC;IAC9B,uCAAuC;IACvC,iBAAiB,EAAE,KAAK,CAAC;QACvB,6CAA6C;QAC7C,MAAM,EAAE,MAAM,CAAC;QACf,oCAAoC;QACpC,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC,CAAC;CACJ;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,GAAG,yBAAyB,CAkBnF;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,cAAc,EACrB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAkCT"}