task-o-matic 0.0.9 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/dist/cli/display/progress.d.ts +1 -1
  2. package/dist/cli/display/progress.d.ts.map +1 -1
  3. package/dist/cli/display/progress.js +16 -13
  4. package/dist/commands/benchmark.js +70 -2
  5. package/dist/commands/init.js +48 -27
  6. package/dist/commands/prd.d.ts.map +1 -1
  7. package/dist/commands/prd.js +201 -0
  8. package/dist/commands/tasks/execute-loop.d.ts.map +1 -1
  9. package/dist/commands/tasks/execute-loop.js +10 -0
  10. package/dist/commands/tasks/execute.d.ts.map +1 -1
  11. package/dist/commands/tasks/execute.js +4 -0
  12. package/dist/commands/workflow.d.ts.map +1 -1
  13. package/dist/commands/workflow.js +56 -2
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +2 -0
  16. package/dist/lib/ai-service/ai-operations.d.ts +13 -10
  17. package/dist/lib/ai-service/ai-operations.d.ts.map +1 -1
  18. package/dist/lib/ai-service/ai-operations.js +35 -995
  19. package/dist/lib/ai-service/base-operations.d.ts +13 -0
  20. package/dist/lib/ai-service/base-operations.d.ts.map +1 -0
  21. package/dist/lib/ai-service/base-operations.js +79 -0
  22. package/dist/lib/ai-service/documentation-operations.d.ts +18 -0
  23. package/dist/lib/ai-service/documentation-operations.d.ts.map +1 -0
  24. package/dist/lib/ai-service/documentation-operations.js +291 -0
  25. package/dist/lib/ai-service/prd-operations.d.ts +14 -0
  26. package/dist/lib/ai-service/prd-operations.d.ts.map +1 -0
  27. package/dist/lib/ai-service/prd-operations.js +405 -0
  28. package/dist/lib/ai-service/task-operations.d.ts +12 -0
  29. package/dist/lib/ai-service/task-operations.d.ts.map +1 -0
  30. package/dist/lib/ai-service/task-operations.js +225 -0
  31. package/dist/lib/benchmark/registry.d.ts.map +1 -1
  32. package/dist/lib/benchmark/registry.js +127 -0
  33. package/dist/lib/better-t-stack-cli.d.ts +4 -1
  34. package/dist/lib/better-t-stack-cli.d.ts.map +1 -1
  35. package/dist/lib/better-t-stack-cli.js +126 -5
  36. package/dist/lib/config.d.ts +13 -6
  37. package/dist/lib/config.d.ts.map +1 -1
  38. package/dist/lib/config.js +90 -48
  39. package/dist/lib/context-builder.d.ts +13 -1
  40. package/dist/lib/context-builder.d.ts.map +1 -1
  41. package/dist/lib/context-builder.js +68 -36
  42. package/dist/lib/executors/claude-code-executor.d.ts +5 -2
  43. package/dist/lib/executors/claude-code-executor.d.ts.map +1 -1
  44. package/dist/lib/executors/claude-code-executor.js +30 -3
  45. package/dist/lib/executors/codex-executor.d.ts +5 -2
  46. package/dist/lib/executors/codex-executor.d.ts.map +1 -1
  47. package/dist/lib/executors/codex-executor.js +30 -3
  48. package/dist/lib/executors/executor-factory.d.ts +2 -2
  49. package/dist/lib/executors/executor-factory.d.ts.map +1 -1
  50. package/dist/lib/executors/executor-factory.js +5 -5
  51. package/dist/lib/executors/gemini-executor.d.ts +5 -2
  52. package/dist/lib/executors/gemini-executor.d.ts.map +1 -1
  53. package/dist/lib/executors/gemini-executor.js +30 -3
  54. package/dist/lib/executors/opencode-executor.d.ts +5 -2
  55. package/dist/lib/executors/opencode-executor.d.ts.map +1 -1
  56. package/dist/lib/executors/opencode-executor.js +30 -7
  57. package/dist/lib/index.d.ts +5 -0
  58. package/dist/lib/index.d.ts.map +1 -1
  59. package/dist/lib/index.js +7 -1
  60. package/dist/lib/prompt-builder.d.ts.map +1 -1
  61. package/dist/lib/prompt-builder.js +1 -0
  62. package/dist/lib/storage/file-system.d.ts +3 -7
  63. package/dist/lib/storage/file-system.d.ts.map +1 -1
  64. package/dist/lib/storage/file-system.js +50 -230
  65. package/dist/lib/storage/storage-callbacks.d.ts +17 -0
  66. package/dist/lib/storage/storage-callbacks.d.ts.map +1 -0
  67. package/dist/lib/storage/storage-callbacks.js +94 -0
  68. package/dist/lib/task-execution.d.ts.map +1 -1
  69. package/dist/lib/task-execution.js +16 -9
  70. package/dist/lib/task-loop-execution.d.ts.map +1 -1
  71. package/dist/lib/task-loop-execution.js +207 -8
  72. package/dist/prompts/index.d.ts +2 -0
  73. package/dist/prompts/index.d.ts.map +1 -1
  74. package/dist/prompts/index.js +2 -0
  75. package/dist/prompts/prd-combination.d.ts +2 -0
  76. package/dist/prompts/prd-combination.d.ts.map +1 -0
  77. package/dist/prompts/prd-combination.js +35 -0
  78. package/dist/prompts/prd-generation.d.ts +2 -0
  79. package/dist/prompts/prd-generation.d.ts.map +1 -0
  80. package/dist/prompts/prd-generation.js +49 -0
  81. package/dist/services/prd.d.ts +43 -0
  82. package/dist/services/prd.d.ts.map +1 -1
  83. package/dist/services/prd.js +121 -0
  84. package/dist/services/workflow-ai-assistant.d.ts.map +1 -1
  85. package/dist/services/workflow-ai-assistant.js +1 -40
  86. package/dist/services/workflow.d.ts +10 -0
  87. package/dist/services/workflow.d.ts.map +1 -1
  88. package/dist/services/workflow.js +118 -40
  89. package/dist/test/hooks.test.js +19 -10
  90. package/dist/test/integration/callbacks.test.d.ts +2 -0
  91. package/dist/test/integration/callbacks.test.d.ts.map +1 -0
  92. package/dist/test/integration/callbacks.test.js +64 -0
  93. package/dist/test/task-loop-git.test.js +33 -0
  94. package/dist/test/validation.test.d.ts +2 -0
  95. package/dist/test/validation.test.d.ts.map +1 -0
  96. package/dist/test/validation.test.js +22 -0
  97. package/dist/types/callbacks.d.ts +9 -6
  98. package/dist/types/callbacks.d.ts.map +1 -1
  99. package/dist/types/index.d.ts +17 -2
  100. package/dist/types/index.d.ts.map +1 -1
  101. package/dist/types/workflow-options.d.ts +7 -0
  102. package/dist/types/workflow-options.d.ts.map +1 -1
  103. package/dist/utils/ai-service-factory.d.ts +15 -1
  104. package/dist/utils/ai-service-factory.d.ts.map +1 -1
  105. package/dist/utils/ai-service-factory.js +29 -1
  106. package/dist/utils/streaming-options.d.ts +1 -1
  107. package/dist/utils/streaming-options.d.ts.map +1 -1
  108. package/dist/utils/streaming-options.js +31 -18
  109. package/docs/agents/cli.md +191 -0
  110. package/package.json +3 -2
@@ -0,0 +1,405 @@
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
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.PRDOperations = void 0;
37
+ const ai_1 = require("ai");
38
+ const prompt_builder_1 = require("../prompt-builder");
39
+ const prompts_1 = require("../../prompts");
40
+ const filesystem_tools_1 = require("./filesystem-tools");
41
+ const base_operations_1 = require("./base-operations");
42
+ class PRDOperations extends base_operations_1.BaseOperations {
43
+ async parsePRD(prdContent, config, promptOverride, userMessage, streamingOptions, retryConfig, workingDirectory, enableFilesystemTools) {
44
+ return this.retryHandler.executeWithRetry(async () => {
45
+ let stackInfo = "";
46
+ try {
47
+ stackInfo = await prompt_builder_1.PromptBuilder.detectStackInfo(workingDirectory);
48
+ if (stackInfo === "Not detected") {
49
+ stackInfo = "";
50
+ }
51
+ }
52
+ catch (error) {
53
+ // Stack info not available
54
+ }
55
+ let enhancedPrompt;
56
+ if (promptOverride) {
57
+ enhancedPrompt = promptOverride;
58
+ }
59
+ else {
60
+ const variables = {
61
+ PRD_CONTENT: prdContent,
62
+ };
63
+ if (stackInfo) {
64
+ variables.STACK_INFO = stackInfo;
65
+ }
66
+ const promptResult = prompt_builder_1.PromptBuilder.buildPrompt({
67
+ name: "prd-parsing",
68
+ type: "user",
69
+ variables,
70
+ });
71
+ if (!promptResult.success) {
72
+ throw new Error(`Failed to build PRD parsing prompt: ${promptResult.error}`);
73
+ }
74
+ enhancedPrompt = promptResult.prompt;
75
+ }
76
+ let response;
77
+ if (enableFilesystemTools) {
78
+ const model = this.modelProvider.getModel({
79
+ ...this.modelProvider.getAIConfig(),
80
+ ...config,
81
+ });
82
+ const allTools = {
83
+ ...filesystem_tools_1.filesystemTools,
84
+ };
85
+ const result = await (0, ai_1.streamText)({
86
+ model,
87
+ tools: allTools,
88
+ system: prompts_1.PRD_PARSING_SYSTEM_PROMPT +
89
+ `
90
+
91
+ You have access to filesystem tools that allow you to:
92
+ - readFile: Read the contents of any file in the project
93
+ - listDirectory: List contents of directories
94
+
95
+ Use these tools to understand the project structure, existing code patterns, and dependencies when parsing the PRD and creating tasks.`,
96
+ messages: [
97
+ { role: "user", content: userMessage || enhancedPrompt },
98
+ ],
99
+ maxRetries: 0,
100
+ onChunk: streamingOptions?.onChunk
101
+ ? ({ chunk }) => {
102
+ if (chunk.type === "text-delta") {
103
+ streamingOptions.onChunk(chunk.text);
104
+ }
105
+ else if (chunk.type === "reasoning-delta") {
106
+ streamingOptions.onReasoning?.(chunk.text);
107
+ }
108
+ }
109
+ : undefined,
110
+ onFinish: streamingOptions?.onFinish
111
+ ? ({ text, finishReason, usage }) => {
112
+ streamingOptions.onFinish({
113
+ text,
114
+ finishReason,
115
+ usage,
116
+ isAborted: false,
117
+ });
118
+ }
119
+ : undefined,
120
+ });
121
+ response = await result.text;
122
+ }
123
+ else {
124
+ response = await this.streamText("", config, prompts_1.PRD_PARSING_SYSTEM_PROMPT, userMessage || enhancedPrompt, streamingOptions, { maxAttempts: 1 });
125
+ }
126
+ const parseResult = this.jsonParser.parseJSONFromResponse(response);
127
+ if (!parseResult.success) {
128
+ throw new Error(parseResult.error || "Failed to parse PRD response");
129
+ }
130
+ const parsed = parseResult.data;
131
+ const tasks = (parsed?.tasks || []).map((task, index) => {
132
+ const taskId = task.id || (index + 1).toString();
133
+ const { title, description, content, effort, dependencies, ...extraData } = task;
134
+ let fullContent = "";
135
+ if (description || content) {
136
+ fullContent = description || content || "";
137
+ }
138
+ if (Object.keys(extraData).length > 0) {
139
+ fullContent += "\n\n## Additional AI-Generated Information\n";
140
+ for (const [key, value] of Object.entries(extraData)) {
141
+ fullContent += `\n**${key}:** ${JSON.stringify(value, null, 2)}`;
142
+ }
143
+ }
144
+ return {
145
+ id: taskId,
146
+ title: task.title,
147
+ description: (task.description || task.content || "").substring(0, 200) +
148
+ ((task.description || task.content || "").length > 200
149
+ ? "..."
150
+ : ""),
151
+ content: fullContent,
152
+ status: "todo",
153
+ createdAt: Date.now(),
154
+ updatedAt: Date.now(),
155
+ estimatedEffort: task.effort,
156
+ dependencies: task.dependencies || [],
157
+ tags: task.tags || [],
158
+ };
159
+ });
160
+ return {
161
+ tasks,
162
+ summary: parsed?.summary || "PRD parsed successfully",
163
+ estimatedDuration: parsed?.estimatedDuration || "Unknown",
164
+ confidence: parsed?.confidence || 0.7,
165
+ };
166
+ }, retryConfig, "PRD parsing");
167
+ }
168
+ async reworkPRD(prdContent, feedback, config, promptOverride, userMessage, streamingOptions, retryConfig, workingDirectory, enableFilesystemTools) {
169
+ return this.retryHandler.executeWithRetry(async () => {
170
+ let stackInfo = "";
171
+ try {
172
+ stackInfo = await prompt_builder_1.PromptBuilder.detectStackInfo(workingDirectory);
173
+ if (stackInfo === "Not detected") {
174
+ stackInfo = "";
175
+ }
176
+ }
177
+ catch (error) {
178
+ // Stack info not available
179
+ }
180
+ let prompt;
181
+ if (promptOverride) {
182
+ prompt = promptOverride;
183
+ }
184
+ else {
185
+ const variables = {
186
+ PRD_CONTENT: prdContent,
187
+ USER_FEEDBACK: feedback,
188
+ };
189
+ if (stackInfo) {
190
+ variables.STACK_INFO = stackInfo;
191
+ }
192
+ const promptResult = prompt_builder_1.PromptBuilder.buildPrompt({
193
+ name: "prd-rework",
194
+ type: "user",
195
+ variables,
196
+ });
197
+ if (!promptResult.success) {
198
+ throw new Error(`Failed to build PRD rework prompt: ${promptResult.error}`);
199
+ }
200
+ prompt = promptResult.prompt;
201
+ }
202
+ if (enableFilesystemTools) {
203
+ const model = this.modelProvider.getModel({
204
+ ...this.modelProvider.getAIConfig(),
205
+ ...config,
206
+ });
207
+ const allTools = {
208
+ ...filesystem_tools_1.filesystemTools,
209
+ };
210
+ const result = await (0, ai_1.streamText)({
211
+ model,
212
+ tools: allTools,
213
+ system: prompts_1.PRD_REWORK_SYSTEM_PROMPT +
214
+ `
215
+
216
+ You have access to filesystem tools that allow you to:
217
+ - readFile: Read the contents of any file in the project
218
+ - listDirectory: List contents of directories
219
+
220
+ Use these tools to understand the current project structure, existing code patterns, and dependencies when reworking the PRD based on feedback.`,
221
+ messages: [{ role: "user", content: userMessage || prompt }],
222
+ maxRetries: 0,
223
+ onChunk: streamingOptions?.onChunk
224
+ ? ({ chunk }) => {
225
+ if (chunk.type === "text-delta") {
226
+ streamingOptions.onChunk(chunk.text);
227
+ }
228
+ else if (chunk.type === "reasoning-delta") {
229
+ streamingOptions.onReasoning?.(chunk.text);
230
+ }
231
+ }
232
+ : undefined,
233
+ onFinish: streamingOptions?.onFinish
234
+ ? ({ text, finishReason, usage }) => {
235
+ streamingOptions.onFinish({
236
+ text,
237
+ finishReason,
238
+ usage,
239
+ isAborted: false,
240
+ });
241
+ }
242
+ : undefined,
243
+ });
244
+ return await result.text;
245
+ }
246
+ else {
247
+ return this.streamText("", config, prompts_1.PRD_REWORK_SYSTEM_PROMPT, userMessage || prompt, streamingOptions, { maxAttempts: 1 });
248
+ }
249
+ }, retryConfig, "PRD rework");
250
+ }
251
+ async generatePRDQuestions(prdContent, config, promptOverride, userMessage, streamingOptions, retryConfig, workingDirectory, enableFilesystemTools) {
252
+ return this.retryHandler.executeWithRetry(async () => {
253
+ let stackInfo = "";
254
+ try {
255
+ stackInfo = await prompt_builder_1.PromptBuilder.detectStackInfo(workingDirectory);
256
+ if (stackInfo === "Not detected") {
257
+ stackInfo = "";
258
+ }
259
+ }
260
+ catch (error) {
261
+ // Stack info not available
262
+ }
263
+ let prompt;
264
+ if (promptOverride) {
265
+ prompt = promptOverride;
266
+ }
267
+ else {
268
+ const variables = {
269
+ PRD_CONTENT: prdContent,
270
+ };
271
+ if (stackInfo) {
272
+ variables.STACK_INFO = stackInfo;
273
+ }
274
+ const promptResult = prompt_builder_1.PromptBuilder.buildPrompt({
275
+ name: "prd-question",
276
+ type: "user",
277
+ variables,
278
+ });
279
+ if (!promptResult.success) {
280
+ throw new Error(`Failed to build PRD question prompt: ${promptResult.error}`);
281
+ }
282
+ prompt = promptResult.prompt;
283
+ }
284
+ const { PRD_QUESTION_SYSTEM_PROMPT } = await Promise.resolve().then(() => __importStar(require("../../prompts")));
285
+ let response;
286
+ if (enableFilesystemTools) {
287
+ const model = this.modelProvider.getModel({
288
+ ...this.modelProvider.getAIConfig(),
289
+ ...config,
290
+ });
291
+ const allTools = { ...filesystem_tools_1.filesystemTools };
292
+ const result = await (0, ai_1.streamText)({
293
+ model,
294
+ tools: allTools,
295
+ system: PRD_QUESTION_SYSTEM_PROMPT +
296
+ `\n\nYou have access to filesystem tools to check existing code/structure if needed.`,
297
+ messages: [{ role: "user", content: userMessage || prompt }],
298
+ maxRetries: 0,
299
+ onChunk: streamingOptions?.onChunk
300
+ ? ({ chunk }) => {
301
+ if (chunk.type === "text-delta") {
302
+ streamingOptions.onChunk(chunk.text);
303
+ }
304
+ else if (chunk.type === "reasoning-delta") {
305
+ streamingOptions.onReasoning?.(chunk.text);
306
+ }
307
+ }
308
+ : undefined,
309
+ onFinish: streamingOptions?.onFinish
310
+ ? ({ text, finishReason, usage }) => {
311
+ streamingOptions.onFinish({
312
+ text,
313
+ finishReason,
314
+ usage,
315
+ isAborted: false,
316
+ });
317
+ }
318
+ : undefined,
319
+ });
320
+ response = await result.text;
321
+ }
322
+ else {
323
+ response = await this.streamText("", config, PRD_QUESTION_SYSTEM_PROMPT, userMessage || prompt, streamingOptions, { maxAttempts: 1 });
324
+ }
325
+ const parseResult = this.jsonParser.parseJSONFromResponse(response);
326
+ if (!parseResult.success) {
327
+ throw new Error(parseResult.error || "Failed to parse PRD questions");
328
+ }
329
+ return parseResult.data?.questions || [];
330
+ }, retryConfig, "PRD questioning");
331
+ }
332
+ async answerPRDQuestions(prdContent, questions, config, contextInfo, streamingOptions, retryConfig) {
333
+ return this.retryHandler.executeWithRetry(async () => {
334
+ const questionsText = questions
335
+ .map((q, i) => `${i + 1}. ${q}`)
336
+ .join("\n");
337
+ const contextText = contextInfo
338
+ ? `\n\nProject Context:\n${contextInfo.stackInfo
339
+ ? `Technology Stack: ${contextInfo.stackInfo}\n`
340
+ : ""}${contextInfo.projectDescription
341
+ ? `Project Description: ${contextInfo.projectDescription}\n`
342
+ : ""}`
343
+ : "";
344
+ const prompt = `You are a product expert helping to clarify a PRD.
345
+
346
+ PRD Content:
347
+ ${prdContent}${contextText}
348
+
349
+ Please answer the following questions based on the PRD and context:
350
+
351
+ ${questionsText}
352
+
353
+ Provide thoughtful, specific answers that will help refine the PRD.
354
+ Format your response as JSON with the following structure:
355
+ {
356
+ "answers": {
357
+ "1": "answer to question 1",
358
+ "2": "answer to question 2",
359
+ ...
360
+ }
361
+ }`;
362
+ const systemPrompt = `You are a product expert analyzing PRDs and answering clarifying questions.
363
+ Your answers should be:
364
+ - Specific and actionable
365
+ - Based on the PRD content and project context
366
+ - Helpful for refining the PRD
367
+ - Formatted as JSON`;
368
+ const response = await this.streamText("", config, systemPrompt, prompt, streamingOptions, { maxAttempts: 1 });
369
+ const parseResult = this.jsonParser.parseJSONFromResponse(response);
370
+ if (!parseResult.success) {
371
+ throw new Error(parseResult.error || "Failed to parse PRD answers response");
372
+ }
373
+ const answers = {};
374
+ const numberedAnswers = parseResult.data?.answers || {};
375
+ questions.forEach((question, index) => {
376
+ const key = String(index + 1);
377
+ if (numberedAnswers[key]) {
378
+ answers[question] = numberedAnswers[key];
379
+ }
380
+ });
381
+ return answers;
382
+ }, retryConfig, "PRD question answering");
383
+ }
384
+ async generatePRD(description, config, promptOverride, userMessage, streamingOptions, retryConfig) {
385
+ return this.retryHandler.executeWithRetry(async () => {
386
+ const systemPrompt = prompts_1.PRD_GENERATION_SYSTEM_PROMPT;
387
+ const userContent = userMessage || `Product Description:\n${description}`;
388
+ return this.streamText("", config, systemPrompt, userContent, streamingOptions, { maxAttempts: 1 });
389
+ }, retryConfig, "PRD generation");
390
+ }
391
+ async combinePRDs(prds, originalDescription, config, promptOverride, userMessage, streamingOptions, retryConfig) {
392
+ return this.retryHandler.executeWithRetry(async () => {
393
+ const systemPrompt = prompts_1.PRD_COMBINATION_SYSTEM_PROMPT;
394
+ let userContent = userMessage;
395
+ if (!userContent) {
396
+ userContent = `Original Description:\n${originalDescription}\n\n`;
397
+ prds.forEach((prd, index) => {
398
+ userContent += `--- PRD ${index + 1} ---\n${prd}\n\n`;
399
+ });
400
+ }
401
+ return this.streamText("", config, systemPrompt, userContent, streamingOptions, { maxAttempts: 1 });
402
+ }, retryConfig, "PRD combination");
403
+ }
404
+ }
405
+ exports.PRDOperations = PRDOperations;
@@ -0,0 +1,12 @@
1
+ import { AIConfig, Task, StreamingOptions, RetryConfig } from "../../types";
2
+ import { BaseOperations } from "./base-operations";
3
+ export declare class TaskOperations extends BaseOperations {
4
+ breakdownTask(task: Task, config?: Partial<AIConfig>, promptOverride?: string, userMessage?: string, streamingOptions?: StreamingOptions, retryConfig?: Partial<RetryConfig>, fullContent?: string, stackInfo?: string, existingSubtasks?: Task[], enableFilesystemTools?: boolean): Promise<Array<{
5
+ title: string;
6
+ content: string;
7
+ estimatedEffort?: string;
8
+ }>>;
9
+ enhanceTask(title: string, description?: string, config?: Partial<AIConfig>, promptOverride?: string, userMessage?: string, taskId?: string, streamingOptions?: StreamingOptions, retryConfig?: Partial<RetryConfig>): Promise<string>;
10
+ planTask(taskContext: string, taskDetails: string, config?: Partial<AIConfig>, promptOverride?: string, userMessage?: string, streamingOptions?: StreamingOptions, retryConfig?: Partial<RetryConfig>): Promise<any>;
11
+ }
12
+ //# sourceMappingURL=task-operations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-operations.d.ts","sourceRoot":"","sources":["../../../src/lib/ai-service/task-operations.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,QAAQ,EACR,IAAI,EACJ,gBAAgB,EAChB,WAAW,EAEZ,MAAM,aAAa,CAAC;AAUrB,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,qBAAa,cAAe,SAAQ,cAAc;IAC1C,aAAa,CACjB,IAAI,EAAE,IAAI,EACV,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,cAAc,CAAC,EAAE,MAAM,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,EAClC,WAAW,CAAC,EAAE,MAAM,EACpB,SAAS,CAAC,EAAE,MAAM,EAClB,gBAAgB,CAAC,EAAE,IAAI,EAAE,EACzB,qBAAqB,CAAC,EAAE,OAAO,GAC9B,OAAO,CACR,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CACpE;IAgIK,WAAW,CACf,KAAK,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,MAAM,EACpB,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,cAAc,CAAC,EAAE,MAAM,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,MAAM,CAAC,EAAE,MAAM,EACf,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC;IAyEZ,QAAQ,CACZ,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,cAAc,CAAC,EAAE,MAAM,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GACjC,OAAO,CAAC,GAAG,CAAC;CA6EhB"}
@@ -0,0 +1,225 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TaskOperations = void 0;
4
+ const ai_1 = require("ai");
5
+ const prompt_builder_1 = require("../prompt-builder");
6
+ const stack_formatter_1 = require("../../utils/stack-formatter");
7
+ const prompts_1 = require("../../prompts");
8
+ const ai_service_factory_1 = require("../../utils/ai-service-factory");
9
+ const filesystem_tools_1 = require("./filesystem-tools");
10
+ const base_operations_1 = require("./base-operations");
11
+ class TaskOperations extends base_operations_1.BaseOperations {
12
+ async breakdownTask(task, config, promptOverride, userMessage, streamingOptions, retryConfig, fullContent, stackInfo, existingSubtasks, enableFilesystemTools) {
13
+ return this.retryHandler.executeWithRetry(async () => {
14
+ let prompt;
15
+ if (promptOverride) {
16
+ prompt = promptOverride;
17
+ }
18
+ else {
19
+ const variables = {
20
+ TASK_TITLE: task.title,
21
+ TASK_DESCRIPTION: task.description || "No description",
22
+ };
23
+ if (fullContent) {
24
+ variables.TASK_CONTENT = fullContent;
25
+ }
26
+ if (existingSubtasks && existingSubtasks.length > 0) {
27
+ const existingSubtasksText = existingSubtasks
28
+ .map((subtask, index) => `${index + 1}. ${subtask.title}: ${subtask.description || "No description"}`)
29
+ .join("\n");
30
+ variables.EXISTING_SUBTASKS = existingSubtasksText;
31
+ }
32
+ if (stackInfo) {
33
+ variables.STACK_INFO = stackInfo;
34
+ }
35
+ const promptResult = prompt_builder_1.PromptBuilder.buildPrompt({
36
+ name: "task-breakdown",
37
+ type: "user",
38
+ variables,
39
+ });
40
+ if (!promptResult.success) {
41
+ throw new Error(`Failed to build task breakdown prompt: ${promptResult.error}`);
42
+ }
43
+ prompt = promptResult.prompt;
44
+ }
45
+ let response;
46
+ if (enableFilesystemTools) {
47
+ const model = this.modelProvider.getModel({
48
+ ...this.modelProvider.getAIConfig(),
49
+ ...config,
50
+ });
51
+ const allTools = {
52
+ ...filesystem_tools_1.filesystemTools,
53
+ };
54
+ const result = await (0, ai_1.streamText)({
55
+ model,
56
+ tools: allTools,
57
+ system: prompts_1.TASK_BREAKDOWN_SYSTEM_PROMPT +
58
+ `
59
+
60
+ You have access to filesystem tools that allow you to:
61
+ - readFile: Read the contents of any file in the project
62
+ - listDirectory: List contents of directories
63
+
64
+ Use these tools to understand the project structure, existing code, and dependencies when breaking down tasks into subtasks.`,
65
+ messages: [{ role: "user", content: userMessage || prompt }],
66
+ maxRetries: 0,
67
+ onChunk: streamingOptions?.onChunk
68
+ ? ({ chunk }) => {
69
+ if (chunk.type === "text-delta") {
70
+ streamingOptions.onChunk(chunk.text);
71
+ }
72
+ else if (chunk.type === "reasoning-delta") {
73
+ streamingOptions.onReasoning?.(chunk.text);
74
+ }
75
+ }
76
+ : undefined,
77
+ onFinish: streamingOptions?.onFinish
78
+ ? ({ text, finishReason, usage }) => {
79
+ streamingOptions.onFinish({
80
+ text,
81
+ finishReason,
82
+ usage,
83
+ isAborted: false,
84
+ });
85
+ }
86
+ : undefined,
87
+ });
88
+ response = await result.text;
89
+ }
90
+ else {
91
+ response = await this.streamText("", config, prompts_1.TASK_BREAKDOWN_SYSTEM_PROMPT, userMessage || prompt, streamingOptions, { maxAttempts: 1 });
92
+ }
93
+ const parseResult = this.jsonParser.parseJSONFromResponse(response);
94
+ if (!parseResult.success) {
95
+ throw new Error(parseResult.error || "Failed to parse task breakdown response");
96
+ }
97
+ const parsed = parseResult.data;
98
+ return (parsed?.subtasks || []).map((subtask) => ({
99
+ title: subtask.title,
100
+ content: subtask.description || "",
101
+ estimatedEffort: subtask.effort,
102
+ }));
103
+ }, retryConfig, "Task breakdown");
104
+ }
105
+ async enhanceTask(title, description, config, promptOverride, userMessage, taskId, streamingOptions, retryConfig) {
106
+ return this.retryHandler.executeWithRetry(async () => {
107
+ let contextInfo = "";
108
+ let prdContent = "";
109
+ if (taskId) {
110
+ const contextBuilder = (0, ai_service_factory_1.getContextBuilder)();
111
+ try {
112
+ const context = await contextBuilder.buildContext(taskId);
113
+ if (context.documentation || context.stack || context.prdContent) {
114
+ contextInfo = "\n\nAvailable Context:\n";
115
+ if (context.stack) {
116
+ contextInfo += (0, stack_formatter_1.formatStackForContext)(context.stack) + "\n";
117
+ }
118
+ if (context.documentation) {
119
+ contextInfo += `Documentation Available: ${context.documentation.recap}\n`;
120
+ if (context.documentation.files.length > 0) {
121
+ contextInfo += `Documentation Files: ${context.documentation.files
122
+ .map((f) => f.path)
123
+ .join(", ")}\n`;
124
+ }
125
+ }
126
+ if (context.prdContent) {
127
+ prdContent = context.prdContent;
128
+ }
129
+ }
130
+ }
131
+ catch (error) {
132
+ throw error;
133
+ }
134
+ }
135
+ let prompt;
136
+ if (promptOverride) {
137
+ prompt = promptOverride;
138
+ }
139
+ else {
140
+ const promptResult = prompt_builder_1.PromptBuilder.buildPrompt({
141
+ name: "task-enhancement",
142
+ type: "user",
143
+ variables: {
144
+ TASK_TITLE: title,
145
+ TASK_DESCRIPTION: description || "None",
146
+ CONTEXT_INFO: contextInfo,
147
+ PRD_CONTENT: prdContent || "No PRD content available",
148
+ },
149
+ });
150
+ if (!promptResult.success) {
151
+ throw new Error(`Failed to build task enhancement prompt: ${promptResult.error}`);
152
+ }
153
+ prompt = promptResult.prompt;
154
+ }
155
+ return this.streamText("", config, prompts_1.TASK_ENHANCEMENT_SYSTEM_PROMPT, userMessage || prompt, streamingOptions, { maxAttempts: 1 });
156
+ }, retryConfig, "Task enhancement");
157
+ }
158
+ async planTask(taskContext, taskDetails, config, promptOverride, userMessage, streamingOptions, retryConfig) {
159
+ return this.retryHandler.executeWithRetry(async () => {
160
+ let prompt;
161
+ if (promptOverride) {
162
+ prompt = promptOverride;
163
+ }
164
+ else {
165
+ const promptResult = prompt_builder_1.PromptBuilder.buildPrompt({
166
+ name: "task-planning",
167
+ type: "user",
168
+ variables: {
169
+ TASK_CONTEXT: taskContext,
170
+ TASK_DETAILS: taskDetails,
171
+ },
172
+ });
173
+ if (!promptResult.success) {
174
+ throw new Error(`Failed to build task planning prompt: ${promptResult.error}`);
175
+ }
176
+ prompt = promptResult.prompt;
177
+ }
178
+ const model = this.modelProvider.getModel({
179
+ ...this.modelProvider.getAIConfig(),
180
+ ...config,
181
+ });
182
+ const mcpTools = await this.context7Client.getMCPTools();
183
+ const allTools = {
184
+ ...mcpTools,
185
+ ...filesystem_tools_1.filesystemTools,
186
+ };
187
+ const result = (0, ai_1.streamText)({
188
+ model,
189
+ tools: allTools,
190
+ system: prompts_1.TASK_PLANNING_SYSTEM_PROMPT +
191
+ `
192
+
193
+ You have access to filesystem tools that allow you to:
194
+ - readFile: Read the contents of any file in the project
195
+ - listDirectory: List contents of directories
196
+
197
+ Use these tools to understand the project structure, existing code, and dependencies when creating implementation plans.`,
198
+ messages: [{ role: "user", content: userMessage || prompt }],
199
+ maxRetries: 0,
200
+ onChunk: streamingOptions?.onChunk
201
+ ? ({ chunk }) => {
202
+ if (chunk.type === "text-delta") {
203
+ streamingOptions.onChunk(chunk.text);
204
+ }
205
+ else if (chunk.type === "reasoning-delta") {
206
+ streamingOptions.onReasoning?.(chunk.text);
207
+ }
208
+ }
209
+ : undefined,
210
+ onFinish: streamingOptions?.onFinish
211
+ ? ({ text, finishReason, usage }) => {
212
+ streamingOptions.onFinish({
213
+ text,
214
+ finishReason,
215
+ usage,
216
+ isAborted: false,
217
+ });
218
+ }
219
+ : undefined,
220
+ });
221
+ return (await result).text;
222
+ }, retryConfig, "Task planning");
223
+ }
224
+ }
225
+ exports.TaskOperations = TaskOperations;
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/lib/benchmark/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAA0B,MAAM,SAAS,CAAC;AAOzE,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,UAAU,CAAkD;;IAMpE,QAAQ,CAAC,EAAE,EAAE,sBAAsB;IAInC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,sBAAsB,GAAG,SAAS;IAInD,IAAI,IAAI,sBAAsB,EAAE;IAIhC,OAAO,CAAC,gBAAgB;CAkGzB;AAED,eAAO,MAAM,iBAAiB,mBAA0B,CAAC"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/lib/benchmark/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAA0B,MAAM,SAAS,CAAC;AAOzE,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,UAAU,CAAkD;;IAMpE,QAAQ,CAAC,EAAE,EAAE,sBAAsB;IAInC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,sBAAsB,GAAG,SAAS;IAInD,IAAI,IAAI,sBAAsB,EAAE;IAIhC,OAAO,CAAC,gBAAgB;CA2RzB;AAED,eAAO,MAAM,iBAAiB,mBAA0B,CAAC"}