@geanatz/cortex-mcp 5.0.1

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 (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +281 -0
  3. package/dist/errors/errors.d.ts +109 -0
  4. package/dist/errors/errors.js +199 -0
  5. package/dist/errors/index.d.ts +4 -0
  6. package/dist/errors/index.js +4 -0
  7. package/dist/features/task-management/models/artifact.d.ts +169 -0
  8. package/dist/features/task-management/models/artifact.js +155 -0
  9. package/dist/features/task-management/models/config.d.ts +54 -0
  10. package/dist/features/task-management/models/config.js +54 -0
  11. package/dist/features/task-management/models/index.d.ts +6 -0
  12. package/dist/features/task-management/models/index.js +6 -0
  13. package/dist/features/task-management/models/task.d.ts +173 -0
  14. package/dist/features/task-management/models/task.js +84 -0
  15. package/dist/features/task-management/storage/file-storage.d.ts +130 -0
  16. package/dist/features/task-management/storage/file-storage.js +575 -0
  17. package/dist/features/task-management/storage/index.d.ts +5 -0
  18. package/dist/features/task-management/storage/index.js +5 -0
  19. package/dist/features/task-management/storage/storage.d.ts +159 -0
  20. package/dist/features/task-management/storage/storage.js +37 -0
  21. package/dist/features/task-management/tools/artifacts/index.d.ts +6 -0
  22. package/dist/features/task-management/tools/artifacts/index.js +174 -0
  23. package/dist/features/task-management/tools/base/handlers.d.ts +7 -0
  24. package/dist/features/task-management/tools/base/handlers.js +15 -0
  25. package/dist/features/task-management/tools/base/index.d.ts +3 -0
  26. package/dist/features/task-management/tools/base/index.js +3 -0
  27. package/dist/features/task-management/tools/base/schemas.d.ts +3 -0
  28. package/dist/features/task-management/tools/base/schemas.js +6 -0
  29. package/dist/features/task-management/tools/base/types.d.ts +13 -0
  30. package/dist/features/task-management/tools/base/types.js +1 -0
  31. package/dist/features/task-management/tools/tasks/index.d.ts +10 -0
  32. package/dist/features/task-management/tools/tasks/index.js +500 -0
  33. package/dist/index.d.ts +2 -0
  34. package/dist/index.js +57 -0
  35. package/dist/server.d.ts +11 -0
  36. package/dist/server.js +61 -0
  37. package/dist/types/common.d.ts +10 -0
  38. package/dist/types/common.js +1 -0
  39. package/dist/types/index.d.ts +5 -0
  40. package/dist/types/index.js +5 -0
  41. package/dist/utils/cache.d.ts +104 -0
  42. package/dist/utils/cache.js +196 -0
  43. package/dist/utils/file-utils.d.ts +101 -0
  44. package/dist/utils/file-utils.js +270 -0
  45. package/dist/utils/index.d.ts +12 -0
  46. package/dist/utils/index.js +12 -0
  47. package/dist/utils/logger.d.ts +77 -0
  48. package/dist/utils/logger.js +173 -0
  49. package/dist/utils/response-builder.d.ts +4 -0
  50. package/dist/utils/response-builder.js +19 -0
  51. package/dist/utils/storage-config.d.ts +29 -0
  52. package/dist/utils/storage-config.js +51 -0
  53. package/dist/utils/string-utils.d.ts +2 -0
  54. package/dist/utils/string-utils.js +16 -0
  55. package/dist/utils/validation.d.ts +9 -0
  56. package/dist/utils/validation.js +9 -0
  57. package/dist/utils/version.d.ts +9 -0
  58. package/dist/utils/version.js +41 -0
  59. package/package.json +60 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Geanatz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,281 @@
1
+ # Cortex MCP - Task-Based Orchestration for AI Workflows
2
+
3
+ An MCP (Model Context Protocol) server for managing task-based workflows with artifact support across five orchestration phases: Explore, Search, Plan, Build, and Test.
4
+
5
+ ## Features
6
+
7
+ - **Simplified Task Management** - Parent tasks with inline subtasks, no separate folders
8
+ - **Phase-Aware Artifacts** - Store and manage artifacts for each orchestration phase (explore, search, plan, build, test)
9
+ - **File-Based Storage** - All data stored in `.cortex/` directory with no database required
10
+ - **In-Memory Caching** - High-performance caching layer with TTL for frequently accessed tasks
11
+ - **Structured Logging** - Comprehensive logging with configurable levels
12
+
13
+ ## Installation
14
+
15
+ ### Using npx (Recommended)
16
+
17
+ Run the latest version without installing:
18
+
19
+ ```bash
20
+ npx -y @geanatz/cortex-mcp@latest
21
+ ```
22
+
23
+ ### Global Installation
24
+
25
+ ```bash
26
+ npm install -g @geanatz/cortex-mcp
27
+ ```
28
+
29
+ ### Local Installation
30
+
31
+ ```bash
32
+ npm install @geanatz/cortex-mcp
33
+ ```
34
+
35
+ ## Usage
36
+
37
+ ### Starting the Server
38
+
39
+ ```bash
40
+ # Project-specific mode (stores in .cortex/ )
41
+ cortex-mcp
42
+
43
+ # Global mode (stores in ~/.cortex/)
44
+ cortex-mcp --claude
45
+ ```
46
+
47
+ ### MCP Configuration
48
+
49
+ Add to your MCP settings (e.g., Claude Desktop, Cursor, etc.):
50
+
51
+ ```json
52
+ {
53
+ "cortex": {
54
+ "type": "local",
55
+ "enabled": true,
56
+ "command": [
57
+ "npx",
58
+ "-y",
59
+ "@geanatz/cortex-mcp@latest"
60
+ ]
61
+ }
62
+ }
63
+ ```
64
+
65
+ Or for global mode:
66
+
67
+ ```json
68
+ {
69
+ "cortex": {
70
+ "type": "local",
71
+ "enabled": true,
72
+ "command": [
73
+ "npx",
74
+ "-y",
75
+ "@geanatz/cortex-mcp@latest",
76
+ "--claude"
77
+ ]
78
+ }
79
+ }
80
+ ```
81
+
82
+ ### Creating Tasks
83
+
84
+ ```
85
+ Tool: create_task
86
+ Parameters:
87
+ - workingDirectory: path where tasks are stored
88
+ - details: task description (generates task ID)
89
+ - status (optional): pending | in_progress | done
90
+ - tags (optional): categorization tags
91
+ ```
92
+
93
+ ### Managing Subtasks
94
+
95
+ Subtasks are created using `update_task` with the `addSubtask` parameter:
96
+
97
+ ```
98
+ Tool: update_task
99
+ Parameters:
100
+ - id: parent task ID
101
+ - addSubtask: { details: "Subtask description", status: "pending" }
102
+ - updateSubtask: { id: "1", status: "done" }
103
+ - removeSubtaskId: "1"
104
+ ```
105
+
106
+ ### Managing Artifacts
107
+
108
+ Each task can have artifacts for 5 phases:
109
+ - **explore**: Codebase analysis and discovery findings
110
+ - **search**: External research and documentation findings
111
+ - **plan**: Implementation approach and step-by-step plan
112
+ - **build**: Implementation changes and modifications made
113
+ - **test**: Test execution results and verification status
114
+
115
+ ```
116
+ Tools: create_{phase}, update_{phase}, delete_{phase}
117
+ Parameters:
118
+ - workingDirectory: project directory
119
+ - taskId: which task to attach artifact to
120
+ - content: markdown content
121
+ - status: pending | in-progress | completed | failed | skipped
122
+ - retries, error: optional metadata
123
+ ```
124
+
125
+ ## Storage Format
126
+
127
+ Tasks are stored in `.cortex/tasks/{number}-{slug}/` directories:
128
+
129
+ ```
130
+ .cortex/
131
+ └── tasks/
132
+ ├── 001-implement-auth/
133
+ │ ├── .task.json (parent task + subtasks array)
134
+ │ ├── explore.md (explore phase artifact)
135
+ │ ├── search.md (search phase artifact)
136
+ │ ├── plan.md (plan phase artifact)
137
+ │ ├── build.md (build phase artifact)
138
+ │ └── test.md (test phase artifact)
139
+ └── 002-setup-database/
140
+ ├── .task.json
141
+ └── ... (optional artifacts)
142
+ ```
143
+
144
+ ### Task JSON Structure
145
+
146
+ ```json
147
+ {
148
+ "id": "001-implement-auth",
149
+ "details": "Implement authentication system",
150
+ "status": "in_progress",
151
+ "tags": ["auth", "backend"],
152
+ "createdAt": "2024-01-01T00:00:00Z",
153
+ "updatedAt": "2024-01-01T00:00:00Z",
154
+ "actualHours": 2.5,
155
+ "subtasks": [
156
+ { "id": "1", "details": "Setup JWT library", "status": "done" },
157
+ { "id": "2", "details": "Create login endpoint", "status": "in_progress" },
158
+ { "id": "3", "details": "Add middleware", "status": "pending" }
159
+ ]
160
+ }
161
+ ```
162
+
163
+ ## Data Model
164
+
165
+ ### Task (Parent)
166
+ ```typescript
167
+ interface Task {
168
+ id: string; // Task ID (e.g., "001-implement-auth")
169
+ details: string; // Full task description
170
+ status: 'pending' | 'in_progress' | 'done';
171
+ createdAt: string; // ISO 8601 timestamp
172
+ updatedAt: string; // Last modification timestamp
173
+ tags?: string[]; // Categorization tags
174
+ actualHours?: number; // Time tracking
175
+ subtasks: Subtask[]; // Array of subtasks
176
+ }
177
+ ```
178
+
179
+ ### Subtask
180
+ ```typescript
181
+ interface Subtask {
182
+ id: string; // Simple ID ("1", "2", etc.)
183
+ details: string; // Subtask description
184
+ status: 'pending' | 'in_progress' | 'done';
185
+ }
186
+ ```
187
+
188
+ ### Artifact
189
+ ```typescript
190
+ interface Artifact {
191
+ metadata: {
192
+ phase: 'explore' | 'search' | 'plan' | 'build' | 'test';
193
+ status: 'pending' | 'in-progress' | 'completed' | 'failed' | 'skipped';
194
+ createdAt: string; // ISO 8601
195
+ updatedAt: string; // ISO 8601
196
+ retries?: number; // Attempt count
197
+ error?: string; // Error message if status=failed
198
+ }
199
+ content: string; // Markdown content
200
+ }
201
+ ```
202
+
203
+ ## Available Tools
204
+
205
+ ### Task Management
206
+ - `create_task` - Create a new parent task
207
+ - `list_tasks` - List all tasks with subtasks
208
+ - `get_task` - Get task details including subtasks and artifacts
209
+ - `update_task` - Update task and manage subtasks
210
+ - `delete_task` - Delete task and all its subtasks
211
+
212
+ ### Artifact Management
213
+ - `create_explore` - Create explore phase artifact
214
+ - `update_explore` - Update explore phase artifact
215
+ - `delete_explore` - Delete explore phase artifact
216
+ - `create_search` - Create search phase artifact
217
+ - `update_search` - Update search phase artifact
218
+ - `delete_search` - Delete search phase artifact
219
+ - `create_plan` - Create plan phase artifact
220
+ - `update_plan` - Update plan phase artifact
221
+ - `delete_plan` - Delete plan phase artifact
222
+ - `create_build` - Create build phase artifact
223
+ - `update_build` - Update build phase artifact
224
+ - `delete_build` - Delete build phase artifact
225
+ - `create_test` - Create test phase artifact
226
+ - `update_test` - Update test phase artifact
227
+ - `delete_test` - Delete test phase artifact
228
+
229
+ ## Configuration
230
+
231
+ ### Environment Variables
232
+ - `DEBUG=true` - Enable debug logging
233
+
234
+ ### Command-Line Flags
235
+ - `--claude` - Use global directory mode (~/.cortex/)
236
+
237
+ ## Development
238
+
239
+ ```bash
240
+ # Build TypeScript
241
+ npm run build
242
+
243
+ # Watch mode
244
+ npm run dev
245
+
246
+ # Start server
247
+ npm start
248
+ ```
249
+
250
+ ### Build Optimization
251
+ - Uses TypeScript with incremental builds
252
+ - Optimized for <5s build times with ~800MB memory usage
253
+ - Proper closure elimination for fast type inference
254
+
255
+ ## Architecture
256
+
257
+ - **Clean layering** - Types → Utilities → Storage → Tools → Server
258
+ - **No circular dependencies** - Easy to understand data flow
259
+ - **Abstract storage** - File-based implementation, easily extensible
260
+ - **MCP-compliant** - Full compliance with Model Context Protocol specification
261
+
262
+ ## Version
263
+
264
+ Current version: **5.0.0**
265
+
266
+ - v5.0.0: Simplified model - subtasks stored inline, removed dependencies, removed move_task
267
+ - v4.0.0: Complete refactor with artifact support and optimized build
268
+ - v3.x: Legacy memory features (deprecated)
269
+ - v1.x: Initial implementation
270
+
271
+ ## License
272
+
273
+ MIT - See LICENSE file for details
274
+
275
+ ## Author
276
+
277
+ Geanatz
278
+
279
+ ## Contributing
280
+
281
+ Contributions welcome!
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Custom error classes for the application
3
+ * Provides typed, hierarchical error handling
4
+ */
5
+ /**
6
+ * Base application error class
7
+ * All custom errors should extend this
8
+ */
9
+ export declare abstract class AppError extends Error {
10
+ readonly code: string;
11
+ readonly timestamp: Date;
12
+ readonly context?: Record<string, unknown>;
13
+ constructor(message: string, code: string, context?: Record<string, unknown>);
14
+ /**
15
+ * Convert error to JSON-serializable object
16
+ */
17
+ toJSON(): Record<string, unknown>;
18
+ }
19
+ /**
20
+ * Error codes enum for type-safe error handling
21
+ */
22
+ export declare const ErrorCodes: {
23
+ readonly VALIDATION_ERROR: "VALIDATION_ERROR";
24
+ readonly INVALID_INPUT: "INVALID_INPUT";
25
+ readonly REQUIRED_FIELD_MISSING: "REQUIRED_FIELD_MISSING";
26
+ readonly INVALID_FORMAT: "INVALID_FORMAT";
27
+ readonly NOT_FOUND: "NOT_FOUND";
28
+ readonly TASK_NOT_FOUND: "TASK_NOT_FOUND";
29
+ readonly ARTIFACT_NOT_FOUND: "ARTIFACT_NOT_FOUND";
30
+ readonly PARENT_NOT_FOUND: "PARENT_NOT_FOUND";
31
+ readonly DEPENDENCY_NOT_FOUND: "DEPENDENCY_NOT_FOUND";
32
+ readonly ALREADY_EXISTS: "ALREADY_EXISTS";
33
+ readonly CIRCULAR_REFERENCE: "CIRCULAR_REFERENCE";
34
+ readonly SELF_REFERENCE: "SELF_REFERENCE";
35
+ readonly STORAGE_ERROR: "STORAGE_ERROR";
36
+ readonly FILE_READ_ERROR: "FILE_READ_ERROR";
37
+ readonly FILE_WRITE_ERROR: "FILE_WRITE_ERROR";
38
+ readonly DIRECTORY_ERROR: "DIRECTORY_ERROR";
39
+ readonly PARSE_ERROR: "PARSE_ERROR";
40
+ readonly INITIALIZATION_ERROR: "INITIALIZATION_ERROR";
41
+ readonly CONFIGURATION_ERROR: "CONFIGURATION_ERROR";
42
+ readonly UNKNOWN_ERROR: "UNKNOWN_ERROR";
43
+ };
44
+ export type ErrorCode = typeof ErrorCodes[keyof typeof ErrorCodes];
45
+ /**
46
+ * Validation error for input validation failures
47
+ */
48
+ export declare class ValidationError extends AppError {
49
+ readonly field?: string;
50
+ readonly value?: unknown;
51
+ constructor(message: string, field?: string, value?: unknown, context?: Record<string, unknown>);
52
+ static requiredField(field: string): ValidationError;
53
+ static invalidFormat(field: string, expected: string, received?: unknown): ValidationError;
54
+ static maxLength(field: string, max: number, actual: number): ValidationError;
55
+ static minLength(field: string, min: number, actual: number): ValidationError;
56
+ static emptyString(field: string): ValidationError;
57
+ }
58
+ /**
59
+ * Not found error for missing resources
60
+ */
61
+ export declare class NotFoundError extends AppError {
62
+ readonly resourceType: string;
63
+ readonly resourceId: string;
64
+ constructor(resourceType: string, resourceId: string, context?: Record<string, unknown>);
65
+ static task(taskId: string): NotFoundError;
66
+ static artifact(taskId: string, phase: string): NotFoundError;
67
+ static parent(parentId: string): NotFoundError;
68
+ static dependency(depId: string): NotFoundError;
69
+ }
70
+ /**
71
+ * Conflict error for operations that would create invalid states
72
+ */
73
+ export declare class ConflictError extends AppError {
74
+ constructor(message: string, code?: ErrorCode, context?: Record<string, unknown>);
75
+ static circularReference(taskId: string, targetId: string): ConflictError;
76
+ static selfReference(taskId: string, operation: string): ConflictError;
77
+ }
78
+ /**
79
+ * Storage error for file system operations
80
+ */
81
+ export declare class StorageError extends AppError {
82
+ readonly path?: string;
83
+ readonly operation?: string;
84
+ constructor(message: string, code?: ErrorCode, path?: string, operation?: string, context?: Record<string, unknown>);
85
+ static readError(path: string, originalError?: Error): StorageError;
86
+ static writeError(path: string, originalError?: Error): StorageError;
87
+ static directoryError(path: string, originalError?: Error): StorageError;
88
+ static parseError(path: string, format: string, originalError?: Error): StorageError;
89
+ static initializationError(path: string, message: string): StorageError;
90
+ }
91
+ /**
92
+ * Type guard to check if an error is an AppError
93
+ */
94
+ export declare function isAppError(error: unknown): error is AppError;
95
+ /**
96
+ * Type guard for specific error types
97
+ */
98
+ export declare function isValidationError(error: unknown): error is ValidationError;
99
+ export declare function isNotFoundError(error: unknown): error is NotFoundError;
100
+ export declare function isConflictError(error: unknown): error is ConflictError;
101
+ export declare function isStorageError(error: unknown): error is StorageError;
102
+ /**
103
+ * Extract error message from unknown error
104
+ */
105
+ export declare function getErrorMessage(error: unknown): string;
106
+ /**
107
+ * Wrap unknown errors in AppError
108
+ */
109
+ export declare function wrapError(error: unknown, fallbackMessage?: string): AppError;
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Custom error classes for the application
3
+ * Provides typed, hierarchical error handling
4
+ */
5
+ /**
6
+ * Base application error class
7
+ * All custom errors should extend this
8
+ */
9
+ export class AppError extends Error {
10
+ code;
11
+ timestamp;
12
+ context;
13
+ constructor(message, code, context) {
14
+ super(message);
15
+ this.name = this.constructor.name;
16
+ this.code = code;
17
+ this.timestamp = new Date();
18
+ this.context = context;
19
+ // Maintains proper stack trace for where error was thrown
20
+ Error.captureStackTrace?.(this, this.constructor);
21
+ }
22
+ /**
23
+ * Convert error to JSON-serializable object
24
+ */
25
+ toJSON() {
26
+ return {
27
+ name: this.name,
28
+ message: this.message,
29
+ code: this.code,
30
+ timestamp: this.timestamp.toISOString(),
31
+ context: this.context,
32
+ };
33
+ }
34
+ }
35
+ /**
36
+ * Error codes enum for type-safe error handling
37
+ */
38
+ export const ErrorCodes = {
39
+ // Validation errors (4xx equivalent)
40
+ VALIDATION_ERROR: 'VALIDATION_ERROR',
41
+ INVALID_INPUT: 'INVALID_INPUT',
42
+ REQUIRED_FIELD_MISSING: 'REQUIRED_FIELD_MISSING',
43
+ INVALID_FORMAT: 'INVALID_FORMAT',
44
+ // Resource errors
45
+ NOT_FOUND: 'NOT_FOUND',
46
+ TASK_NOT_FOUND: 'TASK_NOT_FOUND',
47
+ ARTIFACT_NOT_FOUND: 'ARTIFACT_NOT_FOUND',
48
+ PARENT_NOT_FOUND: 'PARENT_NOT_FOUND',
49
+ DEPENDENCY_NOT_FOUND: 'DEPENDENCY_NOT_FOUND',
50
+ // Conflict errors
51
+ ALREADY_EXISTS: 'ALREADY_EXISTS',
52
+ CIRCULAR_REFERENCE: 'CIRCULAR_REFERENCE',
53
+ SELF_REFERENCE: 'SELF_REFERENCE',
54
+ // Storage errors
55
+ STORAGE_ERROR: 'STORAGE_ERROR',
56
+ FILE_READ_ERROR: 'FILE_READ_ERROR',
57
+ FILE_WRITE_ERROR: 'FILE_WRITE_ERROR',
58
+ DIRECTORY_ERROR: 'DIRECTORY_ERROR',
59
+ PARSE_ERROR: 'PARSE_ERROR',
60
+ // System errors
61
+ INITIALIZATION_ERROR: 'INITIALIZATION_ERROR',
62
+ CONFIGURATION_ERROR: 'CONFIGURATION_ERROR',
63
+ UNKNOWN_ERROR: 'UNKNOWN_ERROR',
64
+ };
65
+ /**
66
+ * Validation error for input validation failures
67
+ */
68
+ export class ValidationError extends AppError {
69
+ field;
70
+ value;
71
+ constructor(message, field, value, context) {
72
+ super(message, ErrorCodes.VALIDATION_ERROR, { ...context, field, value });
73
+ this.field = field;
74
+ this.value = value;
75
+ }
76
+ static requiredField(field) {
77
+ return new ValidationError(`${field} is required.`, field, undefined, { code: ErrorCodes.REQUIRED_FIELD_MISSING });
78
+ }
79
+ static invalidFormat(field, expected, received) {
80
+ return new ValidationError(`Invalid format for ${field}. Expected ${expected}.`, field, received, { code: ErrorCodes.INVALID_FORMAT, expected });
81
+ }
82
+ static maxLength(field, max, actual) {
83
+ return new ValidationError(`${field} must be ${max} characters or less (got ${actual}).`, field, undefined, { code: ErrorCodes.INVALID_INPUT, max, actual });
84
+ }
85
+ static minLength(field, min, actual) {
86
+ return new ValidationError(`${field} must be at least ${min} characters (got ${actual}).`, field, undefined, { code: ErrorCodes.INVALID_INPUT, min, actual });
87
+ }
88
+ static emptyString(field) {
89
+ return new ValidationError(`${field} must not be empty.`, field, '', { code: ErrorCodes.INVALID_INPUT });
90
+ }
91
+ }
92
+ /**
93
+ * Not found error for missing resources
94
+ */
95
+ export class NotFoundError extends AppError {
96
+ resourceType;
97
+ resourceId;
98
+ constructor(resourceType, resourceId, context) {
99
+ super(`${resourceType} with ID "${resourceId}" not found.`, ErrorCodes.NOT_FOUND, { ...context, resourceType, resourceId });
100
+ this.resourceType = resourceType;
101
+ this.resourceId = resourceId;
102
+ }
103
+ static task(taskId) {
104
+ return new NotFoundError('Task', taskId, { code: ErrorCodes.TASK_NOT_FOUND });
105
+ }
106
+ static artifact(taskId, phase) {
107
+ return new NotFoundError(`${phase} artifact`, taskId, { code: ErrorCodes.ARTIFACT_NOT_FOUND, phase });
108
+ }
109
+ static parent(parentId) {
110
+ return new NotFoundError('Parent task', parentId, { code: ErrorCodes.PARENT_NOT_FOUND });
111
+ }
112
+ static dependency(depId) {
113
+ return new NotFoundError('Dependency task', depId, { code: ErrorCodes.DEPENDENCY_NOT_FOUND });
114
+ }
115
+ }
116
+ /**
117
+ * Conflict error for operations that would create invalid states
118
+ */
119
+ export class ConflictError extends AppError {
120
+ constructor(message, code = ErrorCodes.CIRCULAR_REFERENCE, context) {
121
+ super(message, code, context);
122
+ }
123
+ static circularReference(taskId, targetId) {
124
+ return new ConflictError(`Moving task would create a circular reference.`, ErrorCodes.CIRCULAR_REFERENCE, { taskId, targetId });
125
+ }
126
+ static selfReference(taskId, operation) {
127
+ return new ConflictError(`Task cannot ${operation} itself.`, ErrorCodes.SELF_REFERENCE, { taskId, operation });
128
+ }
129
+ }
130
+ /**
131
+ * Storage error for file system operations
132
+ */
133
+ export class StorageError extends AppError {
134
+ path;
135
+ operation;
136
+ constructor(message, code = ErrorCodes.STORAGE_ERROR, path, operation, context) {
137
+ super(message, code, { ...context, path, operation });
138
+ this.path = path;
139
+ this.operation = operation;
140
+ }
141
+ static readError(path, originalError) {
142
+ return new StorageError(`Failed to read file: ${path}`, ErrorCodes.FILE_READ_ERROR, path, 'read', { originalError: originalError?.message });
143
+ }
144
+ static writeError(path, originalError) {
145
+ return new StorageError(`Failed to write file: ${path}`, ErrorCodes.FILE_WRITE_ERROR, path, 'write', { originalError: originalError?.message });
146
+ }
147
+ static directoryError(path, originalError) {
148
+ return new StorageError(`Directory operation failed: ${path}`, ErrorCodes.DIRECTORY_ERROR, path, 'directory', { originalError: originalError?.message });
149
+ }
150
+ static parseError(path, format, originalError) {
151
+ return new StorageError(`Failed to parse ${format} file: ${path}`, ErrorCodes.PARSE_ERROR, path, 'parse', { format, originalError: originalError?.message });
152
+ }
153
+ static initializationError(path, message) {
154
+ return new StorageError(message, ErrorCodes.INITIALIZATION_ERROR, path, 'initialize');
155
+ }
156
+ }
157
+ /**
158
+ * Type guard to check if an error is an AppError
159
+ */
160
+ export function isAppError(error) {
161
+ return error instanceof AppError;
162
+ }
163
+ /**
164
+ * Type guard for specific error types
165
+ */
166
+ export function isValidationError(error) {
167
+ return error instanceof ValidationError;
168
+ }
169
+ export function isNotFoundError(error) {
170
+ return error instanceof NotFoundError;
171
+ }
172
+ export function isConflictError(error) {
173
+ return error instanceof ConflictError;
174
+ }
175
+ export function isStorageError(error) {
176
+ return error instanceof StorageError;
177
+ }
178
+ /**
179
+ * Extract error message from unknown error
180
+ */
181
+ export function getErrorMessage(error) {
182
+ if (error instanceof Error) {
183
+ return error.message;
184
+ }
185
+ if (typeof error === 'string') {
186
+ return error;
187
+ }
188
+ return 'An unknown error occurred';
189
+ }
190
+ /**
191
+ * Wrap unknown errors in AppError
192
+ */
193
+ export function wrapError(error, fallbackMessage) {
194
+ if (isAppError(error)) {
195
+ return error;
196
+ }
197
+ const message = getErrorMessage(error) || fallbackMessage || 'Unknown error';
198
+ return new StorageError(message, ErrorCodes.UNKNOWN_ERROR);
199
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Central error exports
3
+ */
4
+ export * from './errors.js';
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Central error exports
3
+ */
4
+ export * from './errors.js';