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,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core type definitions for Octie task management system
|
|
3
|
+
*
|
|
4
|
+
* This module defines all TypeScript interfaces and types used throughout the system.
|
|
5
|
+
* @module types
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Error code to HTTP status code mapping
|
|
9
|
+
* Used by API error handler to return appropriate status codes
|
|
10
|
+
*/
|
|
11
|
+
export const ERROR_STATUS_MAP = {
|
|
12
|
+
// Client errors (4xx)
|
|
13
|
+
TASK_NOT_FOUND: 404,
|
|
14
|
+
PROJECT_NOT_FOUND: 404,
|
|
15
|
+
VALIDATION_ERROR: 400,
|
|
16
|
+
ATOMIC_TASK_VIOLATION: 400,
|
|
17
|
+
INVALID_ARGUMENT: 400,
|
|
18
|
+
INVALID_TASK_ID: 400,
|
|
19
|
+
CIRCULAR_DEPENDENCY: 400,
|
|
20
|
+
DUPLICATE_TASK: 409,
|
|
21
|
+
// Server errors (5xx)
|
|
22
|
+
FILE_OPERATION_ERROR: 500,
|
|
23
|
+
STORAGE_ERROR: 500,
|
|
24
|
+
INTERNAL_ERROR: 500,
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Error code to suggestion mapping
|
|
28
|
+
* Provides actionable recovery steps for each error type
|
|
29
|
+
*/
|
|
30
|
+
export const ERROR_SUGGESTIONS = {
|
|
31
|
+
TASK_NOT_FOUND: 'Use `octie list` to see all available tasks and their IDs.',
|
|
32
|
+
PROJECT_NOT_FOUND: 'Run `octie init` to create a new project or use `--project <path>` to specify the project directory.',
|
|
33
|
+
VALIDATION_ERROR: 'Check the input format and ensure all required fields are provided.',
|
|
34
|
+
ATOMIC_TASK_VIOLATION: 'Split the task into smaller, focused tasks with specific deliverables.',
|
|
35
|
+
INVALID_ARGUMENT: 'Check the command syntax with `octie <command> --help`.',
|
|
36
|
+
INVALID_TASK_ID: 'Task IDs must be valid UUIDs. Use `octie list` to find the correct task ID.',
|
|
37
|
+
CIRCULAR_DEPENDENCY: 'Remove one of the edges in the cycle using `octie update <id> --unblock <blocker_id>`.',
|
|
38
|
+
DUPLICATE_TASK: 'Use `octie list --search <query>` to find existing similar tasks.',
|
|
39
|
+
FILE_OPERATION_ERROR: 'Check file permissions and ensure the .octie directory is writable.',
|
|
40
|
+
STORAGE_ERROR: 'Try restoring from backup with `octie import --file .octie/project.json.bak`.',
|
|
41
|
+
INTERNAL_ERROR: 'Run with --verbose flag for more details or check the logs.',
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Custom error base class
|
|
45
|
+
* All Octie-specific errors extend this class
|
|
46
|
+
*/
|
|
47
|
+
export class OctieError extends Error {
|
|
48
|
+
code;
|
|
49
|
+
/** Optional suggestion for how to resolve the error */
|
|
50
|
+
suggestion;
|
|
51
|
+
/** HTTP status code for API responses */
|
|
52
|
+
statusCode;
|
|
53
|
+
constructor(message, code, suggestion) {
|
|
54
|
+
super(message);
|
|
55
|
+
this.code = code;
|
|
56
|
+
this.name = 'OctieError';
|
|
57
|
+
this.suggestion = suggestion ?? ERROR_SUGGESTIONS[code];
|
|
58
|
+
this.statusCode = ERROR_STATUS_MAP[code] ?? 500;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Error thrown when a task is not found
|
|
63
|
+
*/
|
|
64
|
+
export class TaskNotFoundError extends OctieError {
|
|
65
|
+
constructor(taskId) {
|
|
66
|
+
super(`Task with ID '${taskId}' not found`, 'TASK_NOT_FOUND', `Use \`octie list\` to see all available tasks. The ID '${taskId}' may be incorrect or the task may have been deleted.`);
|
|
67
|
+
this.name = 'TaskNotFoundError';
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Error thrown when a short UUID prefix matches multiple tasks
|
|
72
|
+
*/
|
|
73
|
+
export class AmbiguousIdError extends OctieError {
|
|
74
|
+
constructor(prefix, matchingIds) {
|
|
75
|
+
super(`ID prefix '${prefix}' matches multiple tasks: ${matchingIds.map(id => id.substring(0, 7)).join(', ')}. Please provide more characters.`, 'AMBIGUOUS_ID', `The ID prefix '${prefix}' is too short and matches ${matchingIds.length} tasks. Provide more characters (up to the full UUID) to uniquely identify a task.`);
|
|
76
|
+
this.name = 'AmbiguousIdError';
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Error thrown when a project is not found
|
|
81
|
+
*/
|
|
82
|
+
export class ProjectNotFoundError extends OctieError {
|
|
83
|
+
constructor(path) {
|
|
84
|
+
super(path ? `No Octie project found at '${path}'` : 'No Octie project found', 'PROJECT_NOT_FOUND', 'Run `octie init` to create a new project in the current directory, or use `--project <path>` to specify a different project directory.');
|
|
85
|
+
this.name = 'ProjectNotFoundError';
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Error thrown when a circular dependency is detected
|
|
90
|
+
*/
|
|
91
|
+
export class CircularDependencyError extends OctieError {
|
|
92
|
+
cycleNodes;
|
|
93
|
+
constructor(cycleNodes) {
|
|
94
|
+
super(`Circular dependency detected: ${cycleNodes.join(' -> ')}`, 'CIRCULAR_DEPENDENCY', `Break the cycle by removing one of the dependencies. Use \`octie update ${cycleNodes[0]} --unblock ${cycleNodes[cycleNodes.length - 1]}\` or restructure your task graph.`);
|
|
95
|
+
this.cycleNodes = cycleNodes;
|
|
96
|
+
this.name = 'CircularDependencyError';
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Error thrown when file operations fail
|
|
101
|
+
*/
|
|
102
|
+
export class FileOperationError extends OctieError {
|
|
103
|
+
filePath;
|
|
104
|
+
constructor(message, filePath) {
|
|
105
|
+
super(`${message}: ${filePath}`, 'FILE_OPERATION_ERROR', `Check file permissions and ensure the path is correct. If the file is corrupted, try restoring from backup: \`octie import --file .octie/project.json.bak\``);
|
|
106
|
+
this.filePath = filePath;
|
|
107
|
+
this.name = 'FileOperationError';
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Error thrown when validation fails
|
|
112
|
+
*/
|
|
113
|
+
export class ValidationError extends OctieError {
|
|
114
|
+
field;
|
|
115
|
+
constructor(message, field) {
|
|
116
|
+
super(message, 'VALIDATION_ERROR', field ? `Check the '${field}' field and ensure it meets the requirements.` : 'Check the input format and ensure all required fields are provided.');
|
|
117
|
+
this.field = field;
|
|
118
|
+
this.name = 'ValidationError';
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Error thrown when atomic task validation fails
|
|
123
|
+
*/
|
|
124
|
+
export class AtomicTaskViolationError extends ValidationError {
|
|
125
|
+
violations;
|
|
126
|
+
constructor(message, violations) {
|
|
127
|
+
super(message, 'ATOMIC_TASK_VIOLATION');
|
|
128
|
+
this.violations = violations;
|
|
129
|
+
this.name = 'AtomicTaskViolationError';
|
|
130
|
+
// Override suggestion with specific violations
|
|
131
|
+
this.suggestion = `Task violates atomic task requirements:\n${violations.map(v => ` • ${v}`).join('\n')}\n\nSplit into smaller tasks or make the task more specific.`;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Error thrown when an invalid argument is provided
|
|
136
|
+
*/
|
|
137
|
+
export class InvalidArgumentError extends OctieError {
|
|
138
|
+
constructor(message, suggestion) {
|
|
139
|
+
super(message, 'INVALID_ARGUMENT', suggestion ?? 'Check the command syntax with `octie <command> --help`.');
|
|
140
|
+
this.name = 'InvalidArgumentError';
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Error thrown when a duplicate is detected
|
|
145
|
+
*/
|
|
146
|
+
export class DuplicateTaskError extends OctieError {
|
|
147
|
+
constructor(identifier) {
|
|
148
|
+
super(`Task already exists: ${identifier}`, 'DUPLICATE_TASK', 'Use `octie list --search <query>` to find the existing task, or use a different identifier.');
|
|
149
|
+
this.name = 'DuplicateTaskError';
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Error thrown when storage operations fail
|
|
154
|
+
*/
|
|
155
|
+
export class StorageError extends OctieError {
|
|
156
|
+
constructor(message, suggestion) {
|
|
157
|
+
super(message, 'STORAGE_ERROR', suggestion ?? 'Try restoring from backup or re-initialize the project.');
|
|
158
|
+
this.name = 'StorageError';
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Immutability violation error
|
|
163
|
+
* Thrown when attempting to modify completed items that are immutable
|
|
164
|
+
*
|
|
165
|
+
* Per the status refactor spec:
|
|
166
|
+
* - success_criteria items: Cannot be unchecked or deleted once completed
|
|
167
|
+
* - deliverables items: Cannot be unchecked or deleted once completed
|
|
168
|
+
* - need_fix items: Cannot be deleted or unmarked once completed
|
|
169
|
+
*/
|
|
170
|
+
export class ImmutabilityViolationError extends ValidationError {
|
|
171
|
+
/** ID of the item that cannot be modified */
|
|
172
|
+
itemId;
|
|
173
|
+
/** Type of the item (success_criterion, deliverable, need_fix) */
|
|
174
|
+
itemType;
|
|
175
|
+
constructor(message, itemId, itemType) {
|
|
176
|
+
super(message, itemType);
|
|
177
|
+
this.name = 'ImmutabilityViolationError';
|
|
178
|
+
this.itemId = itemId;
|
|
179
|
+
this.itemType = itemType;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph Routes - Graph analysis and validation endpoints
|
|
3
|
+
*
|
|
4
|
+
* Provides endpoints for graph structure analysis, topological sorting,
|
|
5
|
+
* cycle detection, critical path analysis, and project statistics.
|
|
6
|
+
*
|
|
7
|
+
* @module web/routes/graph
|
|
8
|
+
*/
|
|
9
|
+
import type { Router } from 'express';
|
|
10
|
+
import type { TaskGraphStore } from '../../core/graph/index.js';
|
|
11
|
+
/**
|
|
12
|
+
* Register graph routes
|
|
13
|
+
* @param router - Express Router instance
|
|
14
|
+
* @param getGraph - Function to get the current graph instance
|
|
15
|
+
*/
|
|
16
|
+
export declare function registerGraphRoutes(router: Router, getGraph: () => TaskGraphStore | null): void;
|
|
17
|
+
//# sourceMappingURL=graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../../src/web/routes/graph.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAqB,MAAM,EAAE,MAAM,SAAS,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAmDhE;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,cAAc,GAAG,IAAI,GACpC,IAAI,CAoQN"}
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph Routes - Graph analysis and validation endpoints
|
|
3
|
+
*
|
|
4
|
+
* Provides endpoints for graph structure analysis, topological sorting,
|
|
5
|
+
* cycle detection, critical path analysis, and project statistics.
|
|
6
|
+
*
|
|
7
|
+
* @module web/routes/graph
|
|
8
|
+
*/
|
|
9
|
+
import { topologicalSort, findCriticalPath, isValidDAG } from '../../core/graph/sort.js';
|
|
10
|
+
import { detectCycle, hasCycle, getCycleStatistics } from '../../core/graph/cycle.js';
|
|
11
|
+
import { TaskStorage } from '../../core/storage/file-store.js';
|
|
12
|
+
import { ERROR_SUGGESTIONS } from '../../types/index.js';
|
|
13
|
+
/**
|
|
14
|
+
* Async error handler wrapper
|
|
15
|
+
* Catches async errors and passes them to Express error handling
|
|
16
|
+
*/
|
|
17
|
+
function asyncHandler(fn) {
|
|
18
|
+
return (req, res, next) => {
|
|
19
|
+
Promise.resolve(fn(req, res)).catch(next);
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Send successful API response
|
|
24
|
+
*/
|
|
25
|
+
function sendSuccess(res, data, status = 200) {
|
|
26
|
+
res.status(status).json({
|
|
27
|
+
success: true,
|
|
28
|
+
data,
|
|
29
|
+
timestamp: new Date().toISOString(),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Send error API response
|
|
34
|
+
*/
|
|
35
|
+
function sendError(res, code, message, status = 400, details, suggestion) {
|
|
36
|
+
res.status(status).json({
|
|
37
|
+
success: false,
|
|
38
|
+
error: {
|
|
39
|
+
code,
|
|
40
|
+
message,
|
|
41
|
+
suggestion: suggestion ?? ERROR_SUGGESTIONS[code],
|
|
42
|
+
details,
|
|
43
|
+
},
|
|
44
|
+
timestamp: new Date().toISOString(),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Register graph routes
|
|
49
|
+
* @param router - Express Router instance
|
|
50
|
+
* @param getGraph - Function to get the current graph instance
|
|
51
|
+
*/
|
|
52
|
+
export function registerGraphRoutes(router, getGraph) {
|
|
53
|
+
// Cache for loaded project graphs
|
|
54
|
+
const graphCache = new Map();
|
|
55
|
+
/**
|
|
56
|
+
* Get graph for a specific project path, using cache when possible
|
|
57
|
+
*/
|
|
58
|
+
async function getProjectGraph(projectPath) {
|
|
59
|
+
if (!projectPath) {
|
|
60
|
+
return getGraph();
|
|
61
|
+
}
|
|
62
|
+
// Check cache first
|
|
63
|
+
const cached = graphCache.get(projectPath);
|
|
64
|
+
if (cached) {
|
|
65
|
+
return cached;
|
|
66
|
+
}
|
|
67
|
+
// Load the project
|
|
68
|
+
try {
|
|
69
|
+
const storage = new TaskStorage({ projectDir: projectPath });
|
|
70
|
+
const graph = await storage.load();
|
|
71
|
+
graphCache.set(projectPath, graph);
|
|
72
|
+
return graph;
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Extract project path from query params
|
|
80
|
+
*/
|
|
81
|
+
function getProjectPath(req) {
|
|
82
|
+
const project = req.query.project;
|
|
83
|
+
return typeof project === 'string' ? project : undefined;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* GET /api/graph
|
|
87
|
+
* Get full graph structure including all tasks and edges
|
|
88
|
+
*/
|
|
89
|
+
router.get('/api/graph', asyncHandler(async (req, res) => {
|
|
90
|
+
const projectPath = getProjectPath(req);
|
|
91
|
+
const graph = await getProjectGraph(projectPath);
|
|
92
|
+
if (!graph) {
|
|
93
|
+
return sendError(res, 'GRAPH_NOT_LOADED', projectPath ? `Project not found: ${projectPath}` : 'Graph not loaded', 500);
|
|
94
|
+
}
|
|
95
|
+
// Serialize graph to JSON format
|
|
96
|
+
const graphData = graph.toJSON();
|
|
97
|
+
// Convert nodes from object (keyed by ID) to array for frontend
|
|
98
|
+
const nodesArray = Object.values(graphData.nodes);
|
|
99
|
+
// Get valid node IDs
|
|
100
|
+
const validNodeIds = new Set(nodesArray.map(n => n.id));
|
|
101
|
+
// Filter edges to only include valid node references
|
|
102
|
+
const filterEdges = (edges) => {
|
|
103
|
+
const filtered = {};
|
|
104
|
+
for (const [sourceId, targetIds] of Object.entries(edges)) {
|
|
105
|
+
// Skip if source is invalid
|
|
106
|
+
if (!sourceId || sourceId === 'null' || sourceId === 'undefined' || !validNodeIds.has(sourceId)) {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
// Filter targets to only valid nodes
|
|
110
|
+
const validTargets = (targetIds || []).filter(targetId => targetId && targetId !== 'null' && targetId !== 'undefined' && validNodeIds.has(targetId));
|
|
111
|
+
if (validTargets.length > 0) {
|
|
112
|
+
filtered[sourceId] = validTargets;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return filtered;
|
|
116
|
+
};
|
|
117
|
+
return sendSuccess(res, {
|
|
118
|
+
metadata: graphData.metadata,
|
|
119
|
+
nodes: nodesArray,
|
|
120
|
+
outgoingEdges: filterEdges(graphData.outgoingEdges),
|
|
121
|
+
incomingEdges: filterEdges(graphData.incomingEdges),
|
|
122
|
+
});
|
|
123
|
+
}));
|
|
124
|
+
/**
|
|
125
|
+
* GET /api/graph/topology
|
|
126
|
+
* Get topological order of tasks
|
|
127
|
+
*/
|
|
128
|
+
router.get('/api/graph/topology', asyncHandler(async (req, res) => {
|
|
129
|
+
const projectPath = getProjectPath(req);
|
|
130
|
+
const graph = await getProjectGraph(projectPath);
|
|
131
|
+
if (!graph) {
|
|
132
|
+
return sendError(res, 'GRAPH_NOT_LOADED', projectPath ? `Project not found: ${projectPath}` : 'Graph not loaded', 500);
|
|
133
|
+
}
|
|
134
|
+
const result = topologicalSort(graph);
|
|
135
|
+
if (result.hasCycle) {
|
|
136
|
+
return sendSuccess(res, {
|
|
137
|
+
hasCycle: true,
|
|
138
|
+
cycleNodes: result.cycleNodes,
|
|
139
|
+
message: 'Graph contains cycles, topological sort is not valid for cyclic graphs',
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
return sendSuccess(res, {
|
|
143
|
+
hasCycle: false,
|
|
144
|
+
sorted: result.sorted,
|
|
145
|
+
taskCount: result.sorted.length,
|
|
146
|
+
});
|
|
147
|
+
}));
|
|
148
|
+
/**
|
|
149
|
+
* POST /api/graph/validate
|
|
150
|
+
* Validate graph structure and check for cycles
|
|
151
|
+
*/
|
|
152
|
+
router.post('/api/graph/validate', asyncHandler(async (req, res) => {
|
|
153
|
+
const projectPath = getProjectPath(req);
|
|
154
|
+
const graph = await getProjectGraph(projectPath);
|
|
155
|
+
if (!graph) {
|
|
156
|
+
return sendError(res, 'GRAPH_NOT_LOADED', projectPath ? `Project not found: ${projectPath}` : 'Graph not loaded', 500);
|
|
157
|
+
}
|
|
158
|
+
// Check if graph is valid (acyclic)
|
|
159
|
+
const isValid = isValidDAG(graph);
|
|
160
|
+
// Get cycle statistics if graph has cycles
|
|
161
|
+
let cycleStats = null;
|
|
162
|
+
if (!isValid) {
|
|
163
|
+
cycleStats = getCycleStatistics(graph);
|
|
164
|
+
}
|
|
165
|
+
return sendSuccess(res, {
|
|
166
|
+
isValid,
|
|
167
|
+
hasCycle: !isValid,
|
|
168
|
+
cycleStats,
|
|
169
|
+
message: isValid
|
|
170
|
+
? 'Graph structure is valid (acyclic)'
|
|
171
|
+
: 'Graph contains cycles and is not a valid DAG',
|
|
172
|
+
});
|
|
173
|
+
}));
|
|
174
|
+
/**
|
|
175
|
+
* GET /api/graph/cycles
|
|
176
|
+
* Detect and return all cycles in the graph
|
|
177
|
+
*/
|
|
178
|
+
router.get('/api/graph/cycles', asyncHandler(async (req, res) => {
|
|
179
|
+
const projectPath = getProjectPath(req);
|
|
180
|
+
const graph = await getProjectGraph(projectPath);
|
|
181
|
+
if (!graph) {
|
|
182
|
+
return sendError(res, 'GRAPH_NOT_LOADED', projectPath ? `Project not found: ${projectPath}` : 'Graph not loaded', 500);
|
|
183
|
+
}
|
|
184
|
+
const result = detectCycle(graph);
|
|
185
|
+
if (!result.hasCycle) {
|
|
186
|
+
return sendSuccess(res, {
|
|
187
|
+
hasCycle: false,
|
|
188
|
+
cycles: [],
|
|
189
|
+
message: 'No cycles detected in graph',
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
return sendSuccess(res, {
|
|
193
|
+
hasCycle: true,
|
|
194
|
+
cycles: result.cycles,
|
|
195
|
+
cycleCount: result.cycles.length,
|
|
196
|
+
message: `Found ${result.cycles.length} cycle(s) in graph`,
|
|
197
|
+
});
|
|
198
|
+
}));
|
|
199
|
+
/**
|
|
200
|
+
* GET /api/graph/critical-path
|
|
201
|
+
* Get the critical path (longest path) through the graph
|
|
202
|
+
*/
|
|
203
|
+
router.get('/api/graph/critical-path', asyncHandler(async (req, res) => {
|
|
204
|
+
const projectPath = getProjectPath(req);
|
|
205
|
+
const graph = await getProjectGraph(projectPath);
|
|
206
|
+
if (!graph) {
|
|
207
|
+
return sendError(res, 'GRAPH_NOT_LOADED', projectPath ? `Project not found: ${projectPath}` : 'Graph not loaded', 500);
|
|
208
|
+
}
|
|
209
|
+
// First check if graph has cycles
|
|
210
|
+
if (hasCycle(graph)) {
|
|
211
|
+
return sendError(res, 'GRAPH_HAS_CYCLE', 'Cannot calculate critical path for cyclic graph', 400);
|
|
212
|
+
}
|
|
213
|
+
const result = findCriticalPath(graph);
|
|
214
|
+
return sendSuccess(res, {
|
|
215
|
+
path: result.path,
|
|
216
|
+
duration: result.duration,
|
|
217
|
+
taskCount: result.path.length,
|
|
218
|
+
});
|
|
219
|
+
}));
|
|
220
|
+
/**
|
|
221
|
+
* GET /api/stats
|
|
222
|
+
* Get project statistics
|
|
223
|
+
*/
|
|
224
|
+
router.get('/api/stats', asyncHandler(async (req, res) => {
|
|
225
|
+
const projectPath = getProjectPath(req);
|
|
226
|
+
const graph = await getProjectGraph(projectPath);
|
|
227
|
+
if (!graph) {
|
|
228
|
+
return sendError(res, 'GRAPH_NOT_LOADED', projectPath ? `Project not found: ${projectPath}` : 'Graph not loaded', 500);
|
|
229
|
+
}
|
|
230
|
+
// Get basic graph stats
|
|
231
|
+
const totalTasks = graph.size;
|
|
232
|
+
const rootTasks = graph.getRootTasks();
|
|
233
|
+
const orphanTasks = graph.getOrphanTasks();
|
|
234
|
+
// Calculate status and priority counts by iterating through tasks
|
|
235
|
+
const statusCounts = new Map();
|
|
236
|
+
statusCounts.set('ready', 0);
|
|
237
|
+
statusCounts.set('in_progress', 0);
|
|
238
|
+
statusCounts.set('in_review', 0);
|
|
239
|
+
statusCounts.set('completed', 0);
|
|
240
|
+
statusCounts.set('blocked', 0);
|
|
241
|
+
const priorityCounts = new Map();
|
|
242
|
+
priorityCounts.set('top', 0);
|
|
243
|
+
priorityCounts.set('second', 0);
|
|
244
|
+
priorityCounts.set('later', 0);
|
|
245
|
+
for (const task of graph.getAllTasks()) {
|
|
246
|
+
const currentStatus = statusCounts.get(task.status) ?? 0;
|
|
247
|
+
statusCounts.set(task.status, currentStatus + 1);
|
|
248
|
+
const currentPriority = priorityCounts.get(task.priority) ?? 0;
|
|
249
|
+
priorityCounts.set(task.priority, currentPriority + 1);
|
|
250
|
+
}
|
|
251
|
+
// Convert Maps to plain objects for JSON response
|
|
252
|
+
const statusCountsObj = {};
|
|
253
|
+
statusCounts.forEach((value, key) => { statusCountsObj[key] = value; });
|
|
254
|
+
const priorityCountsObj = {};
|
|
255
|
+
priorityCounts.forEach((value, key) => { priorityCountsObj[key] = value; });
|
|
256
|
+
// Build response
|
|
257
|
+
const stats = {
|
|
258
|
+
project: {
|
|
259
|
+
name: graph.metadata.project_name,
|
|
260
|
+
version: graph.metadata.version,
|
|
261
|
+
created: graph.metadata.created_at,
|
|
262
|
+
updated: graph.metadata.updated_at,
|
|
263
|
+
},
|
|
264
|
+
tasks: {
|
|
265
|
+
total: totalTasks,
|
|
266
|
+
root: rootTasks.length,
|
|
267
|
+
orphan: orphanTasks.length,
|
|
268
|
+
rootTaskIds: rootTasks,
|
|
269
|
+
orphanTaskIds: orphanTasks,
|
|
270
|
+
statusCounts: statusCountsObj,
|
|
271
|
+
priorityCounts: priorityCountsObj,
|
|
272
|
+
},
|
|
273
|
+
};
|
|
274
|
+
return sendSuccess(res, stats);
|
|
275
|
+
}));
|
|
276
|
+
}
|
|
277
|
+
//# sourceMappingURL=graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../../../src/web/routes/graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Projects Routes - Global project registry endpoints
|
|
3
|
+
*
|
|
4
|
+
* Provides endpoints for listing and managing registered Octie projects.
|
|
5
|
+
*
|
|
6
|
+
* @module web/routes/projects
|
|
7
|
+
*/
|
|
8
|
+
import type { Router } from 'express';
|
|
9
|
+
/**
|
|
10
|
+
* Register project routes
|
|
11
|
+
* @param router - Express Router instance
|
|
12
|
+
*/
|
|
13
|
+
export declare function registerProjectsRoutes(router: Router): void;
|
|
14
|
+
//# sourceMappingURL=projects.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../../src/web/routes/projects.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAqB,MAAM,EAAE,MAAM,SAAS,CAAC;AA6DzD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAgE3D"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Projects Routes - Global project registry endpoints
|
|
3
|
+
*
|
|
4
|
+
* Provides endpoints for listing and managing registered Octie projects.
|
|
5
|
+
*
|
|
6
|
+
* @module web/routes/projects
|
|
7
|
+
*/
|
|
8
|
+
import { getAllProjects, verifyProjectExists, loadRegistry, saveRegistry, } from '../../core/registry/index.js';
|
|
9
|
+
import { ERROR_SUGGESTIONS } from '../../types/index.js';
|
|
10
|
+
/**
|
|
11
|
+
* Async error handler wrapper
|
|
12
|
+
*/
|
|
13
|
+
function asyncHandler(fn) {
|
|
14
|
+
return (req, res, next) => {
|
|
15
|
+
Promise.resolve(fn(req, res)).catch(next);
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Send successful API response
|
|
20
|
+
*/
|
|
21
|
+
function sendSuccess(res, data, status = 200) {
|
|
22
|
+
res.status(status).json({
|
|
23
|
+
success: true,
|
|
24
|
+
data,
|
|
25
|
+
timestamp: new Date().toISOString(),
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Send error API response
|
|
30
|
+
*/
|
|
31
|
+
function sendError(res, code, message, status = 400, details, suggestion) {
|
|
32
|
+
res.status(status).json({
|
|
33
|
+
success: false,
|
|
34
|
+
error: {
|
|
35
|
+
code,
|
|
36
|
+
message,
|
|
37
|
+
suggestion: suggestion ?? ERROR_SUGGESTIONS[code],
|
|
38
|
+
details,
|
|
39
|
+
},
|
|
40
|
+
timestamp: new Date().toISOString(),
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Register project routes
|
|
45
|
+
* @param router - Express Router instance
|
|
46
|
+
*/
|
|
47
|
+
export function registerProjectsRoutes(router) {
|
|
48
|
+
/**
|
|
49
|
+
* GET /api/projects
|
|
50
|
+
* List all registered projects with existence status
|
|
51
|
+
*/
|
|
52
|
+
router.get('/api/projects', asyncHandler(async (_req, res) => {
|
|
53
|
+
const projects = getAllProjects();
|
|
54
|
+
// Add existence status to each project
|
|
55
|
+
const projectsWithStatus = projects.map(project => ({
|
|
56
|
+
...project,
|
|
57
|
+
exists: verifyProjectExists(project),
|
|
58
|
+
}));
|
|
59
|
+
return sendSuccess(res, {
|
|
60
|
+
projects: projectsWithStatus,
|
|
61
|
+
count: projectsWithStatus.length,
|
|
62
|
+
});
|
|
63
|
+
}));
|
|
64
|
+
/**
|
|
65
|
+
* DELETE /api/projects/:path
|
|
66
|
+
* Remove a project from the registry (by encoded path)
|
|
67
|
+
*/
|
|
68
|
+
router.delete('/api/projects/*', asyncHandler(async (req, res) => {
|
|
69
|
+
// Decode the path from URL
|
|
70
|
+
const encodedPath = req.params[0] ?? '';
|
|
71
|
+
const projectPath = decodeURIComponent(encodedPath);
|
|
72
|
+
const registry = loadRegistry();
|
|
73
|
+
let found = false;
|
|
74
|
+
for (const [key, project] of Object.entries(registry.projects)) {
|
|
75
|
+
if (project.path === projectPath) {
|
|
76
|
+
delete registry.projects[key];
|
|
77
|
+
found = true;
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (!found) {
|
|
82
|
+
return sendError(res, 'PROJECT_NOT_FOUND', 'Project not found in registry', 404);
|
|
83
|
+
}
|
|
84
|
+
saveRegistry(registry);
|
|
85
|
+
return sendSuccess(res, {
|
|
86
|
+
removed: true,
|
|
87
|
+
path: projectPath,
|
|
88
|
+
});
|
|
89
|
+
}));
|
|
90
|
+
/**
|
|
91
|
+
* GET /api/registry/path
|
|
92
|
+
* Get the global registry file path
|
|
93
|
+
*/
|
|
94
|
+
router.get('/api/registry/path', asyncHandler(async (_req, res) => {
|
|
95
|
+
const { getGlobalRegistryPath } = await import('../../core/registry/index.js');
|
|
96
|
+
const registryPath = getGlobalRegistryPath();
|
|
97
|
+
return sendSuccess(res, {
|
|
98
|
+
path: registryPath,
|
|
99
|
+
});
|
|
100
|
+
}));
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=projects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.js","sourceRoot":"","sources":["../../../src/web/routes/projects.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task Routes - RESTful CRUD endpoints for task management
|
|
3
|
+
*
|
|
4
|
+
* Provides complete CRUD operations for tasks via REST API.
|
|
5
|
+
* All endpoints use Zod validation and proper HTTP status codes.
|
|
6
|
+
*
|
|
7
|
+
* @module web/routes/tasks
|
|
8
|
+
*/
|
|
9
|
+
import type { Router } from 'express';
|
|
10
|
+
import type { TaskGraphStore } from '../../core/graph/index.js';
|
|
11
|
+
/**
|
|
12
|
+
* Register task routes
|
|
13
|
+
* @param router - Express Router instance
|
|
14
|
+
* @param getGraph - Function to get the current graph instance
|
|
15
|
+
*/
|
|
16
|
+
export declare function registerTaskRoutes(router: Router, getGraph: () => TaskGraphStore | null): void;
|
|
17
|
+
//# sourceMappingURL=tasks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../../src/web/routes/tasks.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAqB,MAAM,EAAE,MAAM,SAAS,CAAC;AAEzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAwIhE;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,cAAc,GAAG,IAAI,GACpC,IAAI,CAwcN"}
|