task-o-matic 0.0.3 → 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.
- package/README.md +96 -40
- package/dist/commands/tasks/create.d.ts +3 -0
- package/dist/commands/tasks/create.d.ts.map +1 -0
- package/dist/commands/tasks/create.js +58 -0
- package/dist/commands/tasks/delete.d.ts +3 -0
- package/dist/commands/tasks/delete.d.ts.map +1 -0
- package/dist/commands/tasks/delete.js +40 -0
- package/dist/commands/tasks/document.d.ts +5 -0
- package/dist/commands/tasks/document.d.ts.map +1 -0
- package/dist/commands/tasks/document.js +118 -0
- package/dist/commands/tasks/enhance.d.ts +3 -0
- package/dist/commands/tasks/enhance.d.ts.map +1 -0
- package/dist/commands/tasks/enhance.js +86 -0
- package/dist/commands/tasks/execute.d.ts +3 -0
- package/dist/commands/tasks/execute.d.ts.map +1 -0
- package/dist/commands/tasks/execute.js +33 -0
- package/dist/commands/tasks/index.d.ts +16 -0
- package/dist/commands/tasks/index.d.ts.map +1 -0
- package/dist/commands/tasks/index.js +31 -0
- package/dist/commands/tasks/list.d.ts +3 -0
- package/dist/commands/tasks/list.d.ts.map +1 -0
- package/dist/commands/tasks/list.js +27 -0
- package/dist/commands/tasks/next.d.ts +3 -0
- package/dist/commands/tasks/next.d.ts.map +1 -0
- package/dist/commands/tasks/next.js +44 -0
- package/dist/commands/tasks/plan.d.ts +7 -0
- package/dist/commands/tasks/plan.d.ts.map +1 -0
- package/dist/commands/tasks/plan.js +131 -0
- package/dist/commands/tasks/show.d.ts +3 -0
- package/dist/commands/tasks/show.d.ts.map +1 -0
- package/dist/commands/tasks/show.js +23 -0
- package/dist/commands/tasks/split.d.ts +3 -0
- package/dist/commands/tasks/split.d.ts.map +1 -0
- package/dist/commands/tasks/split.js +95 -0
- package/dist/commands/tasks/status.d.ts +3 -0
- package/dist/commands/tasks/status.d.ts.map +1 -0
- package/dist/commands/tasks/status.js +26 -0
- package/dist/commands/tasks/subtasks.d.ts +3 -0
- package/dist/commands/tasks/subtasks.d.ts.map +1 -0
- package/dist/commands/tasks/subtasks.js +35 -0
- package/dist/commands/tasks/tags.d.ts +4 -0
- package/dist/commands/tasks/tags.d.ts.map +1 -0
- package/dist/commands/tasks/tags.js +37 -0
- package/dist/commands/tasks/tree.d.ts +3 -0
- package/dist/commands/tasks/tree.d.ts.map +1 -0
- package/dist/commands/tasks/tree.js +20 -0
- package/dist/commands/tasks/update.d.ts +3 -0
- package/dist/commands/tasks/update.d.ts.map +1 -0
- package/dist/commands/tasks/update.js +35 -0
- package/dist/commands/tasks.d.ts.map +1 -1
- package/dist/commands/tasks.js +23 -686
- package/dist/commands/workflow.d.ts +4 -0
- package/dist/commands/workflow.d.ts.map +1 -0
- package/dist/commands/workflow.js +434 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/lib/ai-service/ai-operations.d.ts.map +1 -1
- package/dist/lib/ai-service/ai-operations.js +54 -22
- package/dist/lib/ai-service/research-tools.d.ts.map +1 -1
- package/dist/lib/ai-service/research-tools.js +2 -2
- package/dist/lib/context-builder.d.ts +2 -1
- package/dist/lib/context-builder.d.ts.map +1 -1
- package/dist/lib/context-builder.js +3 -8
- package/dist/lib/hooks/logger.d.ts +2 -0
- package/dist/lib/hooks/logger.d.ts.map +1 -0
- package/dist/lib/hooks/logger.js +27 -0
- package/dist/lib/hooks.d.ts +64 -0
- package/dist/lib/hooks.d.ts.map +1 -0
- package/dist/lib/hooks.js +60 -0
- package/dist/lib/index.d.ts +18 -17
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +3 -3
- package/dist/lib/prompt-builder.d.ts.map +1 -1
- package/dist/lib/prompt-builder.js +16 -8
- package/dist/lib/{storage.d.ts → storage/file-system.d.ts} +4 -3
- package/dist/lib/storage/file-system.d.ts.map +1 -0
- package/dist/lib/{storage.js → storage/file-system.js} +141 -152
- package/dist/lib/storage/types.d.ts +43 -0
- package/dist/lib/storage/types.d.ts.map +1 -0
- package/dist/lib/storage/types.js +2 -0
- package/dist/lib/task-execution.d.ts.map +1 -1
- package/dist/lib/task-execution.js +22 -3
- package/dist/prompts/workflow-assistance.d.ts +32 -0
- package/dist/prompts/workflow-assistance.d.ts.map +1 -0
- package/dist/prompts/workflow-assistance.js +130 -0
- package/dist/services/tasks.d.ts +4 -6
- package/dist/services/tasks.d.ts.map +1 -1
- package/dist/services/tasks.js +115 -96
- package/dist/services/workflow-ai-assistant.d.ts +74 -0
- package/dist/services/workflow-ai-assistant.d.ts.map +1 -0
- package/dist/services/workflow-ai-assistant.js +223 -0
- package/dist/test/hooks.test.d.ts +2 -0
- package/dist/test/hooks.test.d.ts.map +1 -0
- package/dist/test/hooks.test.js +58 -0
- package/dist/test/storage.test.js +16 -16
- package/dist/types/options.d.ts +35 -0
- package/dist/types/options.d.ts.map +1 -1
- package/dist/utils/ai-service-factory.d.ts +5 -5
- package/dist/utils/ai-service-factory.d.ts.map +1 -1
- package/dist/utils/ai-service-factory.js +4 -3
- package/dist/utils/workflow-prompts.d.ts +17 -0
- package/dist/utils/workflow-prompts.d.ts.map +1 -0
- package/dist/utils/workflow-prompts.js +88 -0
- package/package.json +2 -2
- package/dist/lib/storage.d.ts.map +0 -1
package/dist/services/tasks.js
CHANGED
|
@@ -37,6 +37,7 @@ exports.taskService = exports.TaskService = void 0;
|
|
|
37
37
|
const ai_service_factory_1 = require("../utils/ai-service-factory");
|
|
38
38
|
const stack_formatter_1 = require("../utils/stack-formatter");
|
|
39
39
|
const ai_config_builder_1 = require("../utils/ai-config-builder");
|
|
40
|
+
const hooks_1 = require("../lib/hooks");
|
|
40
41
|
/**
|
|
41
42
|
* TaskService - Centralized business logic for all task operations
|
|
42
43
|
* This service is framework-agnostic and can be used by CLI, TUI, or Web
|
|
@@ -50,16 +51,16 @@ class TaskService {
|
|
|
50
51
|
let content = input.content;
|
|
51
52
|
let aiMetadata;
|
|
52
53
|
if (input.aiEnhance) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
hooks_1.hooks.emit("task:progress", {
|
|
55
|
+
message: "Building context for task...",
|
|
56
|
+
type: "progress",
|
|
56
57
|
});
|
|
57
58
|
const context = await (0, ai_service_factory_1.getContextBuilder)().buildContextForNewTask(input.title, input.content);
|
|
58
59
|
const stackInfo = (0, stack_formatter_1.formatStackInfo)(context.stack);
|
|
59
60
|
const enhancementAIConfig = (0, ai_config_builder_1.buildAIConfig)(input.aiOptions);
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
hooks_1.hooks.emit("task:progress", {
|
|
62
|
+
message: "Enhancing task with AI documentation...",
|
|
63
|
+
type: "progress",
|
|
63
64
|
});
|
|
64
65
|
const taskDescription = input.content ?? "";
|
|
65
66
|
content = await (0, ai_service_factory_1.getAIOperations)().enhanceTaskWithDocumentation(`task-${Date.now()}`, input.title, taskDescription, stackInfo, input.streamingOptions, undefined, enhancementAIConfig, context.existingResearch);
|
|
@@ -74,9 +75,9 @@ class TaskService {
|
|
|
74
75
|
generatedAt: Date.now(),
|
|
75
76
|
};
|
|
76
77
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
hooks_1.hooks.emit("task:progress", {
|
|
79
|
+
message: "Saving task...",
|
|
80
|
+
type: "progress",
|
|
80
81
|
});
|
|
81
82
|
const task = await (0, ai_service_factory_1.getStorage)().createTask({
|
|
82
83
|
title: input.title,
|
|
@@ -85,10 +86,12 @@ class TaskService {
|
|
|
85
86
|
parentId: input.parentId,
|
|
86
87
|
estimatedEffort: input.effort,
|
|
87
88
|
}, aiMetadata);
|
|
88
|
-
|
|
89
|
-
type:
|
|
90
|
-
message:
|
|
89
|
+
hooks_1.hooks.emit("task:progress", {
|
|
90
|
+
type: "completed",
|
|
91
|
+
message: "Task created successfully",
|
|
91
92
|
});
|
|
93
|
+
// Emit task:created event
|
|
94
|
+
await hooks_1.hooks.emit("task:created", { task });
|
|
92
95
|
return { success: true, task, aiMetadata };
|
|
93
96
|
}
|
|
94
97
|
async listTasks(filters) {
|
|
@@ -144,6 +147,19 @@ class TaskService {
|
|
|
144
147
|
if (!updatedTask) {
|
|
145
148
|
throw new Error(`Failed to update task ${id}`);
|
|
146
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
|
+
}
|
|
147
163
|
return updatedTask;
|
|
148
164
|
}
|
|
149
165
|
async setTaskStatus(id, status) {
|
|
@@ -173,7 +189,10 @@ class TaskService {
|
|
|
173
189
|
else if (cascade) {
|
|
174
190
|
// Recursively delete subtasks
|
|
175
191
|
for (const subtask of subtasks) {
|
|
176
|
-
const result = await this.deleteTask(subtask.id, {
|
|
192
|
+
const result = await this.deleteTask(subtask.id, {
|
|
193
|
+
cascade: true,
|
|
194
|
+
force: true,
|
|
195
|
+
});
|
|
177
196
|
deleted.push(...result.deleted);
|
|
178
197
|
orphanedSubtasks.push(...result.orphanedSubtasks);
|
|
179
198
|
}
|
|
@@ -182,6 +201,8 @@ class TaskService {
|
|
|
182
201
|
const success = await storage.deleteTask(id);
|
|
183
202
|
if (success) {
|
|
184
203
|
deleted.push(taskToDelete);
|
|
204
|
+
// Emit task:deleted event
|
|
205
|
+
await hooks_1.hooks.emit("task:deleted", { taskId: id });
|
|
185
206
|
}
|
|
186
207
|
return { success: true, deleted, orphanedSubtasks };
|
|
187
208
|
}
|
|
@@ -286,31 +307,31 @@ class TaskService {
|
|
|
286
307
|
// ============================================================================
|
|
287
308
|
// AI OPERATIONS
|
|
288
309
|
// ============================================================================
|
|
289
|
-
async enhanceTask(taskId, aiOptions, streamingOptions
|
|
310
|
+
async enhanceTask(taskId, aiOptions, streamingOptions) {
|
|
290
311
|
const startTime = Date.now();
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
312
|
+
hooks_1.hooks.emit("task:progress", {
|
|
313
|
+
message: "Starting task enhancement...",
|
|
314
|
+
type: "started",
|
|
294
315
|
});
|
|
295
316
|
const task = await (0, ai_service_factory_1.getStorage)().getTask(taskId);
|
|
296
317
|
if (!task) {
|
|
297
318
|
throw new Error(`Task with ID ${taskId} not found`);
|
|
298
319
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
320
|
+
hooks_1.hooks.emit("task:progress", {
|
|
321
|
+
message: "Building context...",
|
|
322
|
+
type: "progress",
|
|
302
323
|
});
|
|
303
324
|
const context = await (0, ai_service_factory_1.getContextBuilder)().buildContext(taskId);
|
|
304
325
|
const stackInfo = (0, stack_formatter_1.formatStackInfo)(context.stack);
|
|
305
326
|
const enhancementAIConfig = (0, ai_config_builder_1.buildAIConfig)(aiOptions);
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
327
|
+
hooks_1.hooks.emit("task:progress", {
|
|
328
|
+
message: "Calling AI for enhancement...",
|
|
329
|
+
type: "progress",
|
|
309
330
|
});
|
|
310
331
|
const enhancedContent = await (0, ai_service_factory_1.getAIOperations)().enhanceTaskWithDocumentation(task.id, task.title, task.description ?? "", stackInfo, streamingOptions, undefined, enhancementAIConfig, context.existingResearch);
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
332
|
+
hooks_1.hooks.emit("task:progress", {
|
|
333
|
+
message: "Saving enhanced content...",
|
|
334
|
+
type: "progress",
|
|
314
335
|
});
|
|
315
336
|
const originalLength = task.description?.length || 0;
|
|
316
337
|
if (enhancedContent.length > 200) {
|
|
@@ -336,9 +357,9 @@ class TaskService {
|
|
|
336
357
|
};
|
|
337
358
|
await (0, ai_service_factory_1.getStorage)().saveTaskAIMetadata(aiMetadata);
|
|
338
359
|
const duration = Date.now() - startTime;
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
360
|
+
hooks_1.hooks.emit("task:progress", {
|
|
361
|
+
message: "Task enhancement completed",
|
|
362
|
+
type: "completed",
|
|
342
363
|
});
|
|
343
364
|
return {
|
|
344
365
|
success: true,
|
|
@@ -356,11 +377,11 @@ class TaskService {
|
|
|
356
377
|
},
|
|
357
378
|
};
|
|
358
379
|
}
|
|
359
|
-
async splitTask(taskId, aiOptions, promptOverride, messageOverride, streamingOptions,
|
|
380
|
+
async splitTask(taskId, aiOptions, promptOverride, messageOverride, streamingOptions, enableFilesystemTools) {
|
|
360
381
|
const startTime = Date.now();
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
382
|
+
hooks_1.hooks.emit("task:progress", {
|
|
383
|
+
message: "Starting task breakdown...",
|
|
384
|
+
type: "started",
|
|
364
385
|
});
|
|
365
386
|
const task = await (0, ai_service_factory_1.getStorage)().getTask(taskId);
|
|
366
387
|
if (!task) {
|
|
@@ -371,9 +392,9 @@ class TaskService {
|
|
|
371
392
|
if (existingSubtasks.length > 0) {
|
|
372
393
|
throw new Error(`Task ${task.title} already has ${existingSubtasks.length} subtasks. Use existing subtasks or delete them first.`);
|
|
373
394
|
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
395
|
+
hooks_1.hooks.emit("task:progress", {
|
|
396
|
+
message: "Building context...",
|
|
397
|
+
type: "progress",
|
|
377
398
|
});
|
|
378
399
|
// Build comprehensive context
|
|
379
400
|
const context = await (0, ai_service_factory_1.getContextBuilder)().buildContext(taskId);
|
|
@@ -381,25 +402,23 @@ class TaskService {
|
|
|
381
402
|
// Get full task content
|
|
382
403
|
const fullContent = context.task.fullContent || task.description || "";
|
|
383
404
|
const breakdownAIConfig = (0, ai_config_builder_1.buildAIConfig)(aiOptions);
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
405
|
+
hooks_1.hooks.emit("task:progress", {
|
|
406
|
+
message: "Calling AI to break down task...",
|
|
407
|
+
type: "progress",
|
|
387
408
|
});
|
|
388
409
|
// Use AI service to break down the task with enhanced context
|
|
389
410
|
const subtaskData = await (0, ai_service_factory_1.getAIOperations)().breakdownTask(task, breakdownAIConfig, promptOverride, messageOverride, streamingOptions, undefined, fullContent, stackInfo, existingSubtasks, enableFilesystemTools);
|
|
390
|
-
|
|
391
|
-
type: 'progress',
|
|
411
|
+
hooks_1.hooks.emit("task:progress", {
|
|
392
412
|
message: `Creating ${subtaskData.length} subtasks...`,
|
|
413
|
+
type: "progress",
|
|
393
414
|
});
|
|
394
415
|
// Create subtasks
|
|
395
416
|
const createdSubtasks = [];
|
|
396
417
|
for (let i = 0; i < subtaskData.length; i++) {
|
|
397
418
|
const subtask = subtaskData[i];
|
|
398
|
-
|
|
399
|
-
type: 'progress',
|
|
419
|
+
hooks_1.hooks.emit("task:progress", {
|
|
400
420
|
message: `Creating subtask ${i + 1}/${subtaskData.length}: ${subtask.title}`,
|
|
401
|
-
|
|
402
|
-
total: subtaskData.length,
|
|
421
|
+
type: "progress",
|
|
403
422
|
});
|
|
404
423
|
const result = await this.createTask({
|
|
405
424
|
title: subtask.title,
|
|
@@ -423,9 +442,9 @@ class TaskService {
|
|
|
423
442
|
};
|
|
424
443
|
await (0, ai_service_factory_1.getStorage)().saveTaskAIMetadata(aiMetadata);
|
|
425
444
|
const duration = Date.now() - startTime;
|
|
426
|
-
|
|
427
|
-
type: 'completed',
|
|
445
|
+
hooks_1.hooks.emit("task:progress", {
|
|
428
446
|
message: `Task split into ${createdSubtasks.length} subtasks`,
|
|
447
|
+
type: "completed",
|
|
429
448
|
});
|
|
430
449
|
return {
|
|
431
450
|
success: true,
|
|
@@ -442,11 +461,11 @@ class TaskService {
|
|
|
442
461
|
},
|
|
443
462
|
};
|
|
444
463
|
}
|
|
445
|
-
async documentTask(taskId, force = false, aiOptions, streamingOptions
|
|
464
|
+
async documentTask(taskId, force = false, aiOptions, streamingOptions) {
|
|
446
465
|
const startTime = Date.now();
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
466
|
+
hooks_1.hooks.emit("task:progress", {
|
|
467
|
+
message: "Analyzing documentation needs...",
|
|
468
|
+
type: "started",
|
|
450
469
|
});
|
|
451
470
|
const task = await (0, ai_service_factory_1.getStorage)().getTask(taskId);
|
|
452
471
|
if (!task) {
|
|
@@ -454,9 +473,9 @@ class TaskService {
|
|
|
454
473
|
}
|
|
455
474
|
if (task.documentation && !force) {
|
|
456
475
|
if ((0, ai_service_factory_1.getContextBuilder)().isDocumentationFresh(task.documentation)) {
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
476
|
+
hooks_1.hooks.emit("task:progress", {
|
|
477
|
+
message: "Documentation is fresh, skipping analysis",
|
|
478
|
+
type: "info",
|
|
460
479
|
});
|
|
461
480
|
return {
|
|
462
481
|
success: true,
|
|
@@ -468,9 +487,9 @@ class TaskService {
|
|
|
468
487
|
};
|
|
469
488
|
}
|
|
470
489
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
490
|
+
hooks_1.hooks.emit("task:progress", {
|
|
491
|
+
message: "Building context...",
|
|
492
|
+
type: "progress",
|
|
474
493
|
});
|
|
475
494
|
const context = await (0, ai_service_factory_1.getContextBuilder)().buildContext(taskId);
|
|
476
495
|
const stackInfo = (0, stack_formatter_1.formatStackInfo)(context.stack);
|
|
@@ -483,17 +502,17 @@ class TaskService {
|
|
|
483
502
|
// Get existing documentations from all tasks
|
|
484
503
|
const tasks = await (0, ai_service_factory_1.getStorage)().getTasks();
|
|
485
504
|
const documentations = tasks.map((task) => task.documentation);
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
505
|
+
hooks_1.hooks.emit("task:progress", {
|
|
506
|
+
message: "Calling AI to analyze documentation needs...",
|
|
507
|
+
type: "progress",
|
|
489
508
|
});
|
|
490
509
|
// First analyze what documentation is needed
|
|
491
510
|
const analysis = await (0, ai_service_factory_1.getAIOperations)().analyzeDocumentationNeeds(task.id, task.title, fullContent, stackInfo, streamingOptions, undefined, analysisAIConfig, documentations);
|
|
492
511
|
let documentation;
|
|
493
512
|
if (analysis.libraries.length > 0) {
|
|
494
|
-
|
|
495
|
-
type: 'progress',
|
|
513
|
+
hooks_1.hooks.emit("task:progress", {
|
|
496
514
|
message: `Fetching documentation for ${analysis.libraries.length} libraries...`,
|
|
515
|
+
type: "progress",
|
|
497
516
|
});
|
|
498
517
|
// Build research object from actual libraries
|
|
499
518
|
const research = {};
|
|
@@ -509,9 +528,9 @@ class TaskService {
|
|
|
509
528
|
doc: docFile,
|
|
510
529
|
});
|
|
511
530
|
}
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
531
|
+
hooks_1.hooks.emit("task:progress", {
|
|
532
|
+
message: "Generating documentation recap...",
|
|
533
|
+
type: "progress",
|
|
515
534
|
});
|
|
516
535
|
const recap = await (0, ai_service_factory_1.getAIOperations)().generateDocumentationRecap(analysis.libraries, analysis.toolResults?.map((tr) => ({
|
|
517
536
|
library: tr.toolName,
|
|
@@ -524,16 +543,16 @@ class TaskService {
|
|
|
524
543
|
files: analysis.files || [],
|
|
525
544
|
research,
|
|
526
545
|
};
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
546
|
+
hooks_1.hooks.emit("task:progress", {
|
|
547
|
+
message: "Saving documentation...",
|
|
548
|
+
type: "progress",
|
|
530
549
|
});
|
|
531
550
|
await (0, ai_service_factory_1.getStorage)().updateTask(taskId, { documentation });
|
|
532
551
|
}
|
|
533
552
|
const duration = Date.now() - startTime;
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
553
|
+
hooks_1.hooks.emit("task:progress", {
|
|
554
|
+
message: "Documentation analysis completed",
|
|
555
|
+
type: "completed",
|
|
537
556
|
});
|
|
538
557
|
return {
|
|
539
558
|
success: true,
|
|
@@ -545,11 +564,11 @@ class TaskService {
|
|
|
545
564
|
},
|
|
546
565
|
};
|
|
547
566
|
}
|
|
548
|
-
async planTask(taskId, aiOptions, streamingOptions
|
|
567
|
+
async planTask(taskId, aiOptions, streamingOptions) {
|
|
549
568
|
const startTime = Date.now();
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
569
|
+
hooks_1.hooks.emit("task:progress", {
|
|
570
|
+
message: "Creating implementation plan...",
|
|
571
|
+
type: "started",
|
|
553
572
|
});
|
|
554
573
|
const task = await (0, ai_service_factory_1.getStorage)().getTask(taskId);
|
|
555
574
|
if (!task) {
|
|
@@ -557,9 +576,9 @@ class TaskService {
|
|
|
557
576
|
}
|
|
558
577
|
const aiService = (0, ai_service_factory_1.getAIOperations)();
|
|
559
578
|
const planAIConfig = (0, ai_config_builder_1.buildAIConfig)(aiOptions);
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
579
|
+
hooks_1.hooks.emit("task:progress", {
|
|
580
|
+
message: "Building task context...",
|
|
581
|
+
type: "progress",
|
|
563
582
|
});
|
|
564
583
|
// Build task context and details
|
|
565
584
|
let taskContext = `Task ID: ${task.id}\nTitle: ${task.title}\n`;
|
|
@@ -581,21 +600,21 @@ class TaskService {
|
|
|
581
600
|
taskDetails += ` ${subtask.description || "No description"}\n\n`;
|
|
582
601
|
});
|
|
583
602
|
}
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
603
|
+
hooks_1.hooks.emit("task:progress", {
|
|
604
|
+
message: "Calling AI to create plan...",
|
|
605
|
+
type: "progress",
|
|
587
606
|
});
|
|
588
607
|
const plan = await aiService.planTask(taskContext, taskDetails, planAIConfig, undefined, undefined, streamingOptions);
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
608
|
+
hooks_1.hooks.emit("task:progress", {
|
|
609
|
+
message: "Saving plan...",
|
|
610
|
+
type: "progress",
|
|
592
611
|
});
|
|
593
612
|
// Save the plan to storage
|
|
594
613
|
await (0, ai_service_factory_1.getStorage)().savePlan(taskId, plan);
|
|
595
614
|
const duration = Date.now() - startTime;
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
615
|
+
hooks_1.hooks.emit("task:progress", {
|
|
616
|
+
message: "Implementation plan created",
|
|
617
|
+
type: "completed",
|
|
599
618
|
});
|
|
600
619
|
const aiConfig = (0, ai_service_factory_1.getModelProvider)().getAIConfig();
|
|
601
620
|
return {
|
|
@@ -623,13 +642,13 @@ class TaskService {
|
|
|
623
642
|
throw new Error(`Task with ID ${taskId} not found`);
|
|
624
643
|
}
|
|
625
644
|
try {
|
|
626
|
-
const { readFileSync, existsSync } = await Promise.resolve().then(() => __importStar(require(
|
|
627
|
-
const { resolve } = await Promise.resolve().then(() => __importStar(require(
|
|
645
|
+
const { readFileSync, existsSync } = await Promise.resolve().then(() => __importStar(require("fs")));
|
|
646
|
+
const { resolve } = await Promise.resolve().then(() => __importStar(require("path")));
|
|
628
647
|
const resolvedPath = resolve(filePath);
|
|
629
648
|
if (!existsSync(resolvedPath)) {
|
|
630
649
|
throw new Error(`Documentation file not found: ${filePath}`);
|
|
631
650
|
}
|
|
632
|
-
const content = readFileSync(resolvedPath,
|
|
651
|
+
const content = readFileSync(resolvedPath, "utf-8");
|
|
633
652
|
const savedPath = await (0, ai_service_factory_1.getStorage)().saveTaskDocumentation(taskId, content);
|
|
634
653
|
return {
|
|
635
654
|
filePath: savedPath,
|
|
@@ -637,7 +656,7 @@ class TaskService {
|
|
|
637
656
|
};
|
|
638
657
|
}
|
|
639
658
|
catch (error) {
|
|
640
|
-
throw new Error(`Failed to add documentation from file: ${error instanceof Error ? error.message :
|
|
659
|
+
throw new Error(`Failed to add documentation from file: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
641
660
|
}
|
|
642
661
|
}
|
|
643
662
|
async setTaskPlan(taskId, planText, planFilePath) {
|
|
@@ -648,23 +667,23 @@ class TaskService {
|
|
|
648
667
|
let plan;
|
|
649
668
|
if (planFilePath) {
|
|
650
669
|
try {
|
|
651
|
-
const { readFileSync, existsSync } = await Promise.resolve().then(() => __importStar(require(
|
|
652
|
-
const { resolve } = await Promise.resolve().then(() => __importStar(require(
|
|
670
|
+
const { readFileSync, existsSync } = await Promise.resolve().then(() => __importStar(require("fs")));
|
|
671
|
+
const { resolve } = await Promise.resolve().then(() => __importStar(require("path")));
|
|
653
672
|
const resolvedPath = resolve(planFilePath);
|
|
654
673
|
if (!existsSync(resolvedPath)) {
|
|
655
674
|
throw new Error(`Plan file not found: ${planFilePath}`);
|
|
656
675
|
}
|
|
657
|
-
plan = readFileSync(resolvedPath,
|
|
676
|
+
plan = readFileSync(resolvedPath, "utf-8");
|
|
658
677
|
}
|
|
659
678
|
catch (error) {
|
|
660
|
-
throw new Error(`Failed to read plan file: ${error instanceof Error ? error.message :
|
|
679
|
+
throw new Error(`Failed to read plan file: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
661
680
|
}
|
|
662
681
|
}
|
|
663
682
|
else if (planText) {
|
|
664
683
|
plan = planText;
|
|
665
684
|
}
|
|
666
685
|
else {
|
|
667
|
-
throw new Error(
|
|
686
|
+
throw new Error("Either planText or planFilePath must be provided");
|
|
668
687
|
}
|
|
669
688
|
await (0, ai_service_factory_1.getStorage)().savePlan(taskId, plan);
|
|
670
689
|
const planFile = `plans/${taskId}.md`;
|
|
@@ -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"}
|