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,252 @@
1
+ /**
2
+ * Find command - Search and filter tasks with advanced options
3
+ *
4
+ * Provides powerful search capabilities:
5
+ * - Title substring matching
6
+ * - Full-text search across description, notes, criteria, deliverables
7
+ * - File reference search
8
+ * - C7 verification library search
9
+ * - Special filters: without-blockers, orphans, leaves
10
+ */
11
+ import { Command } from 'commander';
12
+ import Table from 'cli-table3';
13
+ import chalk from 'chalk';
14
+ import { getProjectPath, loadGraph, formatStatus, formatPriority } from '../utils/helpers.js';
15
+ /**
16
+ * Format task as table row
17
+ */
18
+ function formatTaskAsRow(task, showId = true) {
19
+ const row = [];
20
+ if (showId) {
21
+ row.push(task.id.substring(0, 8));
22
+ }
23
+ row.push(formatStatus(task.status), formatPriority(task.priority), task.title.substring(0, 40));
24
+ return row;
25
+ }
26
+ /**
27
+ * Format task as markdown (brief for list view)
28
+ */
29
+ function formatTaskAsMarkdown(task) {
30
+ const checkbox = task.status === 'completed' ? '[x]' : '[ ]';
31
+ const status = formatStatus(task.status);
32
+ const priority = formatPriority(task.priority);
33
+ return `## ${checkbox} ${task.title}\n` +
34
+ `**ID**: \`${task.id}\`\n` +
35
+ `**Status**: ${status}\n` +
36
+ `**Priority**: ${priority}\n` +
37
+ `**Description**: ${task.description.substring(0, 100)}...\n`;
38
+ }
39
+ /**
40
+ * Check if task matches title pattern (case-insensitive substring)
41
+ */
42
+ function matchesTitle(task, pattern) {
43
+ return task.title.toLowerCase().includes(pattern.toLowerCase());
44
+ }
45
+ /**
46
+ * Check if task contains search text in various fields
47
+ */
48
+ function matchesSearch(task, query) {
49
+ const queryLower = query.toLowerCase();
50
+ // Search in title
51
+ if (task.title.toLowerCase().includes(queryLower))
52
+ return true;
53
+ // Search in description
54
+ if (task.description.toLowerCase().includes(queryLower))
55
+ return true;
56
+ // Search in notes
57
+ if (task.notes.toLowerCase().includes(queryLower))
58
+ return true;
59
+ // Search in success criteria
60
+ if (task.success_criteria.some(sc => sc.text.toLowerCase().includes(queryLower)))
61
+ return true;
62
+ // Search in deliverables
63
+ if (task.deliverables.some(d => d.text.toLowerCase().includes(queryLower)))
64
+ return true;
65
+ return false;
66
+ }
67
+ /**
68
+ * Check if task has a specific related file
69
+ */
70
+ function matchesFile(task, filePath) {
71
+ return task.related_files.some(f => f.toLowerCase().includes(filePath.toLowerCase()));
72
+ }
73
+ /**
74
+ * Check if task has C7 verification from specific library
75
+ */
76
+ function matchesC7Verification(task, libraryId) {
77
+ const libraryLower = libraryId.toLowerCase();
78
+ return task.c7_verified.some(v => v.library_id.toLowerCase().includes(libraryLower));
79
+ }
80
+ /**
81
+ * Check if task has no blockers
82
+ */
83
+ function hasNoBlockers(task) {
84
+ return task.blockers.length === 0;
85
+ }
86
+ /**
87
+ * Apply all filters and return matching tasks
88
+ */
89
+ function applyFilters(graph, options) {
90
+ let taskIds = null;
91
+ let tasks = graph.getAllTasks();
92
+ // If --orphans flag is set, filter to orphan tasks only
93
+ if (options.orphans) {
94
+ const orphanIds = graph.getOrphanTasks();
95
+ if (taskIds === null) {
96
+ taskIds = new Set(orphanIds);
97
+ }
98
+ else {
99
+ taskIds = new Set(orphanIds.filter(id => taskIds.has(id)));
100
+ }
101
+ }
102
+ // If --leaves flag is set, filter to leaf tasks only
103
+ if (options.leaves) {
104
+ const leafIds = graph.getLeafTasks();
105
+ if (taskIds === null) {
106
+ taskIds = new Set(leafIds);
107
+ }
108
+ else {
109
+ taskIds = new Set(leafIds.filter(id => taskIds.has(id)));
110
+ }
111
+ }
112
+ // If --without-blockers flag is set, filter to tasks with no blockers
113
+ if (options.withoutBlockers) {
114
+ const noBlockerIds = tasks.filter(t => hasNoBlockers(t)).map(t => t.id);
115
+ if (taskIds === null) {
116
+ taskIds = new Set(noBlockerIds);
117
+ }
118
+ else {
119
+ taskIds = new Set(noBlockerIds.filter(id => taskIds.has(id)));
120
+ }
121
+ }
122
+ // If taskIds has been constrained by flags, filter tasks
123
+ if (taskIds !== null) {
124
+ tasks = tasks.filter(t => taskIds.has(t.id));
125
+ }
126
+ // Apply --title filter
127
+ if (options.title) {
128
+ tasks = tasks.filter(t => matchesTitle(t, options.title));
129
+ }
130
+ // Apply --search filter (full-text search)
131
+ if (options.search) {
132
+ tasks = tasks.filter(t => matchesSearch(t, options.search));
133
+ }
134
+ // Apply --has-file filter
135
+ if (options.hasFile) {
136
+ tasks = tasks.filter(t => matchesFile(t, options.hasFile));
137
+ }
138
+ // Apply --verified filter (C7 verification library)
139
+ if (options.verified) {
140
+ // Handle Windows Git Bash path conversion: "/path" becomes "C:/Program Files/Git/path"
141
+ let libraryId = options.verified;
142
+ const gitBashPrefix = /^[A-Za-z]:\/(\/)?Program Files\/Git\//;
143
+ if (gitBashPrefix.test(libraryId)) {
144
+ const match = libraryId.match(/Program Files\/Git\/(.*)$/);
145
+ if (match) {
146
+ libraryId = '/' + match[1];
147
+ }
148
+ }
149
+ tasks = tasks.filter(t => matchesC7Verification(t, libraryId));
150
+ }
151
+ // Apply --status filter
152
+ if (options.status) {
153
+ tasks = tasks.filter(t => t.status === options.status);
154
+ }
155
+ // Apply --priority filter
156
+ if (options.priority) {
157
+ tasks = tasks.filter(t => t.priority === options.priority);
158
+ }
159
+ return tasks;
160
+ }
161
+ /**
162
+ * Output results in the specified format
163
+ */
164
+ function outputResults(tasks, format) {
165
+ switch (format) {
166
+ case 'json':
167
+ console.log(JSON.stringify(tasks, null, 2));
168
+ break;
169
+ case 'md':
170
+ console.log(`# Search Results (${tasks.length})\n`);
171
+ for (const task of tasks) {
172
+ console.log(formatTaskAsMarkdown(task));
173
+ }
174
+ break;
175
+ case 'table':
176
+ default:
177
+ if (tasks.length === 0) {
178
+ console.log(chalk.yellow('No tasks found matching the criteria'));
179
+ return;
180
+ }
181
+ const table = new Table({
182
+ head: [
183
+ chalk.gray('ID'),
184
+ chalk.gray('Status'),
185
+ chalk.gray('Priority'),
186
+ chalk.gray('Title'),
187
+ ].map(h => chalk.bold(h)),
188
+ colWidths: [10, 15, 10, 40],
189
+ wordWrap: true,
190
+ });
191
+ for (const task of tasks) {
192
+ table.push(formatTaskAsRow(task));
193
+ }
194
+ console.log(table.toString());
195
+ console.log(chalk.gray(`Found: ${tasks.length} task${tasks.length !== 1 ? 's' : ''}`));
196
+ break;
197
+ }
198
+ }
199
+ /**
200
+ * Create the find command
201
+ */
202
+ export const findCommand = new Command('find')
203
+ .description('Search and filter tasks with advanced options')
204
+ .option('-t, --title <pattern>', 'Search task titles (case-insensitive substring)')
205
+ .option('-s, --search <text>', 'Full-text search in description, notes, criteria, deliverables')
206
+ .option('-f, --has-file <path>', 'Find tasks referencing a specific file')
207
+ .option('-v, --verified <library>', 'Find tasks with C7 verification from specific library')
208
+ .option('--without-blockers', 'Show tasks with no blockers (ready to start)')
209
+ .option('--orphans', 'Show tasks with no relationships (no edges)')
210
+ .option('--leaves', 'Show tasks with no outgoing edges (end tasks)')
211
+ .option('--status <status>', 'Filter by status (ready|in_progress|in_review|completed|blocked)')
212
+ .option('-p, --priority <priority>', 'Filter by priority (top|second|later)')
213
+ .addHelpText('after', `
214
+ Examples:
215
+ $ octie find --title "auth" Find tasks with "auth" in title
216
+ $ octie find --search "JWT token" Full-text search for "JWT token"
217
+ $ octie find --has-file "auth.ts" Find tasks referencing auth.ts
218
+ $ octie find --verified "/express" Find tasks verified against Express docs
219
+ $ octie find --without-blockers Find tasks ready to start
220
+ $ octie find --orphans Find disconnected tasks
221
+ $ octie find --leaves --status ready Find ready end tasks
222
+ $ octie find --title "API" --priority top Combine multiple filters
223
+
224
+ Output formats:
225
+ $ octie find --title "auth" --format json Output as JSON
226
+ $ octie find --search "test" --format md Output as Markdown
227
+ `)
228
+ .action(async (options, command) => {
229
+ try {
230
+ // Get global options
231
+ const globalOpts = command.parent?.opts() || {};
232
+ const format = globalOpts.format || 'table';
233
+ // Load project
234
+ const projectPath = await getProjectPath(globalOpts.project);
235
+ const graph = await loadGraph(projectPath);
236
+ // Apply filters
237
+ const tasks = applyFilters(graph, options);
238
+ // Output results
239
+ outputResults(tasks, format);
240
+ process.exit(0);
241
+ }
242
+ catch (err) {
243
+ if (err instanceof Error) {
244
+ console.error(chalk.red(`Error: ${err.message}`));
245
+ }
246
+ else {
247
+ console.error(chalk.red('Failed to search tasks'));
248
+ }
249
+ process.exit(1);
250
+ }
251
+ });
252
+ //# sourceMappingURL=find.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find.js","sourceRoot":"","sources":["../../../src/cli/commands/find.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Get command - Retrieve and display task details
3
+ */
4
+ import { Command } from 'commander';
5
+ /**
6
+ * Create the get command
7
+ */
8
+ export declare const getCommand: Command;
9
+ //# sourceMappingURL=get.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/get.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC;;GAEG;AACH,eAAO,MAAM,UAAU,SAiEnB,CAAC"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Get command - Retrieve and display task details
3
+ */
4
+ import { Command } from 'commander';
5
+ import { getProjectPath, loadGraph, error } from '../utils/helpers.js';
6
+ import { formatTaskMarkdown } from '../output/markdown.js';
7
+ import { formatTaskJSON } from '../output/json.js';
8
+ import { formatTaskDetailTable } from '../output/table.js';
9
+ import chalk from 'chalk';
10
+ /**
11
+ * Create the get command
12
+ */
13
+ export const getCommand = new Command('get')
14
+ .description('Get task details')
15
+ .argument('<id>', 'Task ID (full UUID or first 7-8 characters)')
16
+ .addHelpText('after', `
17
+ Task ID Format:
18
+ • Full UUID: 12345678-1234-1234-1234-123456789012
19
+ • Short UUID: First 7-8 characters (e.g., 12345678)
20
+
21
+ Output Formats (use global --format option):
22
+ table - Formatted table view (default)
23
+ json - Full JSON representation
24
+ md - Markdown format for documentation
25
+
26
+ Examples:
27
+ $ octie get abc12345
28
+ $ octie get abc12345 --format json
29
+ $ octie get abc12345 --format md
30
+
31
+ Global Options:
32
+ --format <format> Output format: table, json, md
33
+ --project <path> Project directory path
34
+ `)
35
+ .action(async (id, _options, command) => {
36
+ try {
37
+ // Get global options
38
+ const globalOpts = command.parent?.opts() || {};
39
+ const format = globalOpts.format || 'table';
40
+ // Load project
41
+ const projectPath = await getProjectPath(globalOpts.project);
42
+ const graph = await loadGraph(projectPath);
43
+ // Find task (supports full UUID or short prefix)
44
+ const task = graph.getNodeByIdOrPrefix(id);
45
+ if (!task) {
46
+ error(chalk.red(`Task not found: ${id}`));
47
+ process.exit(1);
48
+ }
49
+ // Format output
50
+ switch (format) {
51
+ case 'json':
52
+ console.log(formatTaskJSON(task));
53
+ break;
54
+ case 'md':
55
+ console.log(formatTaskMarkdown(task));
56
+ break;
57
+ case 'table':
58
+ default:
59
+ console.log(formatTaskDetailTable(task));
60
+ break;
61
+ }
62
+ process.exit(0);
63
+ }
64
+ catch (err) {
65
+ if (err instanceof Error) {
66
+ console.error(chalk.red(`Error: ${err.message}`));
67
+ }
68
+ else {
69
+ console.error(chalk.red('Failed to get task'));
70
+ }
71
+ process.exit(1);
72
+ }
73
+ });
74
+ //# sourceMappingURL=get.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.js","sourceRoot":"","sources":["../../../src/cli/commands/get.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC;KACzC,WAAW,CAAC,kBAAkB,CAAC;KAC/B,QAAQ,CAAC,MAAM,EAAE,6CAA6C,CAAC;KAC/D,WAAW,CAAC,OAAO,EAAE;;;;;;;;;;;;;;;;;;CAkBvB,CAAC;KACC,MAAM,CAAC,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;IACtC,IAAI,CAAC;QACH,qBAAqB;QACrB,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAChD,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,IAAI,OAAO,CAAC;QAE5C,eAAe;QACf,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAC7D,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,CAAC;QAE3C,iDAAiD;QACjD,MAAM,IAAI,GAAG,KAAK,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC;QAE3C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC,CAAC;YAC1C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,gBAAgB;QAChB,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,MAAM;gBACT,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;gBAClC,MAAM;YAER,KAAK,IAAI;gBACP,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC;gBACtC,MAAM;YAER,KAAK,OAAO,CAAC;YACb;gBACE,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC;gBACzC,MAAM;QACV,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACpD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Graph command - Graph analysis and validation operations
3
+ */
4
+ import { Command } from 'commander';
5
+ /**
6
+ * Create the graph command
7
+ */
8
+ export declare const graphCommand: Command;
9
+ //# sourceMappingURL=graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/graph.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC;;GAEG;AACH,eAAO,MAAM,YAAY,SAgErB,CAAC"}
@@ -0,0 +1,200 @@
1
+ /**
2
+ * Graph command - Graph analysis and validation operations
3
+ */
4
+ import { Command } from 'commander';
5
+ import { getProjectPath, loadGraph, success, error } from '../utils/helpers.js';
6
+ import chalk from 'chalk';
7
+ import { detectCycle, validateReferences } from '../../core/graph/cycle.js';
8
+ import { topologicalSort } from '../../core/graph/sort.js';
9
+ import { getConnectedComponents } from '../../core/graph/traversal.js';
10
+ /**
11
+ * Create the graph command
12
+ */
13
+ export const graphCommand = new Command('graph')
14
+ .description('Graph analysis and validation operations')
15
+ .addHelpText('after', `
16
+ Subcommands:
17
+ validate Check graph integrity (cycles, orphan references)
18
+ cycles Detect and display all cycles in the graph
19
+
20
+ Examples:
21
+ $ octie graph Show graph statistics
22
+ $ octie graph validate Validate graph has no cycles or broken refs
23
+ $ octie graph cycles Show all cycles with task titles
24
+ `)
25
+ .action(async (_options, command) => {
26
+ try {
27
+ // Get global options - traverse up to main program
28
+ const globalOpts = command.parent?.opts() || {};
29
+ const projectPath = await getProjectPath(globalOpts.project);
30
+ const graph = await loadGraph(projectPath);
31
+ console.log('');
32
+ console.log(chalk.bold('Graph Statistics:'));
33
+ console.log('');
34
+ const totalTasks = graph.size;
35
+ const rootTasks = graph.getRootTasks();
36
+ const orphanTasks = graph.getOrphanTasks();
37
+ console.log(`Total tasks: ${totalTasks}`);
38
+ console.log(`Root tasks: ${rootTasks.length}`);
39
+ console.log(`Orphan tasks: ${orphanTasks.length}`);
40
+ console.log('');
41
+ // Check for cycles
42
+ const cycleResult = detectCycle(graph);
43
+ if (cycleResult.hasCycle) {
44
+ console.error(chalk.red(`⚠️ Graph contains ${cycleResult.cycles.length} cycle(s)!`));
45
+ for (const cycle of cycleResult.cycles) {
46
+ console.error(chalk.red(` Cycle: ${cycle.join(' → ')}`));
47
+ }
48
+ }
49
+ else {
50
+ success('Graph is acyclic (valid DAG)');
51
+ }
52
+ // Topological sort
53
+ const sortResult = topologicalSort(graph);
54
+ if (sortResult.hasCycle) {
55
+ console.error(chalk.red(`⚠️ Topological sort failed: cycle detected`));
56
+ }
57
+ else {
58
+ console.log(chalk.green(`✓ Topological sort: ${sortResult.sorted.length} tasks ordered`));
59
+ }
60
+ // Connected components
61
+ const components = getConnectedComponents(graph);
62
+ console.log(`Connected components: ${components.length}`);
63
+ process.exit(0);
64
+ }
65
+ catch (err) {
66
+ if (err instanceof Error) {
67
+ error(err.message);
68
+ }
69
+ else {
70
+ error('Failed to analyze graph');
71
+ }
72
+ process.exit(1);
73
+ }
74
+ });
75
+ // Add subcommands
76
+ graphCommand
77
+ .command('validate')
78
+ .description('Validate graph structure (checks for cycles and orphan references)')
79
+ .addHelpText('after', `
80
+ Validation Checks:
81
+ 1. Cycle Detection - Ensures graph is a valid DAG (no circular dependencies)
82
+ 2. Reference Integrity - Ensures all blocker references point to existing tasks
83
+
84
+ Exit Codes:
85
+ 0 - Graph is valid
86
+ 1 - Validation failed (cycles or broken references found)
87
+
88
+ Example:
89
+ $ octie graph validate
90
+ ✓ Graph validation passed: No cycles detected, all blocker references valid
91
+ `)
92
+ .action(async (_options, command) => {
93
+ try {
94
+ // Get global options - traverse up to main program (parent.parent)
95
+ const globalOpts = command.parent?.parent?.opts() || {};
96
+ const projectPath = await getProjectPath(globalOpts.project);
97
+ const graph = await loadGraph(projectPath);
98
+ // Check for cycles
99
+ const cycleResult = detectCycle(graph);
100
+ if (cycleResult.hasCycle) {
101
+ console.error(chalk.red(`Graph validation failed: ${cycleResult.cycles.length} cycle(s) detected`));
102
+ process.exit(1);
103
+ }
104
+ // Check for missing blocker references
105
+ const refResult = validateReferences(graph);
106
+ if (refResult.hasInvalidReferences) {
107
+ console.error(chalk.red(`Graph validation failed: ${refResult.invalidReferences.length} missing blocker reference(s)`));
108
+ for (const ref of refResult.invalidReferences) {
109
+ console.error(chalk.red(` Task ${ref.taskId.substring(0, 8)} references non-existent blocker: ${ref.invalidBlockerId.substring(0, 8)}`));
110
+ }
111
+ process.exit(1);
112
+ }
113
+ success('Graph validation passed: No cycles detected, all blocker references valid');
114
+ process.exit(0);
115
+ }
116
+ catch (err) {
117
+ if (err instanceof Error) {
118
+ error(err.message);
119
+ }
120
+ else {
121
+ error('Validation failed');
122
+ }
123
+ process.exit(1);
124
+ }
125
+ });
126
+ graphCommand
127
+ .command('cycles')
128
+ .description('Detect and display cycles in the graph')
129
+ .addHelpText('after', `
130
+ Output Format:
131
+ Each cycle is shown as a chain of task IDs with task titles:
132
+
133
+ ⚠️ Found 2 cycle(s):
134
+
135
+ 1. abc12345 → def67890 → abc12345
136
+ - Task A title
137
+ - Task B title
138
+ - Task A title
139
+
140
+ 2. xyz11111 → yyy22222 → zzz33333 → xyz11111
141
+ - Task X title
142
+ - Task Y title
143
+ - Task Z title
144
+ - Task X title
145
+
146
+ Exit Codes:
147
+ 0 - No cycles found
148
+ 1 - Cycles detected
149
+
150
+ How to Fix:
151
+ Use 'octie update <id> --unblock <blocker-id>' to break the cycle.
152
+
153
+ Example:
154
+ $ octie graph cycles
155
+ ⚠️ Found 1 cycle(s):
156
+ 1. abc12345 → def67890 → abc12345
157
+ `)
158
+ .action(async (_options, command) => {
159
+ try {
160
+ // Get global options - traverse up to main program (parent.parent)
161
+ const globalOpts = command.parent?.parent?.opts() || {};
162
+ const projectPath = await getProjectPath(globalOpts.project);
163
+ const graph = await loadGraph(projectPath);
164
+ const result = detectCycle(graph);
165
+ if (result.hasCycle) {
166
+ console.log('');
167
+ console.error(chalk.red.bold(`⚠️ Found ${result.cycles.length} cycle(s):`));
168
+ console.log('');
169
+ for (let i = 0; i < result.cycles.length; i++) {
170
+ const cycle = result.cycles[i];
171
+ if (cycle) {
172
+ console.error(chalk.red(`${i + 1}. ${cycle.join(' → ')}`));
173
+ // Show task titles
174
+ for (const taskId of cycle) {
175
+ const task = graph.getNode(taskId);
176
+ if (task) {
177
+ console.error(chalk.gray(` - ${task.title}`));
178
+ }
179
+ }
180
+ console.log('');
181
+ }
182
+ }
183
+ process.exit(1);
184
+ }
185
+ else {
186
+ success('No cycles detected in graph');
187
+ process.exit(0);
188
+ }
189
+ }
190
+ catch (err) {
191
+ if (err instanceof Error) {
192
+ error(err.message);
193
+ }
194
+ else {
195
+ error('Cycle detection failed');
196
+ }
197
+ process.exit(1);
198
+ }
199
+ });
200
+ //# sourceMappingURL=graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.js","sourceRoot":"","sources":["../../../src/cli/commands/graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Import command - Import project data from file
3
+ */
4
+ import { Command } from 'commander';
5
+ /**
6
+ * Create the import command
7
+ */
8
+ export declare const importCommand: Command;
9
+ //# sourceMappingURL=import.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/import.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2uBpC;;GAEG;AACH,eAAO,MAAM,aAAa,SAuItB,CAAC"}