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.
- package/README.md +96 -40
- package/dist/commands/prd.js +4 -0
- package/dist/commands/prompt.d.ts.map +1 -1
- package/dist/commands/prompt.js +69 -61
- 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 -594
- 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 +5 -3
- package/dist/lib/ai-service/ai-operations.d.ts.map +1 -1
- package/dist/lib/ai-service/ai-operations.js +231 -30
- package/dist/lib/ai-service/filesystem-tools.d.ts +69 -0
- package/dist/lib/ai-service/filesystem-tools.d.ts.map +1 -0
- package/dist/lib/ai-service/filesystem-tools.js +70 -0
- 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/executors/claude-code-executor.d.ts +6 -0
- package/dist/lib/executors/claude-code-executor.d.ts.map +1 -0
- package/dist/lib/executors/claude-code-executor.js +41 -0
- package/dist/lib/executors/codex-executor.d.ts +6 -0
- package/dist/lib/executors/codex-executor.d.ts.map +1 -0
- package/dist/lib/executors/codex-executor.js +41 -0
- package/dist/lib/executors/executor-factory.d.ts.map +1 -1
- package/dist/lib/executors/executor-factory.js +6 -3
- package/dist/lib/executors/gemini-executor.d.ts +6 -0
- package/dist/lib/executors/gemini-executor.d.ts.map +1 -0
- package/dist/lib/executors/gemini-executor.js +41 -0
- package/dist/lib/executors/opencode-executor.d.ts.map +1 -1
- package/dist/lib/executors/opencode-executor.js +2 -3
- 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 +8 -0
- package/dist/lib/prompt-builder.d.ts.map +1 -1
- package/dist/lib/prompt-builder.js +110 -4
- 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 +63 -14
- 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/prd.d.ts +2 -0
- package/dist/services/prd.d.ts.map +1 -1
- package/dist/services/prd.js +4 -4
- package/dist/services/tasks.d.ts +13 -6
- package/dist/services/tasks.d.ts.map +1 -1
- package/dist/services/tasks.js +202 -88
- 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
|
@@ -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
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
|
|
56
|
-
type:
|
|
57
|
-
message:
|
|
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, {
|
|
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
|
|
310
|
+
async enhanceTask(taskId, aiOptions, streamingOptions) {
|
|
257
311
|
const startTime = Date.now();
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
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
|
-
|
|
267
|
-
|
|
268
|
-
|
|
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
|
-
|
|
274
|
-
|
|
275
|
-
|
|
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
|
-
|
|
279
|
-
|
|
280
|
-
|
|
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
|
-
|
|
307
|
-
|
|
308
|
-
|
|
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,
|
|
380
|
+
async splitTask(taskId, aiOptions, promptOverride, messageOverride, streamingOptions, enableFilesystemTools) {
|
|
327
381
|
const startTime = Date.now();
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
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
|
-
|
|
342
|
-
|
|
343
|
-
|
|
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
|
-
|
|
352
|
-
|
|
353
|
-
|
|
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
|
-
|
|
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
|
-
|
|
366
|
-
type: 'progress',
|
|
419
|
+
hooks_1.hooks.emit("task:progress", {
|
|
367
420
|
message: `Creating subtask ${i + 1}/${subtaskData.length}: ${subtask.title}`,
|
|
368
|
-
|
|
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
|
-
|
|
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
|
|
464
|
+
async documentTask(taskId, force = false, aiOptions, streamingOptions) {
|
|
413
465
|
const startTime = Date.now();
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
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
|
-
|
|
425
|
-
|
|
426
|
-
|
|
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
|
-
|
|
439
|
-
|
|
440
|
-
|
|
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
|
-
|
|
454
|
-
|
|
455
|
-
|
|
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
|
-
|
|
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
|
-
|
|
480
|
-
|
|
481
|
-
|
|
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
|
-
|
|
495
|
-
|
|
496
|
-
|
|
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
|
-
|
|
502
|
-
|
|
503
|
-
|
|
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
|
|
567
|
+
async planTask(taskId, aiOptions, streamingOptions) {
|
|
516
568
|
const startTime = Date.now();
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
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
|
-
|
|
528
|
-
|
|
529
|
-
|
|
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
|
-
|
|
552
|
-
|
|
553
|
-
|
|
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
|
-
|
|
557
|
-
|
|
558
|
-
|
|
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
|
-
|
|
564
|
-
|
|
565
|
-
|
|
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"}
|