task-o-matic 0.0.10 → 0.0.12

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 (117) 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 +21 -16
  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 +301 -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 +398 -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 +32 -7
  57. package/dist/lib/prompt-builder.d.ts +11 -0
  58. package/dist/lib/prompt-builder.d.ts.map +1 -1
  59. package/dist/lib/prompt-builder.js +60 -0
  60. package/dist/lib/prompt-registry.d.ts.map +1 -1
  61. package/dist/lib/prompt-registry.js +158 -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 +29 -51
  70. package/dist/lib/task-loop-execution.d.ts.map +1 -1
  71. package/dist/lib/task-loop-execution.js +234 -42
  72. package/dist/prompts/documentation-recap.d.ts +3 -0
  73. package/dist/prompts/documentation-recap.d.ts.map +1 -0
  74. package/dist/prompts/documentation-recap.js +13 -0
  75. package/dist/prompts/index.d.ts +6 -0
  76. package/dist/prompts/index.d.ts.map +1 -1
  77. package/dist/prompts/index.js +6 -0
  78. package/dist/prompts/prd-combination.d.ts +2 -0
  79. package/dist/prompts/prd-combination.d.ts.map +1 -0
  80. package/dist/prompts/prd-combination.js +35 -0
  81. package/dist/prompts/prd-generation.d.ts +2 -0
  82. package/dist/prompts/prd-generation.d.ts.map +1 -0
  83. package/dist/prompts/prd-generation.js +49 -0
  84. package/dist/prompts/prd-question-answer.d.ts +3 -0
  85. package/dist/prompts/prd-question-answer.d.ts.map +1 -0
  86. package/dist/prompts/prd-question-answer.js +27 -0
  87. package/dist/prompts/task-execution.d.ts +3 -0
  88. package/dist/prompts/task-execution.d.ts.map +1 -0
  89. package/dist/prompts/task-execution.js +21 -0
  90. package/dist/prompts/workflow-prompts.d.ts +9 -0
  91. package/dist/prompts/workflow-prompts.d.ts.map +1 -0
  92. package/dist/prompts/workflow-prompts.js +93 -0
  93. package/dist/services/prd.d.ts +43 -0
  94. package/dist/services/prd.d.ts.map +1 -1
  95. package/dist/services/prd.js +121 -0
  96. package/dist/services/workflow-ai-assistant.d.ts.map +1 -1
  97. package/dist/services/workflow-ai-assistant.js +73 -134
  98. package/dist/services/workflow.d.ts +10 -0
  99. package/dist/services/workflow.d.ts.map +1 -1
  100. package/dist/services/workflow.js +118 -40
  101. package/dist/test/integration/callbacks.test.d.ts +2 -0
  102. package/dist/test/integration/callbacks.test.d.ts.map +1 -0
  103. package/dist/test/integration/callbacks.test.js +64 -0
  104. package/dist/types/callbacks.d.ts +9 -6
  105. package/dist/types/callbacks.d.ts.map +1 -1
  106. package/dist/types/index.d.ts +17 -2
  107. package/dist/types/index.d.ts.map +1 -1
  108. package/dist/types/workflow-options.d.ts +7 -0
  109. package/dist/types/workflow-options.d.ts.map +1 -1
  110. package/dist/utils/ai-service-factory.d.ts +15 -1
  111. package/dist/utils/ai-service-factory.d.ts.map +1 -1
  112. package/dist/utils/ai-service-factory.js +29 -1
  113. package/dist/utils/streaming-options.d.ts +1 -1
  114. package/dist/utils/streaming-options.d.ts.map +1 -1
  115. package/dist/utils/streaming-options.js +31 -18
  116. package/docs/agents/cli.md +191 -0
  117. package/package.json +3 -2
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.workflowAIAssistant = exports.WorkflowAIAssistant = void 0;
4
4
  const ai_service_factory_1 = require("../utils/ai-service-factory");
5
5
  const ai_config_builder_1 = require("../utils/ai-config-builder");
6
+ const prompt_builder_1 = require("../lib/prompt-builder");
6
7
  /**
7
8
  * WorkflowAIAssistant - AI-powered decision making for workflow steps
8
9
  * Helps users make configuration choices using natural language
@@ -13,38 +14,22 @@ class WorkflowAIAssistant {
13
14
  */
14
15
  async assistInitConfig(input) {
15
16
  const aiConfig = (0, ai_config_builder_1.buildAIConfig)(input.aiOptions);
16
- const prompt = `You are helping a developer configure their project initialization and tech stack.
17
-
18
- Available Options:
19
- - AI Providers: openrouter, anthropic, openai, custom
20
- - Frontend Frameworks: next, tanstack-router, react-router, vite-react, remix
21
- - Backend Frameworks: hono, express, elysia, fastify
22
- - Databases: sqlite, postgres, mysql, mongodb, turso, neon
23
- - Authentication: better-auth (recommended), clerk, auth0, custom
24
-
25
- User's Description:
26
- "${input.userDescription}"
27
-
28
- Based on the user's description, recommend a complete configuration. Consider:
29
- 1. Project complexity and scale
30
- 2. Developer experience level (infer from description)
31
- 3. Modern best practices for 2025
32
- 4. Compatibility between chosen technologies
33
-
34
- Respond in JSON format:
35
- {
36
- "projectName": "suggested-project-name",
37
- "aiProvider": "recommended-provider",
38
- "aiModel": "recommended-model",
39
- "frontend": "recommended-frontend",
40
- "backend": "recommended-backend",
41
- "database": "recommended-database",
42
- "auth": true/false,
43
- "reasoning": "Brief explanation of your choices"
44
- }`;
45
- const result = await (0, ai_service_factory_1.getAIOperations)().streamText(prompt, aiConfig, undefined, // system prompt
46
- undefined, // user message (prompt is used)
47
- input.streamingOptions);
17
+ const promptResult = prompt_builder_1.PromptBuilder.buildPrompt({
18
+ name: "project-init-suggestion",
19
+ type: "user",
20
+ variables: {
21
+ USER_DESCRIPTION: input.userDescription,
22
+ },
23
+ });
24
+ if (!promptResult.success) {
25
+ throw new Error(`Failed to build project init prompt: ${promptResult.error}`);
26
+ }
27
+ const systemPromptResult = prompt_builder_1.PromptBuilder.buildPrompt({
28
+ name: "project-init-suggestion",
29
+ type: "system",
30
+ variables: {},
31
+ });
32
+ const result = await (0, ai_service_factory_1.getAIOperations)().streamText(promptResult.prompt, aiConfig, systemPromptResult.prompt, undefined, input.streamingOptions);
48
33
  // Parse AI response
49
34
  try {
50
35
  const jsonMatch = result.match(/\{[\s\S]*\}/);
@@ -72,71 +57,30 @@ Respond in JSON format:
72
57
  */
73
58
  async assistPRDCreation(input) {
74
59
  const aiConfig = (0, ai_config_builder_1.buildAIConfig)(input.aiOptions);
75
- const prompt = `You are a product manager helping to create a Product Requirements Document (PRD).
76
-
77
- User's Product Description:
78
- "${input.userDescription}"
79
-
80
- Create a comprehensive PRD with the following sections:
81
-
82
- # Product Requirements Document
83
-
84
- ## Overview
85
- [Brief overview of the product]
86
-
87
- ## Objectives
88
- [Key objectives and goals]
89
-
90
- ## Target Audience
91
- [Who will use this product]
92
-
93
- ## Features
94
-
95
- ### Core Features
96
- [Essential features for MVP]
97
-
98
- ### Future Features
99
- [Nice-to-have features for later]
100
-
101
- ## Technical Requirements
102
- [Technical constraints and requirements]
103
-
104
- ## Success Metrics
105
- [How to measure success]
106
-
107
- ## Timeline
108
- [Rough timeline and milestones]
109
-
110
- Generate a detailed, actionable PRD based on the user's description.`;
111
- const result = await (0, ai_service_factory_1.getAIOperations)().streamText(prompt, aiConfig, undefined, // system prompt
112
- undefined, // user message (prompt is used)
113
- input.streamingOptions);
114
- return result;
60
+ return (0, ai_service_factory_1.getAIOperations)().generatePRD(input.userDescription, aiConfig, undefined, undefined, input.streamingOptions);
115
61
  }
116
62
  /**
117
63
  * Suggest improvements to an existing PRD
118
64
  */
119
65
  async assistPRDRefinement(input) {
120
66
  const aiConfig = (0, ai_config_builder_1.buildAIConfig)(input.aiOptions);
121
- const prompt = `You are a product manager reviewing and improving a PRD.
122
-
123
- Current PRD:
124
- ${input.currentPRD}
125
-
126
- User's Feedback:
127
- "${input.userFeedback}"
128
-
129
- Improve the PRD based on the feedback. Consider:
130
- 1. Clarity and specificity
131
- 2. Completeness of requirements
132
- 3. Feasibility and scope
133
- 4. Technical details
134
- 5. Success criteria
135
-
136
- Return the improved PRD in the same format, incorporating the user's feedback.`;
137
- const result = await (0, ai_service_factory_1.getAIOperations)().streamText(prompt, aiConfig, undefined, // system prompt
138
- undefined, // user message (prompt is used)
139
- input.streamingOptions);
67
+ const promptResult = prompt_builder_1.PromptBuilder.buildPrompt({
68
+ name: "prd-improvement",
69
+ type: "user",
70
+ variables: {
71
+ CURRENT_PRD: input.currentPRD,
72
+ USER_FEEDBACK: input.userFeedback,
73
+ },
74
+ });
75
+ if (!promptResult.success) {
76
+ throw new Error(`Failed to build PRD improvement prompt: ${promptResult.error}`);
77
+ }
78
+ const systemPromptResult = prompt_builder_1.PromptBuilder.buildPrompt({
79
+ name: "prd-improvement",
80
+ type: "system",
81
+ variables: {},
82
+ });
83
+ const result = await (0, ai_service_factory_1.getAIOperations)().streamText(promptResult.prompt, aiConfig, systemPromptResult.prompt, undefined, input.streamingOptions);
140
84
  return result;
141
85
  }
142
86
  /**
@@ -147,31 +91,23 @@ Return the improved PRD in the same format, incorporating the user's feedback.`;
147
91
  const tasksDescription = input.tasks
148
92
  .map((t, i) => `${i + 1}. [${t.id}] ${t.title}${t.description ? `: ${t.description}` : ""}`)
149
93
  .join("\n");
150
- const prompt = `You are a project manager helping to prioritize tasks.
151
-
152
- Tasks:
153
- ${tasksDescription}
154
-
155
- User's Guidance:
156
- "${input.userGuidance}"
157
-
158
- Prioritize these tasks (1 = highest priority) based on:
159
- 1. Dependencies (what needs to be done first)
160
- 2. User's guidance
161
- 3. MVP vs. nice-to-have
162
- 4. Risk and complexity
163
-
164
- Respond in JSON format:
165
- {
166
- "prioritizedTasks": [
167
- {"id": "task-id", "priority": 1, "reasoning": "why this priority"},
168
- ...
169
- ],
170
- "recommendations": "Overall recommendations for task execution"
171
- }`;
172
- const result = await (0, ai_service_factory_1.getAIOperations)().streamText(prompt, aiConfig, undefined, // system prompt
173
- undefined, // user message (prompt is used)
174
- input.streamingOptions);
94
+ const promptResult = prompt_builder_1.PromptBuilder.buildPrompt({
95
+ name: "task-prioritization",
96
+ type: "user",
97
+ variables: {
98
+ TASKS_DESCRIPTION: tasksDescription,
99
+ USER_GUIDANCE: input.userGuidance,
100
+ },
101
+ });
102
+ if (!promptResult.success) {
103
+ throw new Error(`Failed to build task prioritization prompt: ${promptResult.error}`);
104
+ }
105
+ const systemPromptResult = prompt_builder_1.PromptBuilder.buildPrompt({
106
+ name: "task-prioritization",
107
+ type: "system",
108
+ variables: {},
109
+ });
110
+ const result = await (0, ai_service_factory_1.getAIOperations)().streamText(promptResult.prompt, aiConfig, systemPromptResult.prompt, undefined, input.streamingOptions);
175
111
  // Parse AI response
176
112
  try {
177
113
  const jsonMatch = result.match(/\{[\s\S]*\}/);
@@ -197,24 +133,27 @@ Respond in JSON format:
197
133
  */
198
134
  async assistTaskSplitting(input) {
199
135
  const aiConfig = (0, ai_config_builder_1.buildAIConfig)(input.aiOptions);
200
- const prompt = `You are a technical lead helping to break down a complex task.
201
-
202
- Task: ${input.taskTitle}
203
- ${input.taskContent ? `Description: ${input.taskContent}` : ""}
204
-
205
- User's Guidance:
206
- "${input.userGuidance}"
207
-
208
- Generate specific instructions for how to split this task into subtasks. Consider:
209
- 1. Logical breakdown points
210
- 2. Size constraints (e.g., 2-4 hour chunks)
211
- 3. Dependencies between subtasks
212
- 4. Testing and validation steps
213
-
214
- Provide clear, actionable instructions for the AI that will perform the split.`;
215
- const result = await (0, ai_service_factory_1.getAIOperations)().streamText(prompt, aiConfig, undefined, // system prompt
216
- undefined, // user message (prompt is used)
217
- input.streamingOptions);
136
+ const taskContentText = input.taskContent
137
+ ? `Description: ${input.taskContent}`
138
+ : "";
139
+ const promptResult = prompt_builder_1.PromptBuilder.buildPrompt({
140
+ name: "task-splitting-assistance",
141
+ type: "user",
142
+ variables: {
143
+ TASK_TITLE: input.taskTitle,
144
+ TASK_CONTENT: taskContentText,
145
+ USER_GUIDANCE: input.userGuidance,
146
+ },
147
+ });
148
+ if (!promptResult.success) {
149
+ throw new Error(`Failed to build task splitting prompt: ${promptResult.error}`);
150
+ }
151
+ const systemPromptResult = prompt_builder_1.PromptBuilder.buildPrompt({
152
+ name: "task-splitting-assistance",
153
+ type: "system",
154
+ variables: {},
155
+ });
156
+ const result = await (0, ai_service_factory_1.getAIOperations)().streamText(promptResult.prompt, aiConfig, systemPromptResult.prompt, undefined, input.streamingOptions);
218
157
  return result;
219
158
  }
220
159
  }
@@ -24,6 +24,7 @@ export declare class WorkflowService {
24
24
  auth?: boolean;
25
25
  };
26
26
  bootstrap?: boolean;
27
+ includeDocs?: boolean;
27
28
  streamingOptions?: StreamingOptions;
28
29
  callbacks?: ProgressCallback;
29
30
  }): Promise<InitializeResult>;
@@ -40,6 +41,15 @@ export declare class WorkflowService {
40
41
  aiOptions?: AIOptions;
41
42
  streamingOptions?: StreamingOptions;
42
43
  callbacks?: ProgressCallback;
44
+ multiGeneration?: boolean;
45
+ multiGenerationModels?: Array<{
46
+ provider: string;
47
+ model: string;
48
+ }>;
49
+ combineAI?: {
50
+ provider: string;
51
+ model: string;
52
+ };
43
53
  }): Promise<DefinePRDResult>;
44
54
  /**
45
55
  * Step 3: Refine PRD
@@ -1 +1 @@
1
- {"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../src/services/workflow.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../src/services/workflow.ts"],"names":[],"mappings":"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"}
@@ -35,6 +35,7 @@ class WorkflowService {
35
35
  // Switch to project directory
36
36
  process.chdir(projectDir);
37
37
  config_1.configManager.setWorkingDirectory(projectDir);
38
+ await config_1.configManager.load();
38
39
  // Initialize task-o-matic directory structure
39
40
  const taskOMaticDir = (0, path_1.join)(projectDir, ".task-o-matic");
40
41
  if (!(0, fs_1.existsSync)(taskOMaticDir)) {
@@ -53,7 +54,7 @@ class WorkflowService {
53
54
  (aiProvider === "openrouter"
54
55
  ? "anthropic/claude-3.5-sonnet"
55
56
  : aiProvider === "anthropic"
56
- ? "claude-3-5-sonnet-20240620"
57
+ ? "claude-sonnet-4.5"
57
58
  : "gpt-4o");
58
59
  const apiKey = input.aiOptions?.aiKey || process.env.AI_API_KEY || "";
59
60
  // Save AI config to .env
@@ -146,6 +147,7 @@ class WorkflowService {
146
147
  runtime: "node",
147
148
  noInstall: false,
148
149
  noGit: false,
150
+ includeDocs: input.includeDocs,
149
151
  }, projectDir);
150
152
  if (result.success) {
151
153
  bootstrapped = true;
@@ -229,49 +231,125 @@ class WorkflowService {
229
231
  prdContent = input.prdContent;
230
232
  }
231
233
  else if (input.method === "ai" && input.prdDescription) {
232
- input.callbacks?.onProgress?.({
233
- type: "progress",
234
- message: "Generating PRD with AI...",
235
- });
236
- // Capture metrics for AI operations
237
- const streamingOptions = {
238
- ...input.streamingOptions,
239
- onFinish: async (result) => {
240
- if (result.usage) {
241
- tokenUsage = {
242
- prompt: result.usage.inputTokens || result.usage.promptTokens || 0,
243
- completion: result.usage.outputTokens || result.usage.completionTokens || 0,
244
- total: result.usage.totalTokens || 0,
245
- };
246
- // Calculate cost (simplified - would need proper pricing lookup)
247
- if (tokenUsage.total > 0) {
248
- cost = tokenUsage.total * 0.000001; // Placeholder cost calculation
249
- }
234
+ // Check if multi-generation is requested
235
+ if (input.multiGeneration &&
236
+ input.multiGenerationModels &&
237
+ input.multiGenerationModels.length > 1) {
238
+ // Multi-generation mode
239
+ const results = [];
240
+ input.callbacks?.onProgress?.({
241
+ type: "progress",
242
+ message: `Generating ${input.multiGenerationModels.length} PRDs concurrently...`,
243
+ });
244
+ // Generate PRDs concurrently
245
+ const promises = input.multiGenerationModels.map(async (modelConfig, index) => {
246
+ const modelId = `${modelConfig.provider}:${modelConfig.model}`;
247
+ const result = await prd_1.prdService.generatePRD({
248
+ description: input.prdDescription,
249
+ outputDir: prdDir,
250
+ filename: `prd-${modelConfig.provider}-${modelConfig.model.replace(/\//g, "-")}.md`,
251
+ aiOptions: {
252
+ aiProvider: modelConfig.provider,
253
+ aiModel: modelConfig.model,
254
+ },
255
+ callbacks: {
256
+ onProgress: (event) => {
257
+ // Only modify events that have a message property
258
+ if (event.type !== "stream-chunk" &&
259
+ event.type !== "reasoning-chunk") {
260
+ input.callbacks?.onProgress?.({
261
+ ...event,
262
+ message: `[${modelId}] ${event.message}`,
263
+ });
264
+ }
265
+ else {
266
+ input.callbacks?.onProgress?.(event);
267
+ }
268
+ },
269
+ },
270
+ });
271
+ results.push({
272
+ path: result.path,
273
+ content: result.content,
274
+ stats: result.stats,
275
+ modelId,
276
+ });
277
+ return result;
278
+ });
279
+ await Promise.all(promises);
280
+ // Aggregate metrics
281
+ tokenUsage = {
282
+ prompt: results.reduce((sum, r) => sum + (r.stats.tokenUsage?.prompt || 0), 0),
283
+ completion: results.reduce((sum, r) => sum + (r.stats.tokenUsage?.completion || 0), 0),
284
+ total: results.reduce((sum, r) => sum + (r.stats.tokenUsage?.total || 0), 0),
285
+ };
286
+ timeToFirstToken = Math.min(...results
287
+ .map((r) => r.stats.timeToFirstToken || Infinity)
288
+ .filter((t) => t !== Infinity));
289
+ cost = results.reduce((sum, r) => sum + (r.stats.cost || 0), 0);
290
+ // Combine if requested
291
+ if (input.combineAI) {
292
+ input.callbacks?.onProgress?.({
293
+ type: "progress",
294
+ message: "Combining PRDs into master PRD...",
295
+ });
296
+ const prdContents = results.map((r) => r.content);
297
+ const masterResult = await prd_1.prdService.combinePRDs({
298
+ prds: prdContents,
299
+ originalDescription: input.prdDescription,
300
+ outputDir: prdDir,
301
+ filename: "prd-master.md",
302
+ aiOptions: {
303
+ aiProvider: input.combineAI.provider,
304
+ aiModel: input.combineAI.model,
305
+ },
306
+ callbacks: input.callbacks,
307
+ });
308
+ prdContent = masterResult.content;
309
+ prdFilename = "prd-master.md";
310
+ // Add combination metrics
311
+ if (masterResult.stats.tokenUsage) {
312
+ tokenUsage.prompt += masterResult.stats.tokenUsage.prompt;
313
+ tokenUsage.completion += masterResult.stats.tokenUsage.completion;
314
+ tokenUsage.total += masterResult.stats.tokenUsage.total;
250
315
  }
251
- // Call original onFinish if provided
252
- input.streamingOptions?.onFinish?.(result);
253
- },
254
- onChunk: (chunk) => {
255
- if (chunk && !timeToFirstToken) {
256
- timeToFirstToken = Date.now() - startTime;
316
+ if (masterResult.stats.cost) {
317
+ cost = (cost || 0) + masterResult.stats.cost;
257
318
  }
258
- // Call original onChunk if provided
259
- input.streamingOptions?.onChunk?.(chunk);
260
- },
261
- };
262
- prdContent = await workflow_ai_assistant_1.workflowAIAssistant.assistPRDCreation({
263
- userDescription: input.prdDescription,
264
- aiOptions: input.aiOptions,
265
- streamingOptions,
266
- });
319
+ }
320
+ else {
321
+ // Use the first generated PRD as the main one
322
+ prdContent = results[0].content;
323
+ prdFilename = `prd-${results[0].modelId
324
+ .replace(/:/g, "-")
325
+ .replace(/\//g, "-")}.md`;
326
+ }
327
+ }
328
+ else {
329
+ // Single generation mode
330
+ const result = await prd_1.prdService.generatePRD({
331
+ description: input.prdDescription,
332
+ outputDir: prdDir,
333
+ filename: prdFilename,
334
+ aiOptions: input.aiOptions,
335
+ streamingOptions: input.streamingOptions,
336
+ callbacks: input.callbacks,
337
+ });
338
+ prdContent = result.content;
339
+ tokenUsage = result.stats.tokenUsage;
340
+ timeToFirstToken = result.stats.timeToFirstToken;
341
+ cost = result.stats.cost;
342
+ }
267
343
  }
268
- // Save PRD
344
+ // Save PRD if not already saved by AI service
269
345
  const prdPath = (0, path_1.join)(prdDir, prdFilename);
270
- (0, fs_1.writeFileSync)(prdPath, prdContent);
271
- input.callbacks?.onProgress?.({
272
- type: "completed",
273
- message: `PRD saved to ${prdPath}`,
274
- });
346
+ if (input.method !== "ai") {
347
+ (0, fs_1.writeFileSync)(prdPath, prdContent);
348
+ input.callbacks?.onProgress?.({
349
+ type: "completed",
350
+ message: `PRD saved to ${prdPath}`,
351
+ });
352
+ }
275
353
  const stats = {
276
354
  duration: Date.now() - startTime,
277
355
  ...(tokenUsage && { tokenUsage }),
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=callbacks.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"callbacks.test.d.ts","sourceRoot":"","sources":["../../../src/test/integration/callbacks.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,64 @@
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
+ const file_system_1 = require("../../lib/storage/file-system");
37
+ const assert = __importStar(require("assert"));
38
+ describe("Callback Integration", () => {
39
+ it("should use custom storage callbacks", async () => {
40
+ const memoryStore = new Map();
41
+ const callbacks = {
42
+ read: async (key) => memoryStore.get(key) || null,
43
+ write: async (key, value) => {
44
+ memoryStore.set(key, value);
45
+ },
46
+ delete: async (key) => {
47
+ memoryStore.delete(key);
48
+ },
49
+ list: async (prefix) => Array.from(memoryStore.keys()).filter((k) => k.startsWith(prefix || "")),
50
+ exists: async (key) => memoryStore.has(key),
51
+ };
52
+ const storage = new file_system_1.FileSystemStorage(callbacks);
53
+ // Create task
54
+ const task = await storage.createTask({ title: "Test Task" });
55
+ // Verify it was written to memory store
56
+ assert.strictEqual(memoryStore.has("tasks.json"), true);
57
+ const data = JSON.parse(memoryStore.get("tasks.json"));
58
+ assert.strictEqual(data.tasks.length, 1);
59
+ assert.strictEqual(data.tasks[0].title, "Test Task");
60
+ // Verify retrieval
61
+ const retrieved = await storage.getTask(task.id);
62
+ assert.strictEqual(retrieved?.id, task.id);
63
+ });
64
+ });
@@ -1,22 +1,25 @@
1
1
  export type ProgressEvent = {
2
- type: 'started';
2
+ type: "started";
3
3
  message: string;
4
4
  } | {
5
- type: 'progress';
5
+ type: "progress";
6
6
  message: string;
7
7
  current?: number;
8
8
  total?: number;
9
9
  } | {
10
- type: 'stream-chunk';
10
+ type: "stream-chunk";
11
11
  text: string;
12
12
  } | {
13
- type: 'completed';
13
+ type: "reasoning-chunk";
14
+ text: string;
15
+ } | {
16
+ type: "completed";
14
17
  message: string;
15
18
  } | {
16
- type: 'info';
19
+ type: "info";
17
20
  message: string;
18
21
  } | {
19
- type: 'warning';
22
+ type: "warning";
20
23
  message: string;
21
24
  };
22
25
  export interface ProgressCallback {
@@ -1 +1 @@
1
- {"version":3,"file":"callbacks.d.ts","sourceRoot":"","sources":["../../src/types/callbacks.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACvE;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,MAAM,WAAW,gBAAgB;IAC/B,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC5C,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;IACnC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC"}
1
+ {"version":3,"file":"callbacks.d.ts","sourceRoot":"","sources":["../../src/types/callbacks.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACvE;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,MAAM,WAAW,gBAAgB;IAC/B,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC5C,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;IACnC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC"}
@@ -119,6 +119,7 @@ export interface BTSConfig {
119
119
  webDeploy: string;
120
120
  serverDeploy: string;
121
121
  install: boolean;
122
+ includeDocs?: boolean;
122
123
  addons: string[];
123
124
  examples: string[];
124
125
  createdAt?: string;
@@ -214,6 +215,7 @@ export interface StreamingCallbacks {
214
215
  }) => void | Promise<void>;
215
216
  onError?: (error: unknown) => void | Promise<void>;
216
217
  onAbort?: (reason?: string) => void | Promise<void>;
218
+ onReasoning?: (text: string) => void | Promise<void>;
217
219
  }
218
220
  export interface StreamingOptions extends StreamingCallbacks {
219
221
  /** Enable streaming responses. When false, callbacks are ignored and final result is returned. */
@@ -235,16 +237,24 @@ export interface RetryConfig {
235
237
  }
236
238
  export type TaskListResponse = Task[];
237
239
  export type ExecutorTool = "opencode" | "claude" | "gemini" | "codex";
240
+ export interface ExecutorConfig {
241
+ model?: string;
242
+ sessionId?: string;
243
+ continueLastSession?: boolean;
244
+ }
238
245
  export interface ExecuteTaskOptions {
239
246
  taskId: string;
240
247
  tool?: ExecutorTool;
241
248
  message?: string;
242
249
  dry?: boolean;
243
250
  validate?: string[];
251
+ model?: string;
252
+ continueSession?: boolean;
244
253
  }
245
254
  export interface ExternalExecutor {
246
255
  name: string;
247
- execute(message: string, dry?: boolean): Promise<void>;
256
+ execute(message: string, dry?: boolean, config?: ExecutorConfig): Promise<void>;
257
+ supportsSessionResumption(): boolean;
248
258
  }
249
259
  export interface ExecutionResult {
250
260
  success: boolean;
@@ -260,6 +270,11 @@ export interface ExecuteLoopConfig {
260
270
  verificationCommands?: string[];
261
271
  autoCommit?: boolean;
262
272
  tryModels?: ModelAttemptConfig[];
273
+ plan?: boolean;
274
+ planModel?: string;
275
+ reviewPlan?: boolean;
276
+ review?: boolean;
277
+ reviewModel?: string;
263
278
  }
264
279
  export interface ExecuteLoopOptions {
265
280
  filters?: {
@@ -297,7 +312,7 @@ export interface ExecuteLoopResult {
297
312
  taskId: string;
298
313
  taskTitle: string;
299
314
  attempts: TaskExecutionAttempt[];
300
- finalStatus: 'completed' | 'failed';
315
+ finalStatus: "completed" | "failed";
301
316
  }>;
302
317
  duration: number;
303
318
  }