task-o-matic 0.0.10 → 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.
- package/dist/cli/display/progress.d.ts +1 -1
- package/dist/cli/display/progress.d.ts.map +1 -1
- package/dist/cli/display/progress.js +16 -13
- package/dist/commands/benchmark.js +70 -2
- package/dist/commands/init.js +48 -27
- package/dist/commands/prd.d.ts.map +1 -1
- package/dist/commands/prd.js +201 -0
- package/dist/commands/tasks/execute-loop.d.ts.map +1 -1
- package/dist/commands/tasks/execute-loop.js +10 -0
- package/dist/commands/tasks/execute.d.ts.map +1 -1
- package/dist/commands/tasks/execute.js +4 -0
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +56 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/lib/ai-service/ai-operations.d.ts +13 -10
- package/dist/lib/ai-service/ai-operations.d.ts.map +1 -1
- package/dist/lib/ai-service/ai-operations.js +35 -995
- package/dist/lib/ai-service/base-operations.d.ts +13 -0
- package/dist/lib/ai-service/base-operations.d.ts.map +1 -0
- package/dist/lib/ai-service/base-operations.js +79 -0
- package/dist/lib/ai-service/documentation-operations.d.ts +18 -0
- package/dist/lib/ai-service/documentation-operations.d.ts.map +1 -0
- package/dist/lib/ai-service/documentation-operations.js +291 -0
- package/dist/lib/ai-service/prd-operations.d.ts +14 -0
- package/dist/lib/ai-service/prd-operations.d.ts.map +1 -0
- package/dist/lib/ai-service/prd-operations.js +405 -0
- package/dist/lib/ai-service/task-operations.d.ts +12 -0
- package/dist/lib/ai-service/task-operations.d.ts.map +1 -0
- package/dist/lib/ai-service/task-operations.js +225 -0
- package/dist/lib/benchmark/registry.d.ts.map +1 -1
- package/dist/lib/benchmark/registry.js +127 -0
- package/dist/lib/better-t-stack-cli.d.ts +4 -1
- package/dist/lib/better-t-stack-cli.d.ts.map +1 -1
- package/dist/lib/better-t-stack-cli.js +126 -5
- package/dist/lib/config.d.ts +13 -6
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +90 -48
- package/dist/lib/context-builder.d.ts +13 -1
- package/dist/lib/context-builder.d.ts.map +1 -1
- package/dist/lib/context-builder.js +68 -36
- package/dist/lib/executors/claude-code-executor.d.ts +5 -2
- package/dist/lib/executors/claude-code-executor.d.ts.map +1 -1
- package/dist/lib/executors/claude-code-executor.js +30 -3
- package/dist/lib/executors/codex-executor.d.ts +5 -2
- package/dist/lib/executors/codex-executor.d.ts.map +1 -1
- package/dist/lib/executors/codex-executor.js +30 -3
- package/dist/lib/executors/executor-factory.d.ts +2 -2
- package/dist/lib/executors/executor-factory.d.ts.map +1 -1
- package/dist/lib/executors/executor-factory.js +5 -5
- package/dist/lib/executors/gemini-executor.d.ts +5 -2
- package/dist/lib/executors/gemini-executor.d.ts.map +1 -1
- package/dist/lib/executors/gemini-executor.js +30 -3
- package/dist/lib/executors/opencode-executor.d.ts +5 -2
- package/dist/lib/executors/opencode-executor.d.ts.map +1 -1
- package/dist/lib/executors/opencode-executor.js +30 -7
- package/dist/lib/prompt-builder.d.ts.map +1 -1
- package/dist/lib/prompt-builder.js +1 -0
- package/dist/lib/storage/file-system.d.ts +3 -7
- package/dist/lib/storage/file-system.d.ts.map +1 -1
- package/dist/lib/storage/file-system.js +50 -230
- package/dist/lib/storage/storage-callbacks.d.ts +17 -0
- package/dist/lib/storage/storage-callbacks.d.ts.map +1 -0
- package/dist/lib/storage/storage-callbacks.js +94 -0
- package/dist/lib/task-execution.d.ts.map +1 -1
- package/dist/lib/task-execution.js +16 -9
- package/dist/lib/task-loop-execution.d.ts.map +1 -1
- package/dist/lib/task-loop-execution.js +207 -8
- package/dist/prompts/index.d.ts +2 -0
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +2 -0
- package/dist/prompts/prd-combination.d.ts +2 -0
- package/dist/prompts/prd-combination.d.ts.map +1 -0
- package/dist/prompts/prd-combination.js +35 -0
- package/dist/prompts/prd-generation.d.ts +2 -0
- package/dist/prompts/prd-generation.d.ts.map +1 -0
- package/dist/prompts/prd-generation.js +49 -0
- package/dist/services/prd.d.ts +43 -0
- package/dist/services/prd.d.ts.map +1 -1
- package/dist/services/prd.js +121 -0
- package/dist/services/workflow-ai-assistant.d.ts.map +1 -1
- package/dist/services/workflow-ai-assistant.js +1 -40
- package/dist/services/workflow.d.ts +10 -0
- package/dist/services/workflow.d.ts.map +1 -1
- package/dist/services/workflow.js +118 -40
- package/dist/test/integration/callbacks.test.d.ts +2 -0
- package/dist/test/integration/callbacks.test.d.ts.map +1 -0
- package/dist/test/integration/callbacks.test.js +64 -0
- package/dist/types/callbacks.d.ts +9 -6
- package/dist/types/callbacks.d.ts.map +1 -1
- package/dist/types/index.d.ts +17 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/workflow-options.d.ts +7 -0
- package/dist/types/workflow-options.d.ts.map +1 -1
- package/dist/utils/ai-service-factory.d.ts +15 -1
- package/dist/utils/ai-service-factory.d.ts.map +1 -1
- package/dist/utils/ai-service-factory.js +29 -1
- package/dist/utils/streaming-options.d.ts +1 -1
- package/dist/utils/streaming-options.d.ts.map +1 -1
- package/dist/utils/streaming-options.js +31 -18
- package/docs/agents/cli.md +191 -0
- package/package.json +3 -2
|
@@ -13,6 +13,8 @@ const chalk_1 = __importDefault(require("chalk"));
|
|
|
13
13
|
const child_process_1 = require("child_process");
|
|
14
14
|
const util_1 = require("util");
|
|
15
15
|
const ai_service_factory_2 = require("../utils/ai-service-factory");
|
|
16
|
+
const fs_1 = require("fs");
|
|
17
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
16
18
|
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
17
19
|
/**
|
|
18
20
|
* Extract commit message and file list from AI conversation/output
|
|
@@ -152,10 +154,104 @@ async function runVerificationCommands(commands, dry) {
|
|
|
152
154
|
/**
|
|
153
155
|
* Execute a single task with retry logic and error correction
|
|
154
156
|
*/
|
|
155
|
-
async function executeTaskWithRetry(task, tool,
|
|
157
|
+
async function executeTaskWithRetry(task, tool, config, dry) {
|
|
158
|
+
const { maxRetries = 3, verificationCommands = [], tryModels, plan, planModel, reviewPlan, review, reviewModel, autoCommit, } = config;
|
|
156
159
|
const attempts = [];
|
|
157
160
|
let currentAttempt = 1;
|
|
158
161
|
let lastError;
|
|
162
|
+
let planContent;
|
|
163
|
+
// ----------------------------------------------------------------------
|
|
164
|
+
// PLANNING PHASE
|
|
165
|
+
// ----------------------------------------------------------------------
|
|
166
|
+
if (plan) {
|
|
167
|
+
console.log(chalk_1.default.blue.bold(`\n🧠 Starting Planning Phase for Task: ${task.title}`));
|
|
168
|
+
const planFileName = `task-${task.id}-plan.md`;
|
|
169
|
+
const planExecutor = planModel
|
|
170
|
+
? planModel.split(":")[0]
|
|
171
|
+
: tool;
|
|
172
|
+
const planModelName = planModel ? planModel.split(":")[1] : undefined;
|
|
173
|
+
let planningPrompt = `You are a senior software architect. Analyze the following task and create a detailed implementation plan.
|
|
174
|
+
|
|
175
|
+
Task: ${task.title}
|
|
176
|
+
Description: ${task.description || "No description provided."}
|
|
177
|
+
|
|
178
|
+
Requirements:
|
|
179
|
+
1. Analyze the task requirements.
|
|
180
|
+
2. Create a detailed step-by-step implementation plan.
|
|
181
|
+
3. Identify necessary file changes.
|
|
182
|
+
4. Write this plan to a file named "${planFileName}" in the current directory.
|
|
183
|
+
5. Do NOT implement the code yet, just create the plan file.
|
|
184
|
+
|
|
185
|
+
Please create the "${planFileName}" file now.`;
|
|
186
|
+
console.log(chalk_1.default.cyan(` Using executor for planning: ${planExecutor}${planModelName ? ` (${planModelName})` : ""}`));
|
|
187
|
+
// Create executor for planning
|
|
188
|
+
const planningConfig = {
|
|
189
|
+
model: planModelName,
|
|
190
|
+
continueLastSession: false,
|
|
191
|
+
};
|
|
192
|
+
const executor = executor_factory_1.ExecutorFactory.create(planExecutor, planningConfig);
|
|
193
|
+
try {
|
|
194
|
+
let planningComplete = false;
|
|
195
|
+
while (!planningComplete) {
|
|
196
|
+
await executor.execute(planningPrompt, dry, planningConfig);
|
|
197
|
+
if (!dry) {
|
|
198
|
+
// Verify plan file exists and read it
|
|
199
|
+
if ((0, fs_1.existsSync)(planFileName)) {
|
|
200
|
+
planContent = (0, fs_1.readFileSync)(planFileName, "utf-8");
|
|
201
|
+
console.log(chalk_1.default.green(`✅ Plan created successfully: ${planFileName}`));
|
|
202
|
+
// Human Review Loop
|
|
203
|
+
if (reviewPlan) {
|
|
204
|
+
console.log(chalk_1.default.yellow(`\n👀 Pausing for Human Review of the Plan: ${planFileName}`));
|
|
205
|
+
console.log(chalk_1.default.cyan("You can edit the file now."));
|
|
206
|
+
const { feedback } = await inquirer_1.default.prompt([
|
|
207
|
+
{
|
|
208
|
+
type: "input",
|
|
209
|
+
name: "feedback",
|
|
210
|
+
message: "Enter feedback to refine the plan (or press Enter to approve and continue):",
|
|
211
|
+
},
|
|
212
|
+
]);
|
|
213
|
+
if (feedback && feedback.trim() !== "") {
|
|
214
|
+
console.log(chalk_1.default.blue("🔄 Refining plan based on feedback..."));
|
|
215
|
+
planningPrompt = `The user provided the following feedback on the plan you just created:
|
|
216
|
+
|
|
217
|
+
"${feedback}"
|
|
218
|
+
|
|
219
|
+
Please update the plan file "${planFileName}" to incorporate this feedback.`;
|
|
220
|
+
// Continue loop to regenerate plan
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
// Auto-commit plan if enabled (only after approval)
|
|
225
|
+
if (autoCommit) {
|
|
226
|
+
try {
|
|
227
|
+
console.log(chalk_1.default.blue(`📦 Staging plan file: ${planFileName}`));
|
|
228
|
+
await execAsync(`git add ${planFileName}`);
|
|
229
|
+
await execAsync(`git commit -m "docs: create implementation plan for task ${task.id}"`);
|
|
230
|
+
console.log(chalk_1.default.green("✅ Plan committed successfully"));
|
|
231
|
+
}
|
|
232
|
+
catch (e) {
|
|
233
|
+
console.warn(chalk_1.default.yellow(`⚠️ Failed to commit plan: ${e instanceof Error ? e.message : "Unknown error"}`));
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
planningComplete = true;
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
console.warn(chalk_1.default.yellow(`⚠️ Plan file ${planFileName} was not created by the executor.`));
|
|
240
|
+
planningComplete = true; // Exit loop to avoid infinite retry if file not created
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
planningComplete = true; // Dry run
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
console.error(chalk_1.default.red(`❌ Planning phase failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
// ----------------------------------------------------------------------
|
|
253
|
+
// EXECUTION PHASE
|
|
254
|
+
// ----------------------------------------------------------------------
|
|
159
255
|
while (currentAttempt <= maxRetries) {
|
|
160
256
|
// Determine which executor and model to use for this attempt
|
|
161
257
|
let currentExecutor = tool;
|
|
@@ -211,10 +307,13 @@ async function executeTaskWithRetry(task, tool, verificationCommands, maxRetries
|
|
|
211
307
|
messageParts.push(`- Build or test failures\n\n`);
|
|
212
308
|
messageParts.push(`Please fix the error above and complete the task successfully.\n\n`);
|
|
213
309
|
}
|
|
214
|
-
// Add task plan if available
|
|
215
|
-
const
|
|
216
|
-
if (
|
|
217
|
-
messageParts.push(`#
|
|
310
|
+
// Add task plan if available (from planning phase or service)
|
|
311
|
+
const storedPlanData = await tasks_1.taskService.getTaskPlan(task.id);
|
|
312
|
+
if (planContent) {
|
|
313
|
+
messageParts.push(`# Implementation Plan\n\n${planContent}\n\nPlease follow this plan to implement the task.\n`);
|
|
314
|
+
}
|
|
315
|
+
else if (storedPlanData) {
|
|
316
|
+
messageParts.push(`# Task Plan\n\n${storedPlanData.plan}\n`);
|
|
218
317
|
}
|
|
219
318
|
else {
|
|
220
319
|
messageParts.push(`# Task: ${task.title}\n\n${task.description || "No description"}\n`);
|
|
@@ -251,7 +350,16 @@ async function executeTaskWithRetry(task, tool, verificationCommands, maxRetries
|
|
|
251
350
|
tool: currentExecutor,
|
|
252
351
|
});
|
|
253
352
|
// Create executor and run
|
|
254
|
-
|
|
353
|
+
// Build executor config
|
|
354
|
+
const executorConfig = {
|
|
355
|
+
model: currentModel,
|
|
356
|
+
continueLastSession: currentAttempt > 1, // Resume session on retries
|
|
357
|
+
};
|
|
358
|
+
// Log session resumption
|
|
359
|
+
if (currentAttempt > 1) {
|
|
360
|
+
console.log(chalk_1.default.cyan("🔄 Resuming previous session to provide error feedback to AI"));
|
|
361
|
+
}
|
|
362
|
+
const executor = executor_factory_1.ExecutorFactory.create(currentExecutor, executorConfig);
|
|
255
363
|
// Add model info to execution message if specified
|
|
256
364
|
let finalExecutionMessage = executionMessage;
|
|
257
365
|
if (currentModel) {
|
|
@@ -259,7 +367,7 @@ async function executeTaskWithRetry(task, tool, verificationCommands, maxRetries
|
|
|
259
367
|
`**Model Configuration**: Using ${currentModel}\n\n` +
|
|
260
368
|
executionMessage;
|
|
261
369
|
}
|
|
262
|
-
await executor.execute(finalExecutionMessage, dry);
|
|
370
|
+
await executor.execute(finalExecutionMessage, dry, executorConfig);
|
|
263
371
|
// Run verification commands
|
|
264
372
|
const verificationResults = await runVerificationCommands(verificationCommands, dry);
|
|
265
373
|
// Check if all verifications passed
|
|
@@ -281,6 +389,97 @@ async function executeTaskWithRetry(task, tool, verificationCommands, maxRetries
|
|
|
281
389
|
currentAttempt++;
|
|
282
390
|
continue;
|
|
283
391
|
}
|
|
392
|
+
// ----------------------------------------------------------------------
|
|
393
|
+
// AI REVIEW PHASE
|
|
394
|
+
// ----------------------------------------------------------------------
|
|
395
|
+
if (review && !dry) {
|
|
396
|
+
console.log(chalk_1.default.blue.bold("\n🕵️ Starting AI Review Phase..."));
|
|
397
|
+
try {
|
|
398
|
+
// Get git diff
|
|
399
|
+
const { stdout: diff } = await execAsync("git diff HEAD");
|
|
400
|
+
if (!diff.trim()) {
|
|
401
|
+
console.log(chalk_1.default.yellow("⚠️ No changes detected to review."));
|
|
402
|
+
}
|
|
403
|
+
else {
|
|
404
|
+
const reviewExecutor = reviewModel
|
|
405
|
+
? reviewModel.split(":")[0]
|
|
406
|
+
: tool;
|
|
407
|
+
const reviewModelName = reviewModel
|
|
408
|
+
? reviewModel.split(":")[1]
|
|
409
|
+
: undefined;
|
|
410
|
+
console.log(chalk_1.default.cyan(` Using executor for review: ${reviewExecutor}${reviewModelName ? ` (${reviewModelName})` : ""}`));
|
|
411
|
+
const reviewPrompt = `You are a strict code reviewer. Review the following changes for the task.
|
|
412
|
+
|
|
413
|
+
Task: ${task.title}
|
|
414
|
+
Plan: ${planContent || "No plan provided."}
|
|
415
|
+
|
|
416
|
+
Git Diff:
|
|
417
|
+
${diff.substring(0, 10000)}
|
|
418
|
+
|
|
419
|
+
Analyze the changes for:
|
|
420
|
+
1. Correctness (does it solve the task?)
|
|
421
|
+
2. Code Quality (clean code, best practices)
|
|
422
|
+
3. Potential Bugs
|
|
423
|
+
|
|
424
|
+
Return a JSON object:
|
|
425
|
+
{
|
|
426
|
+
"approved": boolean,
|
|
427
|
+
"feedback": "Detailed feedback explaining why it was rejected or approved"
|
|
428
|
+
}
|
|
429
|
+
`;
|
|
430
|
+
const reviewConfig = {
|
|
431
|
+
model: reviewModelName,
|
|
432
|
+
continueLastSession: false,
|
|
433
|
+
};
|
|
434
|
+
// We use a separate executor instance for review to avoid polluting the main context
|
|
435
|
+
// But wait, ExecutorFactory.create returns a new instance usually.
|
|
436
|
+
// However, we need to capture the output which is usually streamed to stdout/file.
|
|
437
|
+
// The current Executor interface doesn't easily return the output string directly if it's designed for side-effects.
|
|
438
|
+
// But we can use getAIOperations().generateText directly for this since it's a simple Q&A.
|
|
439
|
+
const aiOps = (0, ai_service_factory_2.getAIOperations)();
|
|
440
|
+
// We need to construct a proper AI config for getAIOperations
|
|
441
|
+
// This is a bit hacky, ideally we'd use the executor abstraction, but we need the return value.
|
|
442
|
+
// Let's assume we can use the default AI provider for review for now, or try to respect the reviewModel.
|
|
443
|
+
// Actually, let's use the executor but we need to capture its output.
|
|
444
|
+
// The current executor implementation writes to files/stdout.
|
|
445
|
+
// Let's use aiOps directly for the review to get the JSON response.
|
|
446
|
+
const aiResponse = await aiOps.streamText(reviewPrompt);
|
|
447
|
+
const jsonMatch = aiResponse.match(/\{[\s\S]*\}/);
|
|
448
|
+
if (jsonMatch) {
|
|
449
|
+
const reviewResult = JSON.parse(jsonMatch[0]);
|
|
450
|
+
if (!reviewResult.approved) {
|
|
451
|
+
lastError = `AI Review Failed:\n${reviewResult.feedback}`;
|
|
452
|
+
attempts.push({
|
|
453
|
+
attemptNumber: currentAttempt,
|
|
454
|
+
success: false,
|
|
455
|
+
error: lastError,
|
|
456
|
+
executor: currentExecutor,
|
|
457
|
+
model: currentModel,
|
|
458
|
+
verificationResults,
|
|
459
|
+
timestamp: Date.now() - attemptStartTime,
|
|
460
|
+
});
|
|
461
|
+
console.log(chalk_1.default.red(`❌ AI Review Rejected Changes: ${reviewResult.feedback}`));
|
|
462
|
+
// Revert changes? Or just let the next attempt fix them?
|
|
463
|
+
// Usually better to let the next attempt see the bad code and fix it.
|
|
464
|
+
// But we might want to undo if it's really bad.
|
|
465
|
+
// For now, let's keep the changes so the AI can see what it did wrong.
|
|
466
|
+
currentAttempt++;
|
|
467
|
+
continue;
|
|
468
|
+
}
|
|
469
|
+
else {
|
|
470
|
+
console.log(chalk_1.default.green(`✅ AI Review Approved: ${reviewResult.feedback}`));
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
else {
|
|
474
|
+
console.warn(chalk_1.default.yellow("⚠️ Could not parse AI review response. Assuming approval."));
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
catch (error) {
|
|
479
|
+
console.error(chalk_1.default.red(`❌ AI Review failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
480
|
+
// If review crashes, do we fail the task? Maybe safe to warn and proceed.
|
|
481
|
+
}
|
|
482
|
+
}
|
|
284
483
|
// Success! Extract commit info
|
|
285
484
|
let commitInfo;
|
|
286
485
|
if (!dry) {
|
|
@@ -412,7 +611,7 @@ async function executeTaskLoop(options) {
|
|
|
412
611
|
const task = tasksToExecute[i];
|
|
413
612
|
console.log(chalk_1.default.blue.bold(`\n${"=".repeat(60)}\n📌 Task ${i + 1}/${tasksToExecute.length}: ${task.title} (${task.id})\n${"=".repeat(60)}\n`));
|
|
414
613
|
// Execute task with retry logic
|
|
415
|
-
const attempts = await executeTaskWithRetry(task, tool,
|
|
614
|
+
const attempts = await executeTaskWithRetry(task, tool, config, dry);
|
|
416
615
|
// Check if task succeeded
|
|
417
616
|
const lastAttempt = attempts[attempts.length - 1];
|
|
418
617
|
const succeeded = lastAttempt.success;
|
package/dist/prompts/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC"}
|
package/dist/prompts/index.js
CHANGED
|
@@ -21,3 +21,5 @@ __exportStar(require("./prd-rework"), exports);
|
|
|
21
21
|
__exportStar(require("./documentation-detection"), exports);
|
|
22
22
|
__exportStar(require("./task-planning"), exports);
|
|
23
23
|
__exportStar(require("./prd-question"), exports);
|
|
24
|
+
__exportStar(require("./prd-generation"), exports);
|
|
25
|
+
__exportStar(require("./prd-combination"), exports);
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const PRD_COMBINATION_SYSTEM_PROMPT = "You are a Senior Product Lead tasked with synthesizing multiple Product Requirements Documents (PRDs) into a single, master PRD.\n\nYou will be provided with:\n1. The original product description.\n2. Multiple PRDs generated by different AI models.\n\nYour goal is to create the \"Best of Breed\" Master PRD.\n\nProcess:\n1. Analyze all input PRDs.\n2. Identify the strongest points, most detailed features, and best technical architectural decisions from each.\n3. Resolve any conflicts by choosing the most robust and feasible option.\n4. Merge them into a single, cohesive document following the standard PRD structure.\n\nStructure the Master PRD as follows:\n\n# Master Product Requirements Document\n\n## 1. Overview\n## 2. Objectives\n## 3. Target Audience\n## 4. Features (MVP & Future)\n## 5. Technical Requirements\n## 6. Timeline & Milestones\n## 7. Open Questions / Risks\n\nGuidelines:\n- Do not simply concatenate the documents. Synthesize them.\n- If one PRD has a better database schema and another has better UI/UX flows, combine them.\n- Maintain a consistent tone and voice.\n- Ensure the final document is self-contained and complete.\n";
|
|
2
|
+
//# sourceMappingURL=prd-combination.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prd-combination.d.ts","sourceRoot":"","sources":["../../src/prompts/prd-combination.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,6BAA6B,yoCA+BzC,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PRD_COMBINATION_SYSTEM_PROMPT = void 0;
|
|
4
|
+
exports.PRD_COMBINATION_SYSTEM_PROMPT = `You are a Senior Product Lead tasked with synthesizing multiple Product Requirements Documents (PRDs) into a single, master PRD.
|
|
5
|
+
|
|
6
|
+
You will be provided with:
|
|
7
|
+
1. The original product description.
|
|
8
|
+
2. Multiple PRDs generated by different AI models.
|
|
9
|
+
|
|
10
|
+
Your goal is to create the "Best of Breed" Master PRD.
|
|
11
|
+
|
|
12
|
+
Process:
|
|
13
|
+
1. Analyze all input PRDs.
|
|
14
|
+
2. Identify the strongest points, most detailed features, and best technical architectural decisions from each.
|
|
15
|
+
3. Resolve any conflicts by choosing the most robust and feasible option.
|
|
16
|
+
4. Merge them into a single, cohesive document following the standard PRD structure.
|
|
17
|
+
|
|
18
|
+
Structure the Master PRD as follows:
|
|
19
|
+
|
|
20
|
+
# Master Product Requirements Document
|
|
21
|
+
|
|
22
|
+
## 1. Overview
|
|
23
|
+
## 2. Objectives
|
|
24
|
+
## 3. Target Audience
|
|
25
|
+
## 4. Features (MVP & Future)
|
|
26
|
+
## 5. Technical Requirements
|
|
27
|
+
## 6. Timeline & Milestones
|
|
28
|
+
## 7. Open Questions / Risks
|
|
29
|
+
|
|
30
|
+
Guidelines:
|
|
31
|
+
- Do not simply concatenate the documents. Synthesize them.
|
|
32
|
+
- If one PRD has a better database schema and another has better UI/UX flows, combine them.
|
|
33
|
+
- Maintain a consistent tone and voice.
|
|
34
|
+
- Ensure the final document is self-contained and complete.
|
|
35
|
+
`;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const PRD_GENERATION_SYSTEM_PROMPT = "You are an expert Product Manager and Technical Architect. Your goal is to create a comprehensive Product Requirements Document (PRD) based on the user's description.\n\nThe PRD should be detailed, actionable, and structured in Markdown.\n\nStructure the PRD with the following sections:\n\n# Product Requirements Document\n\n## 1. Overview\n- Executive summary of the product\n- Problem statement\n- Value proposition\n\n## 2. Objectives\n- Key goals (Business & Technical)\n- Success metrics (KPIs)\n\n## 3. Target Audience\n- User personas\n- User stories\n\n## 4. Features\n### 4.1 Core Features (MVP)\n- Detailed description of essential features\n- Acceptance criteria for each\n\n### 4.2 Future Features (Post-MVP)\n- Nice-to-have features for later iterations\n\n## 5. Technical Requirements\n- Tech stack recommendations (Frontend, Backend, Database, etc.)\n- System architecture overview\n- Security and Performance requirements\n\n## 6. Timeline & Milestones\n- Rough estimation of phases\n\n## 7. Open Questions / Risks\n- Any ambiguities or potential blockers\n\nGuidelines:\n- Be specific and avoid vague language.\n- Use professional technical terminology.\n- Focus on feasibility and clarity.\n- If the user provides specific technical constraints, adhere to them strictly.\n";
|
|
2
|
+
//# sourceMappingURL=prd-generation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prd-generation.d.ts","sourceRoot":"","sources":["../../src/prompts/prd-generation.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B,gxCA6CxC,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PRD_GENERATION_SYSTEM_PROMPT = void 0;
|
|
4
|
+
exports.PRD_GENERATION_SYSTEM_PROMPT = `You are an expert Product Manager and Technical Architect. Your goal is to create a comprehensive Product Requirements Document (PRD) based on the user's description.
|
|
5
|
+
|
|
6
|
+
The PRD should be detailed, actionable, and structured in Markdown.
|
|
7
|
+
|
|
8
|
+
Structure the PRD with the following sections:
|
|
9
|
+
|
|
10
|
+
# Product Requirements Document
|
|
11
|
+
|
|
12
|
+
## 1. Overview
|
|
13
|
+
- Executive summary of the product
|
|
14
|
+
- Problem statement
|
|
15
|
+
- Value proposition
|
|
16
|
+
|
|
17
|
+
## 2. Objectives
|
|
18
|
+
- Key goals (Business & Technical)
|
|
19
|
+
- Success metrics (KPIs)
|
|
20
|
+
|
|
21
|
+
## 3. Target Audience
|
|
22
|
+
- User personas
|
|
23
|
+
- User stories
|
|
24
|
+
|
|
25
|
+
## 4. Features
|
|
26
|
+
### 4.1 Core Features (MVP)
|
|
27
|
+
- Detailed description of essential features
|
|
28
|
+
- Acceptance criteria for each
|
|
29
|
+
|
|
30
|
+
### 4.2 Future Features (Post-MVP)
|
|
31
|
+
- Nice-to-have features for later iterations
|
|
32
|
+
|
|
33
|
+
## 5. Technical Requirements
|
|
34
|
+
- Tech stack recommendations (Frontend, Backend, Database, etc.)
|
|
35
|
+
- System architecture overview
|
|
36
|
+
- Security and Performance requirements
|
|
37
|
+
|
|
38
|
+
## 6. Timeline & Milestones
|
|
39
|
+
- Rough estimation of phases
|
|
40
|
+
|
|
41
|
+
## 7. Open Questions / Risks
|
|
42
|
+
- Any ambiguities or potential blockers
|
|
43
|
+
|
|
44
|
+
Guidelines:
|
|
45
|
+
- Be specific and avoid vague language.
|
|
46
|
+
- Use professional technical terminology.
|
|
47
|
+
- Focus on feasibility and clarity.
|
|
48
|
+
- If the user provides specific technical constraints, adhere to them strictly.
|
|
49
|
+
`;
|
package/dist/services/prd.d.ts
CHANGED
|
@@ -54,6 +54,49 @@ export declare class PRDService {
|
|
|
54
54
|
answers: Record<string, string>;
|
|
55
55
|
refinedPRDPath: string;
|
|
56
56
|
}>;
|
|
57
|
+
generatePRD(input: {
|
|
58
|
+
description: string;
|
|
59
|
+
outputDir?: string;
|
|
60
|
+
filename?: string;
|
|
61
|
+
aiOptions?: AIOptions;
|
|
62
|
+
streamingOptions?: StreamingOptions;
|
|
63
|
+
callbacks?: ProgressCallback;
|
|
64
|
+
}): Promise<{
|
|
65
|
+
path: string;
|
|
66
|
+
content: string;
|
|
67
|
+
stats: {
|
|
68
|
+
duration: number;
|
|
69
|
+
tokenUsage?: {
|
|
70
|
+
prompt: number;
|
|
71
|
+
completion: number;
|
|
72
|
+
total: number;
|
|
73
|
+
};
|
|
74
|
+
timeToFirstToken?: number;
|
|
75
|
+
cost?: number;
|
|
76
|
+
};
|
|
77
|
+
}>;
|
|
78
|
+
combinePRDs(input: {
|
|
79
|
+
prds: string[];
|
|
80
|
+
originalDescription: string;
|
|
81
|
+
outputDir?: string;
|
|
82
|
+
filename?: string;
|
|
83
|
+
aiOptions?: AIOptions;
|
|
84
|
+
streamingOptions?: StreamingOptions;
|
|
85
|
+
callbacks?: ProgressCallback;
|
|
86
|
+
}): Promise<{
|
|
87
|
+
path: string;
|
|
88
|
+
content: string;
|
|
89
|
+
stats: {
|
|
90
|
+
duration: number;
|
|
91
|
+
tokenUsage?: {
|
|
92
|
+
prompt: number;
|
|
93
|
+
completion: number;
|
|
94
|
+
total: number;
|
|
95
|
+
};
|
|
96
|
+
timeToFirstToken?: number;
|
|
97
|
+
cost?: number;
|
|
98
|
+
};
|
|
99
|
+
}>;
|
|
57
100
|
}
|
|
58
101
|
export declare const prdService: PRDService;
|
|
59
102
|
//# sourceMappingURL=prd.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prd.d.ts","sourceRoot":"","sources":["../../src/services/prd.ts"],"names":[],"mappings":"AASA,OAAO,EAAiB,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAY,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;GAGG;AACH,qBAAa,UAAU;IACf,QAAQ,CAAC,KAAK,EAAE;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,qBAAqB,CAAC,EAAE,OAAO,CAAC;QAChC,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;QACpC,SAAS,CAAC,EAAE,gBAAgB,CAAC;KAC9B,GAAG,OAAO,CAAC,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"prd.d.ts","sourceRoot":"","sources":["../../src/services/prd.ts"],"names":[],"mappings":"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"}
|
package/dist/services/prd.js
CHANGED
|
@@ -64,6 +64,8 @@ class PRDService {
|
|
|
64
64
|
// Set working directory from CLI layer (defaults to process.cwd() for backward compatibility)
|
|
65
65
|
const workingDir = input.workingDirectory || process.cwd();
|
|
66
66
|
config_1.configManager.setWorkingDirectory(workingDir);
|
|
67
|
+
// Reload config after changing working directory
|
|
68
|
+
await config_1.configManager.load();
|
|
67
69
|
input.callbacks?.onProgress?.({
|
|
68
70
|
type: "progress",
|
|
69
71
|
message: "Reading PRD file...",
|
|
@@ -223,6 +225,7 @@ class PRDService {
|
|
|
223
225
|
}
|
|
224
226
|
const workingDir = input.workingDirectory || process.cwd();
|
|
225
227
|
config_1.configManager.setWorkingDirectory(workingDir);
|
|
228
|
+
await config_1.configManager.load();
|
|
226
229
|
input.callbacks?.onProgress?.({
|
|
227
230
|
type: "progress",
|
|
228
231
|
message: "Reading PRD file...",
|
|
@@ -256,6 +259,7 @@ class PRDService {
|
|
|
256
259
|
// Set working directory from CLI layer (defaults to process.cwd() for backward compatibility)
|
|
257
260
|
const workingDir = input.workingDirectory || process.cwd();
|
|
258
261
|
config_1.configManager.setWorkingDirectory(workingDir);
|
|
262
|
+
await config_1.configManager.load();
|
|
259
263
|
input.callbacks?.onProgress?.({
|
|
260
264
|
type: "progress",
|
|
261
265
|
message: "Reading PRD file...",
|
|
@@ -380,6 +384,123 @@ class PRDService {
|
|
|
380
384
|
refinedPRDPath,
|
|
381
385
|
};
|
|
382
386
|
}
|
|
387
|
+
async generatePRD(input) {
|
|
388
|
+
const startTime = Date.now();
|
|
389
|
+
let tokenUsage;
|
|
390
|
+
let timeToFirstToken;
|
|
391
|
+
let cost;
|
|
392
|
+
input.callbacks?.onProgress?.({
|
|
393
|
+
type: "started",
|
|
394
|
+
message: "Generating PRD...",
|
|
395
|
+
});
|
|
396
|
+
// Capture metrics
|
|
397
|
+
const metricsStreamingOptions = {
|
|
398
|
+
...input.streamingOptions,
|
|
399
|
+
onFinish: async (result) => {
|
|
400
|
+
if (result.usage) {
|
|
401
|
+
tokenUsage = {
|
|
402
|
+
prompt: result.usage.inputTokens || result.usage.promptTokens || 0,
|
|
403
|
+
completion: result.usage.outputTokens || result.usage.completionTokens || 0,
|
|
404
|
+
total: result.usage.totalTokens || 0,
|
|
405
|
+
};
|
|
406
|
+
// Simple cost estimation placeholder
|
|
407
|
+
if (tokenUsage.total > 0) {
|
|
408
|
+
cost = tokenUsage.total * 0.000001;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
await input.streamingOptions?.onFinish?.(result);
|
|
412
|
+
},
|
|
413
|
+
onChunk: (chunk) => {
|
|
414
|
+
if (chunk && !timeToFirstToken) {
|
|
415
|
+
timeToFirstToken = Date.now() - startTime;
|
|
416
|
+
}
|
|
417
|
+
input.streamingOptions?.onChunk?.(chunk);
|
|
418
|
+
},
|
|
419
|
+
};
|
|
420
|
+
const aiConfig = (0, ai_config_builder_1.buildAIConfig)(input.aiOptions);
|
|
421
|
+
const content = await (0, ai_service_factory_1.getAIOperations)().generatePRD(input.description, aiConfig, undefined, undefined, metricsStreamingOptions);
|
|
422
|
+
// Save file
|
|
423
|
+
const taskOMaticDir = config_1.configManager.getTaskOMaticDir();
|
|
424
|
+
const prdDir = input.outputDir || (0, path_1.join)(taskOMaticDir, "prd");
|
|
425
|
+
if (!(0, fs_1.existsSync)(prdDir)) {
|
|
426
|
+
(0, fs_1.mkdirSync)(prdDir, { recursive: true });
|
|
427
|
+
}
|
|
428
|
+
const filename = input.filename || "prd.md";
|
|
429
|
+
const path = (0, path_1.join)(prdDir, filename);
|
|
430
|
+
(0, fs_1.writeFileSync)(path, content);
|
|
431
|
+
input.callbacks?.onProgress?.({
|
|
432
|
+
type: "completed",
|
|
433
|
+
message: `PRD generated and saved to ${path}`,
|
|
434
|
+
});
|
|
435
|
+
return {
|
|
436
|
+
path,
|
|
437
|
+
content,
|
|
438
|
+
stats: {
|
|
439
|
+
duration: Date.now() - startTime,
|
|
440
|
+
tokenUsage,
|
|
441
|
+
timeToFirstToken,
|
|
442
|
+
cost,
|
|
443
|
+
},
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
async combinePRDs(input) {
|
|
447
|
+
const startTime = Date.now();
|
|
448
|
+
let tokenUsage;
|
|
449
|
+
let timeToFirstToken;
|
|
450
|
+
let cost;
|
|
451
|
+
input.callbacks?.onProgress?.({
|
|
452
|
+
type: "started",
|
|
453
|
+
message: "Combining PRDs...",
|
|
454
|
+
});
|
|
455
|
+
// Capture metrics
|
|
456
|
+
const metricsStreamingOptions = {
|
|
457
|
+
...input.streamingOptions,
|
|
458
|
+
onFinish: async (result) => {
|
|
459
|
+
if (result.usage) {
|
|
460
|
+
tokenUsage = {
|
|
461
|
+
prompt: result.usage.inputTokens || result.usage.promptTokens || 0,
|
|
462
|
+
completion: result.usage.outputTokens || result.usage.completionTokens || 0,
|
|
463
|
+
total: result.usage.totalTokens || 0,
|
|
464
|
+
};
|
|
465
|
+
if (tokenUsage.total > 0) {
|
|
466
|
+
cost = tokenUsage.total * 0.000001;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
await input.streamingOptions?.onFinish?.(result);
|
|
470
|
+
},
|
|
471
|
+
onChunk: (chunk) => {
|
|
472
|
+
if (chunk && !timeToFirstToken) {
|
|
473
|
+
timeToFirstToken = Date.now() - startTime;
|
|
474
|
+
}
|
|
475
|
+
input.streamingOptions?.onChunk?.(chunk);
|
|
476
|
+
},
|
|
477
|
+
};
|
|
478
|
+
const aiConfig = (0, ai_config_builder_1.buildAIConfig)(input.aiOptions);
|
|
479
|
+
const content = await (0, ai_service_factory_1.getAIOperations)().combinePRDs(input.prds, input.originalDescription, aiConfig, undefined, undefined, metricsStreamingOptions);
|
|
480
|
+
// Save file
|
|
481
|
+
const taskOMaticDir = config_1.configManager.getTaskOMaticDir();
|
|
482
|
+
const prdDir = input.outputDir || (0, path_1.join)(taskOMaticDir, "prd");
|
|
483
|
+
if (!(0, fs_1.existsSync)(prdDir)) {
|
|
484
|
+
(0, fs_1.mkdirSync)(prdDir, { recursive: true });
|
|
485
|
+
}
|
|
486
|
+
const filename = input.filename || "prd-master.md";
|
|
487
|
+
const path = (0, path_1.join)(prdDir, filename);
|
|
488
|
+
(0, fs_1.writeFileSync)(path, content);
|
|
489
|
+
input.callbacks?.onProgress?.({
|
|
490
|
+
type: "completed",
|
|
491
|
+
message: `Master PRD saved to ${path}`,
|
|
492
|
+
});
|
|
493
|
+
return {
|
|
494
|
+
path,
|
|
495
|
+
content,
|
|
496
|
+
stats: {
|
|
497
|
+
duration: Date.now() - startTime,
|
|
498
|
+
tokenUsage,
|
|
499
|
+
timeToFirstToken,
|
|
500
|
+
cost,
|
|
501
|
+
},
|
|
502
|
+
};
|
|
503
|
+
}
|
|
383
504
|
}
|
|
384
505
|
exports.PRDService = PRDService;
|
|
385
506
|
// Export singleton instance
|
|
@@ -1 +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;
|
|
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;IAYnB;;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"}
|
|
@@ -72,46 +72,7 @@ Respond in JSON format:
|
|
|
72
72
|
*/
|
|
73
73
|
async assistPRDCreation(input) {
|
|
74
74
|
const aiConfig = (0, ai_config_builder_1.buildAIConfig)(input.aiOptions);
|
|
75
|
-
|
|
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;
|
|
75
|
+
return (0, ai_service_factory_1.getAIOperations)().generatePRD(input.userDescription, aiConfig, undefined, undefined, input.streamingOptions);
|
|
115
76
|
}
|
|
116
77
|
/**
|
|
117
78
|
* Suggest improvements to an existing PRD
|