task-o-matic 0.0.14 → 0.0.15

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 (110) hide show
  1. package/dist/cli/display/progress.d.ts +15 -2
  2. package/dist/cli/display/progress.d.ts.map +1 -1
  3. package/dist/cli/display/progress.js +72 -4
  4. package/dist/commands/benchmark.d.ts.map +1 -1
  5. package/dist/commands/benchmark.js +11 -3
  6. package/dist/commands/init.d.ts.map +1 -1
  7. package/dist/commands/init.js +19 -4
  8. package/dist/commands/prd.js +7 -1
  9. package/dist/commands/tasks/delete.d.ts.map +1 -1
  10. package/dist/commands/tasks/delete.js +2 -1
  11. package/dist/commands/tasks/document/add.d.ts.map +1 -1
  12. package/dist/commands/tasks/document/add.js +2 -1
  13. package/dist/commands/tasks/document/get.d.ts.map +1 -1
  14. package/dist/commands/tasks/document/get.js +2 -1
  15. package/dist/commands/tasks/plan/set.d.ts.map +1 -1
  16. package/dist/commands/tasks/plan/set.js +11 -3
  17. package/dist/commands/tasks/show.d.ts.map +1 -1
  18. package/dist/commands/tasks/show.js +2 -1
  19. package/dist/commands/tasks/status.d.ts.map +1 -1
  20. package/dist/commands/tasks/status.js +2 -1
  21. package/dist/commands/tasks/update.d.ts.map +1 -1
  22. package/dist/commands/tasks/update.js +7 -1
  23. package/dist/lib/ai-service/model-provider.d.ts.map +1 -1
  24. package/dist/lib/ai-service/model-provider.js +37 -6
  25. package/dist/lib/ai-service/task-operations.d.ts +1 -0
  26. package/dist/lib/ai-service/task-operations.d.ts.map +1 -1
  27. package/dist/lib/ai-service/task-operations.js +135 -173
  28. package/dist/lib/benchmark/registry.d.ts.map +1 -1
  29. package/dist/lib/benchmark/registry.js +6 -10
  30. package/dist/lib/config-validation.d.ts +215 -0
  31. package/dist/lib/config-validation.d.ts.map +1 -0
  32. package/dist/lib/config-validation.js +246 -0
  33. package/dist/lib/config.d.ts.map +1 -1
  34. package/dist/lib/config.js +19 -5
  35. package/dist/lib/storage/file-system.d.ts.map +1 -1
  36. package/dist/lib/storage/file-system.js +81 -21
  37. package/dist/lib/task-execution-core.d.ts.map +1 -1
  38. package/dist/lib/task-execution-core.js +3 -2
  39. package/dist/services/prd.d.ts +17 -0
  40. package/dist/services/prd.d.ts.map +1 -1
  41. package/dist/services/prd.js +49 -15
  42. package/dist/services/tasks.d.ts +315 -1
  43. package/dist/services/tasks.d.ts.map +1 -1
  44. package/dist/services/tasks.js +483 -107
  45. package/dist/services/workflow-ai-assistant.d.ts.map +1 -1
  46. package/dist/services/workflow-ai-assistant.js +19 -6
  47. package/dist/test/lib/ai-service/task-operations.test.d.ts +2 -0
  48. package/dist/test/lib/ai-service/task-operations.test.d.ts.map +1 -0
  49. package/dist/test/lib/ai-service/task-operations.test.js +362 -0
  50. package/dist/test/mocks/mock-ai-operations.d.ts +15 -0
  51. package/dist/test/mocks/mock-ai-operations.d.ts.map +1 -0
  52. package/dist/test/mocks/mock-ai-operations.js +107 -0
  53. package/dist/test/mocks/mock-context-builder.d.ts +10 -0
  54. package/dist/test/mocks/mock-context-builder.d.ts.map +1 -0
  55. package/dist/test/mocks/mock-context-builder.js +81 -0
  56. package/dist/test/mocks/mock-model-provider.d.ts +7 -0
  57. package/dist/test/mocks/mock-model-provider.d.ts.map +1 -0
  58. package/dist/test/mocks/mock-model-provider.js +21 -0
  59. package/dist/test/mocks/mock-service-factory.d.ts +11 -0
  60. package/dist/test/mocks/mock-service-factory.d.ts.map +1 -0
  61. package/dist/test/mocks/mock-service-factory.js +61 -0
  62. package/dist/test/mocks/mock-storage.d.ts +50 -0
  63. package/dist/test/mocks/mock-storage.d.ts.map +1 -0
  64. package/dist/test/mocks/mock-storage.js +145 -0
  65. package/dist/test/services/task-service.test.d.ts +2 -0
  66. package/dist/test/services/task-service.test.d.ts.map +1 -0
  67. package/dist/test/services/task-service.test.js +352 -0
  68. package/dist/test/test-mock-setup.d.ts +26 -0
  69. package/dist/test/test-mock-setup.d.ts.map +1 -0
  70. package/dist/test/test-mock-setup.js +41 -0
  71. package/dist/test/test-setup.d.ts +9 -0
  72. package/dist/test/test-setup.d.ts.map +1 -0
  73. package/dist/test/test-setup.js +44 -0
  74. package/dist/test/test-utils.d.ts +22 -0
  75. package/dist/test/test-utils.d.ts.map +1 -0
  76. package/dist/test/test-utils.js +37 -0
  77. package/dist/test/utils/ai-operation-utility.test.d.ts +2 -0
  78. package/dist/test/utils/ai-operation-utility.test.d.ts.map +1 -0
  79. package/dist/test/utils/ai-operation-utility.test.js +290 -0
  80. package/dist/test/utils/error-handling.test.d.ts +2 -0
  81. package/dist/test/utils/error-handling.test.d.ts.map +1 -0
  82. package/dist/test/utils/error-handling.test.js +231 -0
  83. package/dist/utils/ai-operation-utility.d.ts +142 -0
  84. package/dist/utils/ai-operation-utility.d.ts.map +1 -0
  85. package/dist/utils/ai-operation-utility.js +288 -0
  86. package/dist/utils/ai-service-factory.d.ts +10 -0
  87. package/dist/utils/ai-service-factory.d.ts.map +1 -1
  88. package/dist/utils/ai-service-factory.js +19 -1
  89. package/dist/utils/cli-validators.d.ts +2 -2
  90. package/dist/utils/cli-validators.d.ts.map +1 -1
  91. package/dist/utils/cli-validators.js +7 -6
  92. package/dist/utils/error-utils.d.ts +3 -3
  93. package/dist/utils/error-utils.d.ts.map +1 -1
  94. package/dist/utils/error-utils.js +5 -4
  95. package/dist/utils/file-utils.d.ts +4 -4
  96. package/dist/utils/file-utils.d.ts.map +1 -1
  97. package/dist/utils/file-utils.js +11 -6
  98. package/dist/utils/id-generator.d.ts +1 -1
  99. package/dist/utils/id-generator.d.ts.map +1 -1
  100. package/dist/utils/id-generator.js +8 -2
  101. package/dist/utils/model-executor-parser.d.ts +1 -1
  102. package/dist/utils/model-executor-parser.d.ts.map +1 -1
  103. package/dist/utils/model-executor-parser.js +3 -2
  104. package/dist/utils/storage-utils.d.ts +3 -3
  105. package/dist/utils/storage-utils.d.ts.map +1 -1
  106. package/dist/utils/storage-utils.js +7 -6
  107. package/dist/utils/task-o-matic-error.d.ts +206 -0
  108. package/dist/utils/task-o-matic-error.d.ts.map +1 -0
  109. package/dist/utils/task-o-matic-error.js +304 -0
  110. package/package.json +2 -2
@@ -34,6 +34,8 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.prdService = exports.PRDService = void 0;
37
+ exports.getPRDService = getPRDService;
38
+ const task_o_matic_error_1 = require("../utils/task-o-matic-error");
37
39
  const fs_1 = require("fs");
38
40
  const path_1 = require("path");
39
41
  const ai_service_factory_1 = require("../utils/ai-service-factory");
@@ -47,6 +49,18 @@ const file_utils_1 = require("../utils/file-utils");
47
49
  * Handles PRD parsing, task extraction, and PRD improvement
48
50
  */
49
51
  class PRDService {
52
+ storage;
53
+ aiOperations;
54
+ /**
55
+ * Create a new PRDService
56
+ *
57
+ * @param dependencies - Optional dependencies to inject (for testing)
58
+ */
59
+ constructor(dependencies = {}) {
60
+ // Use injected dependencies or fall back to singletons
61
+ this.storage = dependencies.storage ?? (0, ai_service_factory_1.getStorage)();
62
+ this.aiOperations = dependencies.aiOperations ?? (0, ai_service_factory_1.getAIOperations)();
63
+ }
50
64
  async parsePRD(input) {
51
65
  const startTime = Date.now();
52
66
  const steps = [];
@@ -59,7 +73,9 @@ class PRDService {
59
73
  // Ensure we're in a task-o-matic project
60
74
  const taskOMaticDir = config_1.configManager.getTaskOMaticDir();
61
75
  if (!(0, fs_1.existsSync)(taskOMaticDir)) {
62
- throw new Error(`Not a task-o-matic project. Run 'task-o-matic init init' first.`);
76
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.CONFIGURATION_ERROR, "Not a task-o-matic project. Run 'task-o-matic init init' first.", {
77
+ suggestions: ["Run `task-o-matic init init` in your project root."],
78
+ });
63
79
  }
64
80
  // Set working directory and reload config (DRY fix 1.4)
65
81
  const workingDir = input.workingDirectory || process.cwd();
@@ -94,7 +110,9 @@ class PRDService {
94
110
  // Validate AI provider if specified
95
111
  if (input.aiOptions?.aiProvider &&
96
112
  !(0, validation_1.isValidAIProvider)(input.aiOptions.aiProvider)) {
97
- throw new Error(`Invalid AI provider: ${input.aiOptions.aiProvider}`);
113
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.AI_CONFIGURATION_ERROR, `Invalid AI provider: ${input.aiOptions.aiProvider}`, {
114
+ suggestions: ["Use a valid AI provider, e.g., 'openai', 'anthropic'"],
115
+ });
98
116
  }
99
117
  const aiConfig = (0, ai_config_builder_1.buildAIConfig)(input.aiOptions);
100
118
  input.callbacks?.onProgress?.({
@@ -104,7 +122,7 @@ class PRDService {
104
122
  const stepStart2 = Date.now();
105
123
  // Use utility to wrap streaming options and capture metrics (DRY fix 1.1)
106
124
  const { options: metricsStreamingOptions, getMetrics } = (0, streaming_utils_1.createMetricsStreamingOptions)(input.streamingOptions, stepStart2);
107
- const result = await (0, ai_service_factory_1.getAIOperations)().parsePRD(prdContent, aiConfig, input.promptOverride, input.messageOverride, metricsStreamingOptions, undefined, // retryConfig
125
+ const result = await this.aiOperations.parsePRD(prdContent, aiConfig, input.promptOverride, input.messageOverride, metricsStreamingOptions, undefined, // retryConfig
108
126
  workingDir, // Pass working directory to AI operations
109
127
  input.enableFilesystemTools);
110
128
  // Extract metrics after AI call
@@ -130,7 +148,7 @@ class PRDService {
130
148
  current: i + 1,
131
149
  total: result.tasks.length,
132
150
  });
133
- const createdTask = await (0, ai_service_factory_1.getStorage)().createTask({
151
+ const createdTask = await this.storage.createTask({
134
152
  id: task.id, // Preserve AI-generated ID for dependencies
135
153
  title: task.title,
136
154
  description: task.description,
@@ -152,7 +170,7 @@ class PRDService {
152
170
  aiModel: input.aiOptions?.aiModel,
153
171
  generatedAt: Date.now(),
154
172
  };
155
- await (0, ai_service_factory_1.getStorage)().saveTaskAIMetadata(aiMetadata);
173
+ await this.storage.saveTaskAIMetadata(aiMetadata);
156
174
  }
157
175
  steps.push({
158
176
  step: "Create Tasks",
@@ -209,14 +227,16 @@ class PRDService {
209
227
  const prdContent = (0, fs_1.readFileSync)(input.file, "utf-8");
210
228
  if (input.aiOptions?.aiProvider &&
211
229
  !(0, validation_1.isValidAIProvider)(input.aiOptions.aiProvider)) {
212
- throw new Error(`Invalid AI provider: ${input.aiOptions.aiProvider}`);
230
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.AI_CONFIGURATION_ERROR, `Invalid AI provider: ${input.aiOptions.aiProvider}`, {
231
+ suggestions: ["Use a valid AI provider, e.g., 'openai', 'anthropic'"],
232
+ });
213
233
  }
214
234
  const aiConfig = (0, ai_config_builder_1.buildAIConfig)(input.aiOptions);
215
235
  input.callbacks?.onProgress?.({
216
236
  type: "progress",
217
237
  message: "Analyzing PRD with AI...",
218
238
  });
219
- const questions = await (0, ai_service_factory_1.getAIOperations)().generatePRDQuestions(prdContent, aiConfig, input.promptOverride, input.messageOverride, input.streamingOptions, undefined, workingDir, input.enableFilesystemTools);
239
+ const questions = await this.aiOperations.generatePRDQuestions(prdContent, aiConfig, input.promptOverride, input.messageOverride, input.streamingOptions, undefined, workingDir, input.enableFilesystemTools);
220
240
  input.callbacks?.onProgress?.({
221
241
  type: "completed",
222
242
  message: `Generated ${questions.length} questions`,
@@ -241,14 +261,16 @@ class PRDService {
241
261
  // Validate AI provider if specified
242
262
  if (input.aiOptions?.aiProvider &&
243
263
  !(0, validation_1.isValidAIProvider)(input.aiOptions.aiProvider)) {
244
- throw new Error(`Invalid AI provider: ${input.aiOptions.aiProvider}`);
264
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.AI_CONFIGURATION_ERROR, `Invalid AI provider: ${input.aiOptions.aiProvider}`, {
265
+ suggestions: ["Use a valid AI provider, e.g., 'openai', 'anthropic'"],
266
+ });
245
267
  }
246
268
  const aiConfig = (0, ai_config_builder_1.buildAIConfig)(input.aiOptions);
247
269
  input.callbacks?.onProgress?.({
248
270
  type: "progress",
249
271
  message: "Calling AI to improve PRD...",
250
272
  });
251
- const improvedPRD = await (0, ai_service_factory_1.getAIOperations)().reworkPRD(prdContent, input.feedback, aiConfig, input.promptOverride, input.messageOverride, input.streamingOptions, undefined, // retryConfig
273
+ const improvedPRD = await this.aiOperations.reworkPRD(prdContent, input.feedback, aiConfig, input.promptOverride, input.messageOverride, input.streamingOptions, undefined, // retryConfig
252
274
  workingDir, // Pass working directory to AI operations
253
275
  input.enableFilesystemTools);
254
276
  input.callbacks?.onProgress?.({
@@ -311,7 +333,7 @@ class PRDService {
311
333
  // User mode: return questions for CLI to prompt user
312
334
  // Answers should be provided in input.answers
313
335
  if (!input.answers || Object.keys(input.answers).length === 0) {
314
- throw new Error("User mode selected but no answers provided. CLI layer should collect answers.");
336
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, "User mode selected but no answers provided. CLI layer should collect answers.");
315
337
  }
316
338
  answers = input.answers;
317
339
  }
@@ -324,7 +346,7 @@ class PRDService {
324
346
  const prdContent = (0, fs_1.readFileSync)(input.file, "utf-8");
325
347
  // Use questionAIOptions if provided, otherwise use main aiOptions
326
348
  const answeringAIConfig = (0, ai_config_builder_1.buildAIConfig)(input.questionAIOptions || input.aiOptions);
327
- answers = await (0, ai_service_factory_1.getAIOperations)().answerPRDQuestions(prdContent, questions, answeringAIConfig, {
349
+ answers = await this.aiOperations.answerPRDQuestions(prdContent, questions, answeringAIConfig, {
328
350
  stackInfo,
329
351
  }, input.streamingOptions);
330
352
  }
@@ -391,7 +413,7 @@ class PRDService {
391
413
  },
392
414
  };
393
415
  const aiConfig = (0, ai_config_builder_1.buildAIConfig)(input.aiOptions);
394
- const content = await (0, ai_service_factory_1.getAIOperations)().generatePRD(input.description, aiConfig, undefined, undefined, metricsStreamingOptions);
416
+ const content = await this.aiOperations.generatePRD(input.description, aiConfig, undefined, undefined, metricsStreamingOptions);
395
417
  // Save file
396
418
  const taskOMaticDir = config_1.configManager.getTaskOMaticDir();
397
419
  const prdDir = input.outputDir || (0, path_1.join)(taskOMaticDir, "prd");
@@ -449,7 +471,7 @@ class PRDService {
449
471
  },
450
472
  };
451
473
  const aiConfig = (0, ai_config_builder_1.buildAIConfig)(input.aiOptions);
452
- const content = await (0, ai_service_factory_1.getAIOperations)().combinePRDs(input.prds, input.originalDescription, aiConfig, undefined, undefined, metricsStreamingOptions);
474
+ const content = await this.aiOperations.combinePRDs(input.prds, input.originalDescription, aiConfig, undefined, undefined, metricsStreamingOptions);
453
475
  // Save file
454
476
  const taskOMaticDir = config_1.configManager.getTaskOMaticDir();
455
477
  const prdDir = input.outputDir || (0, path_1.join)(taskOMaticDir, "prd");
@@ -476,5 +498,17 @@ class PRDService {
476
498
  }
477
499
  }
478
500
  exports.PRDService = PRDService;
479
- // Export singleton instance
480
- exports.prdService = new PRDService();
501
+ // Lazy singleton instance - only created when first accessed
502
+ let prdServiceInstance;
503
+ function getPRDService() {
504
+ if (!prdServiceInstance) {
505
+ prdServiceInstance = new PRDService();
506
+ }
507
+ return prdServiceInstance;
508
+ }
509
+ // Backward compatibility: export as const but use getter
510
+ exports.prdService = new Proxy({}, {
511
+ get(target, prop) {
512
+ return getPRDService()[prop];
513
+ },
514
+ });
@@ -1,11 +1,115 @@
1
+ import { getAIOperations, getModelProvider, getStorage, getContextBuilder } from "../utils/ai-service-factory";
1
2
  import { AIOptions } from "../utils/ai-config-builder";
2
3
  import { Task, StreamingOptions, TaskAIMetadata } from "../types";
3
4
  import { CreateTaskResult, EnhanceTaskResult, SplitTaskResult, PlanTaskResult, DocumentTaskResult, DeleteTaskResult } from "../types/results";
5
+ import { hooks } from "../lib/hooks";
6
+ /**
7
+ * Dependencies for TaskService
8
+ */
9
+ export interface TaskServiceDependencies {
10
+ storage?: ReturnType<typeof getStorage>;
11
+ aiOperations?: ReturnType<typeof getAIOperations>;
12
+ modelProvider?: ReturnType<typeof getModelProvider>;
13
+ contextBuilder?: ReturnType<typeof getContextBuilder>;
14
+ hooks?: typeof hooks;
15
+ }
4
16
  /**
5
17
  * TaskService - Centralized business logic for all task operations
6
- * This service is framework-agnostic and can be used by CLI, TUI, or Web
18
+ *
19
+ * This service provides a comprehensive API for task management with AI-powered features.
20
+ * It's framework-agnostic and can be used by CLI, TUI, or Web applications.
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * import { TaskService } from "task-o-matic";
25
+ *
26
+ * // Initialize with default configuration
27
+ * const taskService = new TaskService();
28
+ *
29
+ * // Create a task with AI enhancement
30
+ * const result = await taskService.createTask({
31
+ * title: "Implement feature",
32
+ * content: "Feature description",
33
+ * aiEnhance: true,
34
+ * aiOptions: {
35
+ * provider: "anthropic",
36
+ * model: "claude-3-5-sonnet"
37
+ * }
38
+ * });
39
+ *
40
+ * // Or inject dependencies for testing
41
+ * const taskService = new TaskService({
42
+ * storage: mockStorage,
43
+ * aiOperations: mockAI,
44
+ * });
45
+ * ```
7
46
  */
8
47
  export declare class TaskService {
48
+ private storage;
49
+ private aiOperations;
50
+ private modelProvider;
51
+ private contextBuilder;
52
+ private hooks;
53
+ /**
54
+ * Create a new TaskService
55
+ *
56
+ * @param dependencies - Optional dependencies to inject (for testing)
57
+ */
58
+ constructor(dependencies?: TaskServiceDependencies);
59
+ /**
60
+ * Creates a new task with optional AI enhancement
61
+ *
62
+ * @param input - Task creation parameters
63
+ * @param input.title - Task title (required, 1-255 characters)
64
+ * @param input.content - Task content/description (optional)
65
+ * @param input.parentId - Parent task ID for creating subtasks
66
+ * @param input.effort - Estimated effort ("small" | "medium" | "large")
67
+ * @param input.aiEnhance - Enable AI enhancement with Context7 documentation
68
+ * @param input.aiOptions - AI configuration override
69
+ * @param input.streamingOptions - Real-time streaming options
70
+ *
71
+ * @returns Promise resolving to task creation result
72
+ *
73
+ * @throws {TaskOMaticError} If task creation fails (e.g., AI operation errors, storage errors)
74
+ * @throws {Error} If input validation fails
75
+ *
76
+ * @example Basic task creation
77
+ * ```typescript
78
+ * const task = await taskService.createTask({
79
+ * title: "Fix authentication bug",
80
+ * content: "Users cannot login with valid credentials",
81
+ * aiEnhance: false
82
+ * });
83
+ * ```
84
+ *
85
+ * @example Task with AI enhancement
86
+ * ```typescript
87
+ * try {
88
+ * const enhancedTask = await taskService.createTask({
89
+ * title: "Design authentication system",
90
+ * content: "Implement OAuth2 + JWT authentication",
91
+ * aiEnhance: true,
92
+ * streamingOptions: {
93
+ * onChunk: (chunk) => console.log("AI:", chunk)
94
+ * }
95
+ * });
96
+ * console.log("Enhanced content:", enhancedTask.task.content);
97
+ * } catch (error) {
98
+ * if (error instanceof TaskOMaticError) {
99
+ * console.error("AI enhancement failed:", error.getDetails());
100
+ * }
101
+ * }
102
+ * ```
103
+ *
104
+ * @example Creating subtasks
105
+ * ```typescript
106
+ * const subtask = await taskService.createTask({
107
+ * title: "Implement OAuth2 flow",
108
+ * parentId: "1",
109
+ * effort: "medium"
110
+ * });
111
+ * ```
112
+ */
9
113
  createTask(input: {
10
114
  title: string;
11
115
  content?: string;
@@ -15,6 +119,27 @@ export declare class TaskService {
15
119
  aiOptions?: AIOptions;
16
120
  streamingOptions?: StreamingOptions;
17
121
  }): Promise<CreateTaskResult>;
122
+ /**
123
+ * List tasks with optional filtering
124
+ *
125
+ * @param filters - Filter criteria
126
+ * @param filters.status - Filter by task status ("todo", "in-progress", "completed")
127
+ * @param filters.tag - Filter by task tag
128
+ *
129
+ * @returns Promise resolving to array of matching tasks
130
+ *
131
+ * @example
132
+ * ```typescript
133
+ * // List all tasks
134
+ * const allTasks = await taskService.listTasks({});
135
+ *
136
+ * // List only completed tasks
137
+ * const completedTasks = await taskService.listTasks({ status: "completed" });
138
+ *
139
+ * // List tasks with specific tag
140
+ * const frontendTasks = await taskService.listTasks({ tag: "frontend" });
141
+ * ```
142
+ */
18
143
  listTasks(filters: {
19
144
  status?: string;
20
145
  tag?: string;
@@ -37,6 +162,35 @@ export declare class TaskService {
37
162
  }): Promise<DeleteTaskResult>;
38
163
  addTags(id: string, tags: string[]): Promise<Task>;
39
164
  removeTags(id: string, tags: string[]): Promise<Task>;
165
+ /**
166
+ * Get the next task based on priority and filtering criteria
167
+ *
168
+ * @param filters - Filter and priority criteria
169
+ * @param filters.status - Filter by task status
170
+ * @param filters.tag - Filter by task tag
171
+ * @param filters.effort - Filter by estimated effort
172
+ * @param filters.priority - Priority strategy ("newest", "oldest", "effort", or default)
173
+ *
174
+ * @returns Promise resolving to the highest priority task or null if none found
175
+ *
176
+ * @example
177
+ * ```typescript
178
+ * // Get the next task by default priority (task ID order)
179
+ * const nextTask = await taskService.getNextTask({});
180
+ *
181
+ * // Get the newest task with "todo" status
182
+ * const newestTodo = await taskService.getNextTask({
183
+ * status: "todo",
184
+ * priority: "newest"
185
+ * });
186
+ *
187
+ * // Get the highest effort task with specific tag
188
+ * const highEffortTask = await taskService.getNextTask({
189
+ * tag: "backend",
190
+ * priority: "effort"
191
+ * });
192
+ * ```
193
+ */
40
194
  getNextTask(filters: {
41
195
  status?: string;
42
196
  tag?: string;
@@ -44,9 +198,168 @@ export declare class TaskService {
44
198
  priority?: string;
45
199
  }): Promise<Task | null>;
46
200
  getTaskTree(rootId?: string): Promise<Task[]>;
201
+ /**
202
+ * Enhance a task with AI-generated documentation using Context7
203
+ *
204
+ * Uses AI to enrich the task description with relevant documentation,
205
+ * code examples, and best practices from Context7 documentation sources.
206
+ *
207
+ * @param taskId - ID of the task to enhance
208
+ * @param aiOptions - Optional AI configuration overrides
209
+ * @param streamingOptions - Optional streaming callbacks for real-time feedback
210
+ * @returns Promise resolving to enhancement result with metrics
211
+ *
212
+ * @throws {Error} If task not found
213
+ * @throws {TaskOMaticError} If AI enhancement fails
214
+ *
215
+ * @example Basic enhancement
216
+ * ```typescript
217
+ * const result = await taskService.enhanceTask("1");
218
+ * console.log("Enhanced content:", result.enhancedContent);
219
+ * console.log("Took:", result.stats.duration, "ms");
220
+ * ```
221
+ *
222
+ * @example With streaming
223
+ * ```typescript
224
+ * try {
225
+ * const result = await taskService.enhanceTask("1", undefined, {
226
+ * onChunk: (chunk) => process.stdout.write(chunk)
227
+ * });
228
+ * console.log("\nEnhancement complete!");
229
+ * } catch (error) {
230
+ * if (error instanceof TaskOMaticError) {
231
+ * console.error("Enhancement failed:", error.getDetails());
232
+ * }
233
+ * }
234
+ * ```
235
+ */
47
236
  enhanceTask(taskId: string, aiOptions?: AIOptions, streamingOptions?: StreamingOptions): Promise<EnhanceTaskResult>;
237
+ /**
238
+ * Split a task into subtasks using AI
239
+ *
240
+ * Analyzes the task and breaks it down into smaller, actionable subtasks
241
+ * with estimated effort. Can optionally use filesystem tools to understand
242
+ * project structure when creating subtasks.
243
+ *
244
+ * @param taskId - ID of the task to split
245
+ * @param aiOptions - Optional AI configuration overrides
246
+ * @param promptOverride - Optional custom prompt
247
+ * @param messageOverride - Optional custom message
248
+ * @param streamingOptions - Optional streaming callbacks
249
+ * @param enableFilesystemTools - Enable filesystem analysis for context
250
+ * @returns Promise resolving to split result with created subtasks
251
+ *
252
+ * @throws {Error} If task not found or already has subtasks
253
+ * @throws {TaskOMaticError} If AI operation fails
254
+ *
255
+ * @example Basic task splitting
256
+ * ```typescript
257
+ * const result = await taskService.splitTask("1");
258
+ * console.log(`Created ${result.subtasks.length} subtasks`);
259
+ * result.subtasks.forEach(subtask => {
260
+ * console.log(`- ${subtask.title} (${subtask.estimatedEffort})`);
261
+ * });
262
+ * ```
263
+ *
264
+ * @example With filesystem tools for code analysis
265
+ * ```typescript
266
+ * try {
267
+ * const result = await taskService.splitTask(
268
+ * "1",
269
+ * undefined,
270
+ * undefined,
271
+ * undefined,
272
+ * { onChunk: (chunk) => console.log(chunk) },
273
+ * true // Enable filesystem tools
274
+ * );
275
+ * console.log("AI analyzed codebase to create subtasks");
276
+ * } catch (error) {
277
+ * if (error instanceof TaskOMaticError) {
278
+ * console.error("Split failed:", error.suggestions);
279
+ * }
280
+ * }
281
+ * ```
282
+ */
48
283
  splitTask(taskId: string, aiOptions?: AIOptions, promptOverride?: string, messageOverride?: string, streamingOptions?: StreamingOptions, enableFilesystemTools?: boolean): Promise<SplitTaskResult>;
284
+ /**
285
+ * Analyze and fetch documentation for a task using Context7
286
+ *
287
+ * Analyzes the task content to identify required libraries and documentation,
288
+ * then fetches relevant documentation from Context7. Caches documentation
289
+ * for future use.
290
+ *
291
+ * @param taskId - ID of the task to document
292
+ * @param force - Force re-fetch even if documentation exists
293
+ * @param aiOptions - Optional AI configuration overrides
294
+ * @param streamingOptions - Optional streaming callbacks
295
+ * @returns Promise resolving to documentation analysis result
296
+ *
297
+ * @throws {Error} If task not found or content is empty
298
+ * @throws {TaskOMaticError} If AI operation fails
299
+ *
300
+ * @example Analyze documentation needs
301
+ * ```typescript
302
+ * const result = await taskService.documentTask("1");
303
+ * if (result.documentation) {
304
+ * console.log("Documentation fetched:");
305
+ * console.log(result.documentation.recap);
306
+ * console.log("Libraries:", result.documentation.libraries);
307
+ * }
308
+ * ```
309
+ *
310
+ * @example Force refresh documentation
311
+ * ```typescript
312
+ * try {
313
+ * const result = await taskService.documentTask("1", true);
314
+ * console.log(`Analyzed ${result.analysis.libraries.length} libraries`);
315
+ * } catch (error) {
316
+ * if (error instanceof TaskOMaticError) {
317
+ * console.error("Documentation fetch failed:", error.getDetails());
318
+ * }
319
+ * }
320
+ * ```
321
+ */
49
322
  documentTask(taskId: string, force?: boolean, aiOptions?: AIOptions, streamingOptions?: StreamingOptions): Promise<DocumentTaskResult>;
323
+ /**
324
+ * Generate an implementation plan for a task using AI
325
+ *
326
+ * Creates a detailed implementation plan with steps, considerations,
327
+ * and technical approach. Uses filesystem and Context7 tools to understand
328
+ * the project context and provide relevant suggestions.
329
+ *
330
+ * @param taskId - ID of the task to plan
331
+ * @param aiOptions - Optional AI configuration overrides
332
+ * @param streamingOptions - Optional streaming callbacks
333
+ * @returns Promise resolving to plan result with generated plan text
334
+ *
335
+ * @throws {Error} If task not found
336
+ * @throws {TaskOMaticError} If AI operation fails
337
+ *
338
+ * @example Basic implementation planning
339
+ * ```typescript
340
+ * const result = await taskService.planTask("1");
341
+ * console.log("Implementation Plan:");
342
+ * console.log(result.plan);
343
+ * console.log(`Generated in ${result.stats.duration}ms`);
344
+ * ```
345
+ *
346
+ * @example With streaming for real-time plan generation
347
+ * ```typescript
348
+ * try {
349
+ * const result = await taskService.planTask("1", undefined, {
350
+ * onChunk: (chunk) => {
351
+ * // Display plan as it's generated
352
+ * process.stdout.write(chunk);
353
+ * }
354
+ * });
355
+ * console.log("\n\nPlan saved to:", `plans/${result.task.id}.md`);
356
+ * } catch (error) {
357
+ * if (error instanceof TaskOMaticError) {
358
+ * console.error("Planning failed:", error.getDetails());
359
+ * }
360
+ * }
361
+ * ```
362
+ */
50
363
  planTask(taskId: string, aiOptions?: AIOptions, streamingOptions?: StreamingOptions): Promise<PlanTaskResult>;
51
364
  getTaskDocumentation(taskId: string): Promise<string | null>;
52
365
  addTaskDocumentationFromFile(taskId: string, filePath: string): Promise<{
@@ -70,5 +383,6 @@ export declare class TaskService {
70
383
  }>>;
71
384
  deleteTaskPlan(taskId: string): Promise<boolean>;
72
385
  }
386
+ export declare function getTaskService(): TaskService;
73
387
  export declare const taskService: TaskService;
74
388
  //# sourceMappingURL=tasks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/services/tasks.ts"],"names":[],"mappings":"AAOA,OAAO,EAAiB,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EACL,IAAI,EACJ,gBAAgB,EAChB,cAAc,EAGf,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAO1B;;;GAGG;AACH,qBAAa,WAAW;IAKhB,UAAU,CAAC,KAAK,EAAE;QACtB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;KACrC,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAiGvB,SAAS,CAAC,OAAO,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAsBtE,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAIzC,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIlD,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAI7D,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAIxC,UAAU,CACd,EAAE,EAAE,MAAM,EACV,OAAO,EAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;KAC1B,GACA,OAAO,CAAC,IAAI,CAAC;IAuDV,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxD,UAAU,CACd,EAAE,EAAE,MAAM,EACV,OAAO,GAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO,GACnD,OAAO,CAAC,gBAAgB,CAAC;IAqDtB,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBlD,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BrD,WAAW,CAAC,OAAO,EAAE;QACzB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAmClB,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAoC7C,WAAW,CACf,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,SAAS,EACrB,gBAAgB,CAAC,EAAE,gBAAgB,GAClC,OAAO,CAAC,iBAAiB,CAAC;IA+GvB,SAAS,CACb,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,SAAS,EACrB,cAAc,CAAC,EAAE,MAAM,EACvB,eAAe,CAAC,EAAE,MAAM,EACxB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,qBAAqB,CAAC,EAAE,OAAO,GAC9B,OAAO,CAAC,eAAe,CAAC;IAoJrB,YAAY,CAChB,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,OAAe,EACtB,SAAS,CAAC,EAAE,SAAS,EACrB,gBAAgB,CAAC,EAAE,gBAAgB,GAClC,OAAO,CAAC,kBAAkB,CAAC;IAoJxB,QAAQ,CACZ,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,SAAS,EACrB,gBAAgB,CAAC,EAAE,gBAAgB,GAClC,OAAO,CAAC,cAAc,CAAC;IA0GpB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAI5D,4BAA4B,CAChC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,IAAI,CAAA;KAAE,CAAC;IAiCtC,WAAW,CACf,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,IAAI,CAAA;KAAE,CAAC;IA0CtC,WAAW,CACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAInE,aAAa,IAAI,OAAO,CAC5B,KAAK,CAAC;QACJ,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC,CACH;IAIK,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAGvD;AAGD,eAAO,MAAM,WAAW,aAAoB,CAAC"}
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/services/tasks.ts"],"names":[],"mappings":"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"}