task-o-matic 0.0.2 → 0.0.4

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 (129) hide show
  1. package/README.md +96 -40
  2. package/dist/commands/prd.js +4 -0
  3. package/dist/commands/prompt.d.ts.map +1 -1
  4. package/dist/commands/prompt.js +69 -61
  5. package/dist/commands/tasks/create.d.ts +3 -0
  6. package/dist/commands/tasks/create.d.ts.map +1 -0
  7. package/dist/commands/tasks/create.js +58 -0
  8. package/dist/commands/tasks/delete.d.ts +3 -0
  9. package/dist/commands/tasks/delete.d.ts.map +1 -0
  10. package/dist/commands/tasks/delete.js +40 -0
  11. package/dist/commands/tasks/document.d.ts +5 -0
  12. package/dist/commands/tasks/document.d.ts.map +1 -0
  13. package/dist/commands/tasks/document.js +118 -0
  14. package/dist/commands/tasks/enhance.d.ts +3 -0
  15. package/dist/commands/tasks/enhance.d.ts.map +1 -0
  16. package/dist/commands/tasks/enhance.js +86 -0
  17. package/dist/commands/tasks/execute.d.ts +3 -0
  18. package/dist/commands/tasks/execute.d.ts.map +1 -0
  19. package/dist/commands/tasks/execute.js +33 -0
  20. package/dist/commands/tasks/index.d.ts +16 -0
  21. package/dist/commands/tasks/index.d.ts.map +1 -0
  22. package/dist/commands/tasks/index.js +31 -0
  23. package/dist/commands/tasks/list.d.ts +3 -0
  24. package/dist/commands/tasks/list.d.ts.map +1 -0
  25. package/dist/commands/tasks/list.js +27 -0
  26. package/dist/commands/tasks/next.d.ts +3 -0
  27. package/dist/commands/tasks/next.d.ts.map +1 -0
  28. package/dist/commands/tasks/next.js +44 -0
  29. package/dist/commands/tasks/plan.d.ts +7 -0
  30. package/dist/commands/tasks/plan.d.ts.map +1 -0
  31. package/dist/commands/tasks/plan.js +131 -0
  32. package/dist/commands/tasks/show.d.ts +3 -0
  33. package/dist/commands/tasks/show.d.ts.map +1 -0
  34. package/dist/commands/tasks/show.js +23 -0
  35. package/dist/commands/tasks/split.d.ts +3 -0
  36. package/dist/commands/tasks/split.d.ts.map +1 -0
  37. package/dist/commands/tasks/split.js +95 -0
  38. package/dist/commands/tasks/status.d.ts +3 -0
  39. package/dist/commands/tasks/status.d.ts.map +1 -0
  40. package/dist/commands/tasks/status.js +26 -0
  41. package/dist/commands/tasks/subtasks.d.ts +3 -0
  42. package/dist/commands/tasks/subtasks.d.ts.map +1 -0
  43. package/dist/commands/tasks/subtasks.js +35 -0
  44. package/dist/commands/tasks/tags.d.ts +4 -0
  45. package/dist/commands/tasks/tags.d.ts.map +1 -0
  46. package/dist/commands/tasks/tags.js +37 -0
  47. package/dist/commands/tasks/tree.d.ts +3 -0
  48. package/dist/commands/tasks/tree.d.ts.map +1 -0
  49. package/dist/commands/tasks/tree.js +20 -0
  50. package/dist/commands/tasks/update.d.ts +3 -0
  51. package/dist/commands/tasks/update.d.ts.map +1 -0
  52. package/dist/commands/tasks/update.js +35 -0
  53. package/dist/commands/tasks.d.ts.map +1 -1
  54. package/dist/commands/tasks.js +23 -594
  55. package/dist/commands/workflow.d.ts +4 -0
  56. package/dist/commands/workflow.d.ts.map +1 -0
  57. package/dist/commands/workflow.js +434 -0
  58. package/dist/index.d.ts.map +1 -1
  59. package/dist/index.js +3 -1
  60. package/dist/lib/ai-service/ai-operations.d.ts +5 -3
  61. package/dist/lib/ai-service/ai-operations.d.ts.map +1 -1
  62. package/dist/lib/ai-service/ai-operations.js +231 -30
  63. package/dist/lib/ai-service/filesystem-tools.d.ts +69 -0
  64. package/dist/lib/ai-service/filesystem-tools.d.ts.map +1 -0
  65. package/dist/lib/ai-service/filesystem-tools.js +70 -0
  66. package/dist/lib/ai-service/research-tools.d.ts.map +1 -1
  67. package/dist/lib/ai-service/research-tools.js +2 -2
  68. package/dist/lib/context-builder.d.ts +2 -1
  69. package/dist/lib/context-builder.d.ts.map +1 -1
  70. package/dist/lib/context-builder.js +3 -8
  71. package/dist/lib/executors/claude-code-executor.d.ts +6 -0
  72. package/dist/lib/executors/claude-code-executor.d.ts.map +1 -0
  73. package/dist/lib/executors/claude-code-executor.js +41 -0
  74. package/dist/lib/executors/codex-executor.d.ts +6 -0
  75. package/dist/lib/executors/codex-executor.d.ts.map +1 -0
  76. package/dist/lib/executors/codex-executor.js +41 -0
  77. package/dist/lib/executors/executor-factory.d.ts.map +1 -1
  78. package/dist/lib/executors/executor-factory.js +6 -3
  79. package/dist/lib/executors/gemini-executor.d.ts +6 -0
  80. package/dist/lib/executors/gemini-executor.d.ts.map +1 -0
  81. package/dist/lib/executors/gemini-executor.js +41 -0
  82. package/dist/lib/executors/opencode-executor.d.ts.map +1 -1
  83. package/dist/lib/executors/opencode-executor.js +2 -3
  84. package/dist/lib/hooks/logger.d.ts +2 -0
  85. package/dist/lib/hooks/logger.d.ts.map +1 -0
  86. package/dist/lib/hooks/logger.js +27 -0
  87. package/dist/lib/hooks.d.ts +64 -0
  88. package/dist/lib/hooks.d.ts.map +1 -0
  89. package/dist/lib/hooks.js +60 -0
  90. package/dist/lib/index.d.ts +18 -17
  91. package/dist/lib/index.d.ts.map +1 -1
  92. package/dist/lib/index.js +3 -3
  93. package/dist/lib/prompt-builder.d.ts +8 -0
  94. package/dist/lib/prompt-builder.d.ts.map +1 -1
  95. package/dist/lib/prompt-builder.js +110 -4
  96. package/dist/lib/{storage.d.ts → storage/file-system.d.ts} +4 -3
  97. package/dist/lib/storage/file-system.d.ts.map +1 -0
  98. package/dist/lib/{storage.js → storage/file-system.js} +141 -152
  99. package/dist/lib/storage/types.d.ts +43 -0
  100. package/dist/lib/storage/types.d.ts.map +1 -0
  101. package/dist/lib/storage/types.js +2 -0
  102. package/dist/lib/task-execution.d.ts.map +1 -1
  103. package/dist/lib/task-execution.js +63 -14
  104. package/dist/prompts/workflow-assistance.d.ts +32 -0
  105. package/dist/prompts/workflow-assistance.d.ts.map +1 -0
  106. package/dist/prompts/workflow-assistance.js +130 -0
  107. package/dist/services/prd.d.ts +2 -0
  108. package/dist/services/prd.d.ts.map +1 -1
  109. package/dist/services/prd.js +4 -4
  110. package/dist/services/tasks.d.ts +13 -6
  111. package/dist/services/tasks.d.ts.map +1 -1
  112. package/dist/services/tasks.js +202 -88
  113. package/dist/services/workflow-ai-assistant.d.ts +74 -0
  114. package/dist/services/workflow-ai-assistant.d.ts.map +1 -0
  115. package/dist/services/workflow-ai-assistant.js +223 -0
  116. package/dist/test/hooks.test.d.ts +2 -0
  117. package/dist/test/hooks.test.d.ts.map +1 -0
  118. package/dist/test/hooks.test.js +58 -0
  119. package/dist/test/storage.test.js +16 -16
  120. package/dist/types/options.d.ts +35 -0
  121. package/dist/types/options.d.ts.map +1 -1
  122. package/dist/utils/ai-service-factory.d.ts +5 -5
  123. package/dist/utils/ai-service-factory.d.ts.map +1 -1
  124. package/dist/utils/ai-service-factory.js +4 -3
  125. package/dist/utils/workflow-prompts.d.ts +17 -0
  126. package/dist/utils/workflow-prompts.d.ts.map +1 -0
  127. package/dist/utils/workflow-prompts.js +88 -0
  128. package/package.json +2 -2
  129. package/dist/lib/storage.d.ts.map +0 -1
@@ -1,9 +1,43 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.taskService = exports.TaskService = void 0;
4
37
  const ai_service_factory_1 = require("../utils/ai-service-factory");
5
38
  const stack_formatter_1 = require("../utils/stack-formatter");
6
39
  const ai_config_builder_1 = require("../utils/ai-config-builder");
40
+ const hooks_1 = require("../lib/hooks");
7
41
  /**
8
42
  * TaskService - Centralized business logic for all task operations
9
43
  * This service is framework-agnostic and can be used by CLI, TUI, or Web
@@ -17,16 +51,16 @@ class TaskService {
17
51
  let content = input.content;
18
52
  let aiMetadata;
19
53
  if (input.aiEnhance) {
20
- input.callbacks?.onProgress?.({
21
- type: 'progress',
22
- message: 'Building context for task...',
54
+ hooks_1.hooks.emit("task:progress", {
55
+ message: "Building context for task...",
56
+ type: "progress",
23
57
  });
24
58
  const context = await (0, ai_service_factory_1.getContextBuilder)().buildContextForNewTask(input.title, input.content);
25
59
  const stackInfo = (0, stack_formatter_1.formatStackInfo)(context.stack);
26
60
  const enhancementAIConfig = (0, ai_config_builder_1.buildAIConfig)(input.aiOptions);
27
- input.callbacks?.onProgress?.({
28
- type: 'progress',
29
- message: 'Enhancing task with AI documentation...',
61
+ hooks_1.hooks.emit("task:progress", {
62
+ message: "Enhancing task with AI documentation...",
63
+ type: "progress",
30
64
  });
31
65
  const taskDescription = input.content ?? "";
32
66
  content = await (0, ai_service_factory_1.getAIOperations)().enhanceTaskWithDocumentation(`task-${Date.now()}`, input.title, taskDescription, stackInfo, input.streamingOptions, undefined, enhancementAIConfig, context.existingResearch);
@@ -41,9 +75,9 @@ class TaskService {
41
75
  generatedAt: Date.now(),
42
76
  };
43
77
  }
44
- input.callbacks?.onProgress?.({
45
- type: 'progress',
46
- message: 'Saving task...',
78
+ hooks_1.hooks.emit("task:progress", {
79
+ message: "Saving task...",
80
+ type: "progress",
47
81
  });
48
82
  const task = await (0, ai_service_factory_1.getStorage)().createTask({
49
83
  title: input.title,
@@ -52,10 +86,12 @@ class TaskService {
52
86
  parentId: input.parentId,
53
87
  estimatedEffort: input.effort,
54
88
  }, aiMetadata);
55
- input.callbacks?.onProgress?.({
56
- type: 'completed',
57
- message: 'Task created successfully',
89
+ hooks_1.hooks.emit("task:progress", {
90
+ type: "completed",
91
+ message: "Task created successfully",
58
92
  });
93
+ // Emit task:created event
94
+ await hooks_1.hooks.emit("task:created", { task });
59
95
  return { success: true, task, aiMetadata };
60
96
  }
61
97
  async listTasks(filters) {
@@ -111,6 +147,19 @@ class TaskService {
111
147
  if (!updatedTask) {
112
148
  throw new Error(`Failed to update task ${id}`);
113
149
  }
150
+ // Emit task:updated event
151
+ await hooks_1.hooks.emit("task:updated", {
152
+ task: updatedTask,
153
+ changes: finalUpdates,
154
+ });
155
+ // Emit task:status-changed event if status changed
156
+ if (updates.status && updates.status !== existingTask.status) {
157
+ await hooks_1.hooks.emit("task:status-changed", {
158
+ task: updatedTask,
159
+ oldStatus: existingTask.status,
160
+ newStatus: updates.status,
161
+ });
162
+ }
114
163
  return updatedTask;
115
164
  }
116
165
  async setTaskStatus(id, status) {
@@ -140,7 +189,10 @@ class TaskService {
140
189
  else if (cascade) {
141
190
  // Recursively delete subtasks
142
191
  for (const subtask of subtasks) {
143
- const result = await this.deleteTask(subtask.id, { cascade: true, force: true });
192
+ const result = await this.deleteTask(subtask.id, {
193
+ cascade: true,
194
+ force: true,
195
+ });
144
196
  deleted.push(...result.deleted);
145
197
  orphanedSubtasks.push(...result.orphanedSubtasks);
146
198
  }
@@ -149,6 +201,8 @@ class TaskService {
149
201
  const success = await storage.deleteTask(id);
150
202
  if (success) {
151
203
  deleted.push(taskToDelete);
204
+ // Emit task:deleted event
205
+ await hooks_1.hooks.emit("task:deleted", { taskId: id });
152
206
  }
153
207
  return { success: true, deleted, orphanedSubtasks };
154
208
  }
@@ -253,31 +307,31 @@ class TaskService {
253
307
  // ============================================================================
254
308
  // AI OPERATIONS
255
309
  // ============================================================================
256
- async enhanceTask(taskId, aiOptions, streamingOptions, callbacks) {
310
+ async enhanceTask(taskId, aiOptions, streamingOptions) {
257
311
  const startTime = Date.now();
258
- callbacks?.onProgress?.({
259
- type: 'started',
260
- message: 'Starting task enhancement...',
312
+ hooks_1.hooks.emit("task:progress", {
313
+ message: "Starting task enhancement...",
314
+ type: "started",
261
315
  });
262
316
  const task = await (0, ai_service_factory_1.getStorage)().getTask(taskId);
263
317
  if (!task) {
264
318
  throw new Error(`Task with ID ${taskId} not found`);
265
319
  }
266
- callbacks?.onProgress?.({
267
- type: 'progress',
268
- message: 'Building context...',
320
+ hooks_1.hooks.emit("task:progress", {
321
+ message: "Building context...",
322
+ type: "progress",
269
323
  });
270
324
  const context = await (0, ai_service_factory_1.getContextBuilder)().buildContext(taskId);
271
325
  const stackInfo = (0, stack_formatter_1.formatStackInfo)(context.stack);
272
326
  const enhancementAIConfig = (0, ai_config_builder_1.buildAIConfig)(aiOptions);
273
- callbacks?.onProgress?.({
274
- type: 'progress',
275
- message: 'Calling AI for enhancement...',
327
+ hooks_1.hooks.emit("task:progress", {
328
+ message: "Calling AI for enhancement...",
329
+ type: "progress",
276
330
  });
277
331
  const enhancedContent = await (0, ai_service_factory_1.getAIOperations)().enhanceTaskWithDocumentation(task.id, task.title, task.description ?? "", stackInfo, streamingOptions, undefined, enhancementAIConfig, context.existingResearch);
278
- callbacks?.onProgress?.({
279
- type: 'progress',
280
- message: 'Saving enhanced content...',
332
+ hooks_1.hooks.emit("task:progress", {
333
+ message: "Saving enhanced content...",
334
+ type: "progress",
281
335
  });
282
336
  const originalLength = task.description?.length || 0;
283
337
  if (enhancedContent.length > 200) {
@@ -303,9 +357,9 @@ class TaskService {
303
357
  };
304
358
  await (0, ai_service_factory_1.getStorage)().saveTaskAIMetadata(aiMetadata);
305
359
  const duration = Date.now() - startTime;
306
- callbacks?.onProgress?.({
307
- type: 'completed',
308
- message: 'Task enhancement completed',
360
+ hooks_1.hooks.emit("task:progress", {
361
+ message: "Task enhancement completed",
362
+ type: "completed",
309
363
  });
310
364
  return {
311
365
  success: true,
@@ -323,11 +377,11 @@ class TaskService {
323
377
  },
324
378
  };
325
379
  }
326
- async splitTask(taskId, aiOptions, promptOverride, messageOverride, streamingOptions, callbacks) {
380
+ async splitTask(taskId, aiOptions, promptOverride, messageOverride, streamingOptions, enableFilesystemTools) {
327
381
  const startTime = Date.now();
328
- callbacks?.onProgress?.({
329
- type: 'started',
330
- message: 'Starting task breakdown...',
382
+ hooks_1.hooks.emit("task:progress", {
383
+ message: "Starting task breakdown...",
384
+ type: "started",
331
385
  });
332
386
  const task = await (0, ai_service_factory_1.getStorage)().getTask(taskId);
333
387
  if (!task) {
@@ -338,9 +392,9 @@ class TaskService {
338
392
  if (existingSubtasks.length > 0) {
339
393
  throw new Error(`Task ${task.title} already has ${existingSubtasks.length} subtasks. Use existing subtasks or delete them first.`);
340
394
  }
341
- callbacks?.onProgress?.({
342
- type: 'progress',
343
- message: 'Building context...',
395
+ hooks_1.hooks.emit("task:progress", {
396
+ message: "Building context...",
397
+ type: "progress",
344
398
  });
345
399
  // Build comprehensive context
346
400
  const context = await (0, ai_service_factory_1.getContextBuilder)().buildContext(taskId);
@@ -348,25 +402,23 @@ class TaskService {
348
402
  // Get full task content
349
403
  const fullContent = context.task.fullContent || task.description || "";
350
404
  const breakdownAIConfig = (0, ai_config_builder_1.buildAIConfig)(aiOptions);
351
- callbacks?.onProgress?.({
352
- type: 'progress',
353
- message: 'Calling AI to break down task...',
405
+ hooks_1.hooks.emit("task:progress", {
406
+ message: "Calling AI to break down task...",
407
+ type: "progress",
354
408
  });
355
409
  // Use AI service to break down the task with enhanced context
356
- const subtaskData = await (0, ai_service_factory_1.getAIOperations)().breakdownTask(task, breakdownAIConfig, promptOverride, messageOverride, streamingOptions, undefined, fullContent, stackInfo, existingSubtasks);
357
- callbacks?.onProgress?.({
358
- type: 'progress',
410
+ const subtaskData = await (0, ai_service_factory_1.getAIOperations)().breakdownTask(task, breakdownAIConfig, promptOverride, messageOverride, streamingOptions, undefined, fullContent, stackInfo, existingSubtasks, enableFilesystemTools);
411
+ hooks_1.hooks.emit("task:progress", {
359
412
  message: `Creating ${subtaskData.length} subtasks...`,
413
+ type: "progress",
360
414
  });
361
415
  // Create subtasks
362
416
  const createdSubtasks = [];
363
417
  for (let i = 0; i < subtaskData.length; i++) {
364
418
  const subtask = subtaskData[i];
365
- callbacks?.onProgress?.({
366
- type: 'progress',
419
+ hooks_1.hooks.emit("task:progress", {
367
420
  message: `Creating subtask ${i + 1}/${subtaskData.length}: ${subtask.title}`,
368
- current: i + 1,
369
- total: subtaskData.length,
421
+ type: "progress",
370
422
  });
371
423
  const result = await this.createTask({
372
424
  title: subtask.title,
@@ -390,9 +442,9 @@ class TaskService {
390
442
  };
391
443
  await (0, ai_service_factory_1.getStorage)().saveTaskAIMetadata(aiMetadata);
392
444
  const duration = Date.now() - startTime;
393
- callbacks?.onProgress?.({
394
- type: 'completed',
445
+ hooks_1.hooks.emit("task:progress", {
395
446
  message: `Task split into ${createdSubtasks.length} subtasks`,
447
+ type: "completed",
396
448
  });
397
449
  return {
398
450
  success: true,
@@ -409,11 +461,11 @@ class TaskService {
409
461
  },
410
462
  };
411
463
  }
412
- async documentTask(taskId, force = false, aiOptions, streamingOptions, callbacks) {
464
+ async documentTask(taskId, force = false, aiOptions, streamingOptions) {
413
465
  const startTime = Date.now();
414
- callbacks?.onProgress?.({
415
- type: 'started',
416
- message: 'Analyzing documentation needs...',
466
+ hooks_1.hooks.emit("task:progress", {
467
+ message: "Analyzing documentation needs...",
468
+ type: "started",
417
469
  });
418
470
  const task = await (0, ai_service_factory_1.getStorage)().getTask(taskId);
419
471
  if (!task) {
@@ -421,9 +473,9 @@ class TaskService {
421
473
  }
422
474
  if (task.documentation && !force) {
423
475
  if ((0, ai_service_factory_1.getContextBuilder)().isDocumentationFresh(task.documentation)) {
424
- callbacks?.onProgress?.({
425
- type: 'info',
426
- message: 'Documentation is fresh, skipping analysis',
476
+ hooks_1.hooks.emit("task:progress", {
477
+ message: "Documentation is fresh, skipping analysis",
478
+ type: "info",
427
479
  });
428
480
  return {
429
481
  success: true,
@@ -435,9 +487,9 @@ class TaskService {
435
487
  };
436
488
  }
437
489
  }
438
- callbacks?.onProgress?.({
439
- type: 'progress',
440
- message: 'Building context...',
490
+ hooks_1.hooks.emit("task:progress", {
491
+ message: "Building context...",
492
+ type: "progress",
441
493
  });
442
494
  const context = await (0, ai_service_factory_1.getContextBuilder)().buildContext(taskId);
443
495
  const stackInfo = (0, stack_formatter_1.formatStackInfo)(context.stack);
@@ -450,17 +502,17 @@ class TaskService {
450
502
  // Get existing documentations from all tasks
451
503
  const tasks = await (0, ai_service_factory_1.getStorage)().getTasks();
452
504
  const documentations = tasks.map((task) => task.documentation);
453
- callbacks?.onProgress?.({
454
- type: 'progress',
455
- message: 'Calling AI to analyze documentation needs...',
505
+ hooks_1.hooks.emit("task:progress", {
506
+ message: "Calling AI to analyze documentation needs...",
507
+ type: "progress",
456
508
  });
457
509
  // First analyze what documentation is needed
458
510
  const analysis = await (0, ai_service_factory_1.getAIOperations)().analyzeDocumentationNeeds(task.id, task.title, fullContent, stackInfo, streamingOptions, undefined, analysisAIConfig, documentations);
459
511
  let documentation;
460
512
  if (analysis.libraries.length > 0) {
461
- callbacks?.onProgress?.({
462
- type: 'progress',
513
+ hooks_1.hooks.emit("task:progress", {
463
514
  message: `Fetching documentation for ${analysis.libraries.length} libraries...`,
515
+ type: "progress",
464
516
  });
465
517
  // Build research object from actual libraries
466
518
  const research = {};
@@ -476,9 +528,9 @@ class TaskService {
476
528
  doc: docFile,
477
529
  });
478
530
  }
479
- callbacks?.onProgress?.({
480
- type: 'progress',
481
- message: 'Generating documentation recap...',
531
+ hooks_1.hooks.emit("task:progress", {
532
+ message: "Generating documentation recap...",
533
+ type: "progress",
482
534
  });
483
535
  const recap = await (0, ai_service_factory_1.getAIOperations)().generateDocumentationRecap(analysis.libraries, analysis.toolResults?.map((tr) => ({
484
536
  library: tr.toolName,
@@ -491,16 +543,16 @@ class TaskService {
491
543
  files: analysis.files || [],
492
544
  research,
493
545
  };
494
- callbacks?.onProgress?.({
495
- type: 'progress',
496
- message: 'Saving documentation...',
546
+ hooks_1.hooks.emit("task:progress", {
547
+ message: "Saving documentation...",
548
+ type: "progress",
497
549
  });
498
550
  await (0, ai_service_factory_1.getStorage)().updateTask(taskId, { documentation });
499
551
  }
500
552
  const duration = Date.now() - startTime;
501
- callbacks?.onProgress?.({
502
- type: 'completed',
503
- message: 'Documentation analysis completed',
553
+ hooks_1.hooks.emit("task:progress", {
554
+ message: "Documentation analysis completed",
555
+ type: "completed",
504
556
  });
505
557
  return {
506
558
  success: true,
@@ -512,11 +564,11 @@ class TaskService {
512
564
  },
513
565
  };
514
566
  }
515
- async planTask(taskId, aiOptions, streamingOptions, callbacks) {
567
+ async planTask(taskId, aiOptions, streamingOptions) {
516
568
  const startTime = Date.now();
517
- callbacks?.onProgress?.({
518
- type: 'started',
519
- message: 'Creating implementation plan...',
569
+ hooks_1.hooks.emit("task:progress", {
570
+ message: "Creating implementation plan...",
571
+ type: "started",
520
572
  });
521
573
  const task = await (0, ai_service_factory_1.getStorage)().getTask(taskId);
522
574
  if (!task) {
@@ -524,9 +576,9 @@ class TaskService {
524
576
  }
525
577
  const aiService = (0, ai_service_factory_1.getAIOperations)();
526
578
  const planAIConfig = (0, ai_config_builder_1.buildAIConfig)(aiOptions);
527
- callbacks?.onProgress?.({
528
- type: 'progress',
529
- message: 'Building task context...',
579
+ hooks_1.hooks.emit("task:progress", {
580
+ message: "Building task context...",
581
+ type: "progress",
530
582
  });
531
583
  // Build task context and details
532
584
  let taskContext = `Task ID: ${task.id}\nTitle: ${task.title}\n`;
@@ -548,21 +600,21 @@ class TaskService {
548
600
  taskDetails += ` ${subtask.description || "No description"}\n\n`;
549
601
  });
550
602
  }
551
- callbacks?.onProgress?.({
552
- type: 'progress',
553
- message: 'Calling AI to create plan...',
603
+ hooks_1.hooks.emit("task:progress", {
604
+ message: "Calling AI to create plan...",
605
+ type: "progress",
554
606
  });
555
607
  const plan = await aiService.planTask(taskContext, taskDetails, planAIConfig, undefined, undefined, streamingOptions);
556
- callbacks?.onProgress?.({
557
- type: 'progress',
558
- message: 'Saving plan...',
608
+ hooks_1.hooks.emit("task:progress", {
609
+ message: "Saving plan...",
610
+ type: "progress",
559
611
  });
560
612
  // Save the plan to storage
561
613
  await (0, ai_service_factory_1.getStorage)().savePlan(taskId, plan);
562
614
  const duration = Date.now() - startTime;
563
- callbacks?.onProgress?.({
564
- type: 'completed',
565
- message: 'Implementation plan created',
615
+ hooks_1.hooks.emit("task:progress", {
616
+ message: "Implementation plan created",
617
+ type: "completed",
566
618
  });
567
619
  const aiConfig = (0, ai_service_factory_1.getModelProvider)().getAIConfig();
568
620
  return {
@@ -579,6 +631,68 @@ class TaskService {
579
631
  };
580
632
  }
581
633
  // ============================================================================
634
+ // DOCUMENTATION OPERATIONS
635
+ // ============================================================================
636
+ async getTaskDocumentation(taskId) {
637
+ return (0, ai_service_factory_1.getStorage)().getTaskDocumentation(taskId);
638
+ }
639
+ async addTaskDocumentationFromFile(taskId, filePath) {
640
+ const task = await this.getTask(taskId);
641
+ if (!task) {
642
+ throw new Error(`Task with ID ${taskId} not found`);
643
+ }
644
+ try {
645
+ const { readFileSync, existsSync } = await Promise.resolve().then(() => __importStar(require("fs")));
646
+ const { resolve } = await Promise.resolve().then(() => __importStar(require("path")));
647
+ const resolvedPath = resolve(filePath);
648
+ if (!existsSync(resolvedPath)) {
649
+ throw new Error(`Documentation file not found: ${filePath}`);
650
+ }
651
+ const content = readFileSync(resolvedPath, "utf-8");
652
+ const savedPath = await (0, ai_service_factory_1.getStorage)().saveTaskDocumentation(taskId, content);
653
+ return {
654
+ filePath: savedPath,
655
+ task,
656
+ };
657
+ }
658
+ catch (error) {
659
+ throw new Error(`Failed to add documentation from file: ${error instanceof Error ? error.message : "Unknown error"}`);
660
+ }
661
+ }
662
+ async setTaskPlan(taskId, planText, planFilePath) {
663
+ const task = await this.getTask(taskId);
664
+ if (!task) {
665
+ throw new Error(`Task with ID ${taskId} not found`);
666
+ }
667
+ let plan;
668
+ if (planFilePath) {
669
+ try {
670
+ const { readFileSync, existsSync } = await Promise.resolve().then(() => __importStar(require("fs")));
671
+ const { resolve } = await Promise.resolve().then(() => __importStar(require("path")));
672
+ const resolvedPath = resolve(planFilePath);
673
+ if (!existsSync(resolvedPath)) {
674
+ throw new Error(`Plan file not found: ${planFilePath}`);
675
+ }
676
+ plan = readFileSync(resolvedPath, "utf-8");
677
+ }
678
+ catch (error) {
679
+ throw new Error(`Failed to read plan file: ${error instanceof Error ? error.message : "Unknown error"}`);
680
+ }
681
+ }
682
+ else if (planText) {
683
+ plan = planText;
684
+ }
685
+ else {
686
+ throw new Error("Either planText or planFilePath must be provided");
687
+ }
688
+ await (0, ai_service_factory_1.getStorage)().savePlan(taskId, plan);
689
+ const planFile = `plans/${taskId}.md`;
690
+ return {
691
+ planFile,
692
+ task,
693
+ };
694
+ }
695
+ // ============================================================================
582
696
  // PLAN OPERATIONS
583
697
  // ============================================================================
584
698
  async getTaskPlan(taskId) {
@@ -0,0 +1,74 @@
1
+ import { StreamingOptions } from "../types";
2
+ import { AIOptions } from "../utils/ai-config-builder";
3
+ /**
4
+ * WorkflowAIAssistant - AI-powered decision making for workflow steps
5
+ * Helps users make configuration choices using natural language
6
+ */
7
+ export declare class WorkflowAIAssistant {
8
+ /**
9
+ * Assist with initialization and bootstrap configuration
10
+ */
11
+ assistInitConfig(input: {
12
+ userDescription: string;
13
+ aiOptions?: AIOptions;
14
+ streamingOptions?: StreamingOptions;
15
+ }): Promise<{
16
+ projectName: string;
17
+ aiProvider: string;
18
+ aiModel: string;
19
+ frontend?: string;
20
+ backend?: string;
21
+ database?: string;
22
+ auth?: boolean;
23
+ reasoning: string;
24
+ }>;
25
+ /**
26
+ * Generate a PRD from user's product description
27
+ */
28
+ assistPRDCreation(input: {
29
+ userDescription: string;
30
+ aiOptions?: AIOptions;
31
+ streamingOptions?: StreamingOptions;
32
+ }): Promise<string>;
33
+ /**
34
+ * Suggest improvements to an existing PRD
35
+ */
36
+ assistPRDRefinement(input: {
37
+ currentPRD: string;
38
+ userFeedback: string;
39
+ aiOptions?: AIOptions;
40
+ streamingOptions?: StreamingOptions;
41
+ }): Promise<string>;
42
+ /**
43
+ * Help prioritize and organize tasks
44
+ */
45
+ assistTaskPrioritization(input: {
46
+ tasks: Array<{
47
+ id: string;
48
+ title: string;
49
+ description?: string;
50
+ }>;
51
+ userGuidance: string;
52
+ aiOptions?: AIOptions;
53
+ streamingOptions?: StreamingOptions;
54
+ }): Promise<{
55
+ prioritizedTasks: Array<{
56
+ id: string;
57
+ priority: number;
58
+ reasoning: string;
59
+ }>;
60
+ recommendations: string;
61
+ }>;
62
+ /**
63
+ * Generate custom instructions for task splitting
64
+ */
65
+ assistTaskSplitting(input: {
66
+ taskTitle: string;
67
+ taskContent?: string;
68
+ userGuidance: string;
69
+ aiOptions?: AIOptions;
70
+ streamingOptions?: StreamingOptions;
71
+ }): Promise<string>;
72
+ }
73
+ export declare const workflowAIAssistant: WorkflowAIAssistant;
74
+ //# sourceMappingURL=workflow-ai-assistant.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-ai-assistant.d.ts","sourceRoot":"","sources":["../../src/services/workflow-ai-assistant.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEtD,OAAO,EAAiB,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAGtE;;;GAGG;AACH,qBAAa,mBAAmB;IAC9B;;OAEG;IACG,gBAAgB,CAAC,KAAK,EAAE;QAC5B,eAAe,EAAE,MAAM,CAAC;QACxB,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;KACrC,GAAG,OAAO,CAAC;QACV,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IA+DF;;OAEG;IACG,iBAAiB,CAAC,KAAK,EAAE;QAC7B,eAAe,EAAE,MAAM,CAAC;QACxB,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;KACrC,GAAG,OAAO,CAAC,MAAM,CAAC;IAmDnB;;OAEG;IACG,mBAAmB,CAAC,KAAK,EAAE;QAC/B,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;KACrC,GAAG,OAAO,CAAC,MAAM,CAAC;IA+BnB;;OAEG;IACG,wBAAwB,CAAC,KAAK,EAAE;QACpC,KAAK,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAClE,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;KACrC,GAAG,OAAO,CAAC;QACV,gBAAgB,EAAE,KAAK,CAAC;YACtB,EAAE,EAAE,MAAM,CAAC;YACX,QAAQ,EAAE,MAAM,CAAC;YACjB,SAAS,EAAE,MAAM,CAAC;SACnB,CAAC,CAAC;QACH,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IA+DF;;OAEG;IACG,mBAAmB,CAAC,KAAK,EAAE;QAC/B,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;KACrC,GAAG,OAAO,CAAC,MAAM,CAAC;CA6BpB;AAGD,eAAO,MAAM,mBAAmB,qBAA4B,CAAC"}