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.
- 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/index.d.ts +5 -0
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +7 -1
- 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/hooks.test.js +19 -10
- 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/test/task-loop-git.test.js +33 -0
- package/dist/test/validation.test.d.ts +2 -0
- package/dist/test/validation.test.d.ts.map +1 -0
- package/dist/test/validation.test.js +22 -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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../../src/cli/display/progress.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../../src/cli/display/progress.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAuC1D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,GAAG,IAAI,CAGzD"}
|
|
@@ -12,29 +12,32 @@ const chalk_1 = __importDefault(require("chalk"));
|
|
|
12
12
|
*/
|
|
13
13
|
function displayProgress(event) {
|
|
14
14
|
switch (event.type) {
|
|
15
|
-
case
|
|
16
|
-
console.log(chalk_1.default.blue(
|
|
15
|
+
case "started":
|
|
16
|
+
console.log(chalk_1.default.blue("🤖 " + event.message));
|
|
17
17
|
break;
|
|
18
|
-
case
|
|
18
|
+
case "progress":
|
|
19
19
|
if (event.current && event.total) {
|
|
20
20
|
const percent = Math.round((event.current / event.total) * 100);
|
|
21
21
|
console.log(chalk_1.default.cyan(` [${event.current}/${event.total}] ${percent}% - ${event.message}`));
|
|
22
22
|
}
|
|
23
23
|
else {
|
|
24
|
-
console.log(chalk_1.default.cyan(
|
|
24
|
+
console.log(chalk_1.default.cyan(" → " + event.message));
|
|
25
25
|
}
|
|
26
26
|
break;
|
|
27
|
-
case
|
|
27
|
+
case "stream-chunk":
|
|
28
28
|
process.stdout.write(event.text);
|
|
29
29
|
break;
|
|
30
|
-
case
|
|
31
|
-
|
|
30
|
+
case "reasoning-chunk":
|
|
31
|
+
process.stdout.write(chalk_1.default.magenta(event.text));
|
|
32
32
|
break;
|
|
33
|
-
case
|
|
34
|
-
console.log(chalk_1.default.
|
|
33
|
+
case "completed":
|
|
34
|
+
console.log(chalk_1.default.green("✓ " + event.message));
|
|
35
35
|
break;
|
|
36
|
-
case
|
|
37
|
-
console.log(chalk_1.default.
|
|
36
|
+
case "warning":
|
|
37
|
+
console.log(chalk_1.default.yellow("⚠️ " + event.message));
|
|
38
|
+
break;
|
|
39
|
+
case "info":
|
|
40
|
+
console.log(chalk_1.default.gray(" ℹ " + event.message));
|
|
38
41
|
break;
|
|
39
42
|
}
|
|
40
43
|
}
|
|
@@ -42,6 +45,6 @@ function displayProgress(event) {
|
|
|
42
45
|
* Display an error message
|
|
43
46
|
*/
|
|
44
47
|
function displayError(error) {
|
|
45
|
-
const message = error instanceof Error ? error.message :
|
|
46
|
-
console.error(chalk_1.default.red(
|
|
48
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
49
|
+
console.error(chalk_1.default.red("❌ Error:"), message);
|
|
47
50
|
}
|
|
@@ -63,7 +63,7 @@ function parseModelString(modelStr) {
|
|
|
63
63
|
exports.benchmarkCommand
|
|
64
64
|
.command("run")
|
|
65
65
|
.description("Run a benchmark operation")
|
|
66
|
-
.argument("<operation>", "Operation to benchmark (e.g., prd-parse, task-breakdown)")
|
|
66
|
+
.argument("<operation>", "Operation to benchmark (e.g., prd-parse, task-breakdown, task-create, prd-create)")
|
|
67
67
|
.requiredOption("--models <list>", "Comma-separated list of models (provider:model[:reasoning=<tokens>])")
|
|
68
68
|
.option("--file <path>", "Input file path (for PRD ops)")
|
|
69
69
|
.option("--task-id <id>", "Task ID (for Task ops)")
|
|
@@ -72,7 +72,22 @@ exports.benchmarkCommand
|
|
|
72
72
|
.option("--prompt <prompt>", "Override prompt")
|
|
73
73
|
.option("--message <message>", "User message")
|
|
74
74
|
.option("--tools", "Enable filesystem tools")
|
|
75
|
-
.option("--feedback <feedback>", "Feedback (for rework)")
|
|
75
|
+
.option("--feedback <feedback>", "Feedback (for prd-rework)")
|
|
76
|
+
// Task creation options
|
|
77
|
+
.option("--title <title>", "Task title (for task-create)")
|
|
78
|
+
.option("--content <content>", "Task content (for task-create)")
|
|
79
|
+
.option("--parent-id <id>", "Parent task ID (for task-create)")
|
|
80
|
+
.option("--effort <effort>", "Effort estimate: small, medium, large (for task-create)")
|
|
81
|
+
.option("--force", "Force operation (for task-document)")
|
|
82
|
+
// PRD creation options
|
|
83
|
+
.option("--description <desc>", "Project/PRD description (for prd-create, prd-combine)")
|
|
84
|
+
.option("--output-dir <dir>", "Output directory (for prd-create, prd-combine)")
|
|
85
|
+
.option("--filename <name>", "Output filename (for prd-create, prd-combine)")
|
|
86
|
+
// PRD combine options
|
|
87
|
+
.option("--prds <list>", "Comma-separated list of PRD file paths (for prd-combine)")
|
|
88
|
+
// PRD refine options
|
|
89
|
+
.option("--question-mode <mode>", "Question mode: user or ai (for prd-refine)")
|
|
90
|
+
.option("--answers <json>", "JSON string of answers (for prd-refine user mode)")
|
|
76
91
|
.action(async (operation, options) => {
|
|
77
92
|
try {
|
|
78
93
|
const modelStrings = options.models.split(",");
|
|
@@ -86,6 +101,7 @@ exports.benchmarkCommand
|
|
|
86
101
|
console.log(chalk_1.default.dim(`Models: ${models.length}, Concurrency: ${config.concurrency}, Delay: ${config.delay}ms`));
|
|
87
102
|
// Construct input object with all potential options
|
|
88
103
|
const input = {
|
|
104
|
+
// Common options
|
|
89
105
|
file: options.file,
|
|
90
106
|
taskId: options.taskId,
|
|
91
107
|
prompt: options.prompt,
|
|
@@ -93,6 +109,20 @@ exports.benchmarkCommand
|
|
|
93
109
|
tools: options.tools,
|
|
94
110
|
feedback: options.feedback,
|
|
95
111
|
workingDirectory: process.cwd(), // Always pass current working directory
|
|
112
|
+
// Task creation options
|
|
113
|
+
title: options.title,
|
|
114
|
+
content: options.content,
|
|
115
|
+
parentId: options.parentId,
|
|
116
|
+
effort: options.effort,
|
|
117
|
+
force: options.force,
|
|
118
|
+
// PRD creation/combine options
|
|
119
|
+
description: options.description,
|
|
120
|
+
outputDir: options.outputDir,
|
|
121
|
+
filename: options.filename,
|
|
122
|
+
prds: options.prds ? options.prds.split(",").map((p) => p.trim()) : undefined,
|
|
123
|
+
// PRD refine options
|
|
124
|
+
questionMode: options.questionMode,
|
|
125
|
+
answers: options.answers ? JSON.parse(options.answers) : undefined,
|
|
96
126
|
};
|
|
97
127
|
// Prepare dashboard
|
|
98
128
|
console.log(chalk_1.default.bold("\nBenchmark Progress:"));
|
|
@@ -181,6 +211,44 @@ exports.benchmarkCommand
|
|
|
181
211
|
console.log(`- ${chalk_1.default.cyan(run.id)} (${date}) - ${run.command}`);
|
|
182
212
|
});
|
|
183
213
|
});
|
|
214
|
+
exports.benchmarkCommand
|
|
215
|
+
.command("operations")
|
|
216
|
+
.description("List all available benchmark operations")
|
|
217
|
+
.action(() => {
|
|
218
|
+
const { benchmarkRegistry } = require("../lib/benchmark/registry");
|
|
219
|
+
const operations = benchmarkRegistry.list();
|
|
220
|
+
console.log(chalk_1.default.bold("\n📊 Available Benchmark Operations\n"));
|
|
221
|
+
console.log(chalk_1.default.dim("Use these operation IDs with 'benchmark run <operation>'\n"));
|
|
222
|
+
// Group by category
|
|
223
|
+
const taskOps = operations.filter((op) => op.id.startsWith("task-"));
|
|
224
|
+
const prdOps = operations.filter((op) => op.id.startsWith("prd-"));
|
|
225
|
+
const workflowOps = operations.filter((op) => op.id.startsWith("workflow-"));
|
|
226
|
+
if (taskOps.length > 0) {
|
|
227
|
+
console.log(chalk_1.default.cyan.bold("Task Operations:"));
|
|
228
|
+
taskOps.forEach((op) => {
|
|
229
|
+
console.log(` ${chalk_1.default.green(op.id.padEnd(20))} - ${op.description}`);
|
|
230
|
+
});
|
|
231
|
+
console.log();
|
|
232
|
+
}
|
|
233
|
+
if (prdOps.length > 0) {
|
|
234
|
+
console.log(chalk_1.default.cyan.bold("PRD Operations:"));
|
|
235
|
+
prdOps.forEach((op) => {
|
|
236
|
+
console.log(` ${chalk_1.default.green(op.id.padEnd(20))} - ${op.description}`);
|
|
237
|
+
});
|
|
238
|
+
console.log();
|
|
239
|
+
}
|
|
240
|
+
if (workflowOps.length > 0) {
|
|
241
|
+
console.log(chalk_1.default.cyan.bold("Workflow Operations:"));
|
|
242
|
+
workflowOps.forEach((op) => {
|
|
243
|
+
console.log(` ${chalk_1.default.green(op.id.padEnd(20))} - ${op.description}`);
|
|
244
|
+
});
|
|
245
|
+
console.log();
|
|
246
|
+
}
|
|
247
|
+
console.log(chalk_1.default.dim("\nTotal operations: " + operations.length));
|
|
248
|
+
console.log(chalk_1.default.dim("\nExample usage:"));
|
|
249
|
+
console.log(chalk_1.default.gray(" task-o-matic benchmark run task-create --models anthropic:claude-3.5-sonnet --title \"Example task\""));
|
|
250
|
+
console.log(chalk_1.default.gray(" task-o-matic benchmark run prd-parse --models openai:gpt-4 --file ./prd.md"));
|
|
251
|
+
});
|
|
184
252
|
exports.benchmarkCommand
|
|
185
253
|
.command("show")
|
|
186
254
|
.description("Show details of a benchmark run")
|
package/dist/commands/init.js
CHANGED
|
@@ -30,6 +30,9 @@ exports.initCommand
|
|
|
30
30
|
.option("--auth <auth>", "Authentication for bootstrap", "better-auth")
|
|
31
31
|
.option("--context7-api-key <key>", "Context7 API key")
|
|
32
32
|
.option("--directory <dir>", "Working directory for the project")
|
|
33
|
+
.option("--package-manager <pm>", "Package manager (npm/pnpm/bun)", "npm")
|
|
34
|
+
.option("--runtime <runtime>", "Runtime (bun/node)", "node")
|
|
35
|
+
.option("--payment <payment>", "Payment provider (none/polar)", "none")
|
|
33
36
|
.action(async (options) => {
|
|
34
37
|
// Handle directory creation/setup first
|
|
35
38
|
if (options.directory) {
|
|
@@ -41,12 +44,53 @@ exports.initCommand
|
|
|
41
44
|
}
|
|
42
45
|
// Set working directory in ConfigManager BEFORE any other operations
|
|
43
46
|
config_1.configManager.setWorkingDirectory(targetDir);
|
|
47
|
+
await config_1.configManager.load();
|
|
44
48
|
console.log(chalk_1.default.cyan(` 📁 Working directory: ${targetDir}`));
|
|
45
49
|
}
|
|
50
|
+
// If project name is provided, run bootstrap FIRST
|
|
51
|
+
if (options.projectName && !options.noBootstrap) {
|
|
52
|
+
console.log(chalk_1.default.blue("\n🚀 Running bootstrap..."));
|
|
53
|
+
// Use working directory for Better-T-Stack execution
|
|
54
|
+
const workingDir = options.directory || process.cwd();
|
|
55
|
+
try {
|
|
56
|
+
const result = await (0, better_t_stack_cli_1.runBetterTStackCLI)(options, workingDir);
|
|
57
|
+
if (result.success && result.projectPath) {
|
|
58
|
+
console.log(chalk_1.default.green(result.message));
|
|
59
|
+
// Update config manager to point to the new project directory
|
|
60
|
+
config_1.configManager.setWorkingDirectory(result.projectPath);
|
|
61
|
+
await config_1.configManager.load();
|
|
62
|
+
// Initialize task-o-matic structure in the new project directory
|
|
63
|
+
await initializeProjectStructure(options);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
throw new Error(result.message);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
console.error(chalk_1.default.red("Bootstrap failed:"), error);
|
|
71
|
+
return; // Stop if bootstrap fails
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
// Standard initialization in current directory
|
|
76
|
+
await initializeProjectStructure(options);
|
|
77
|
+
}
|
|
78
|
+
console.log(chalk_1.default.cyan("\nNext steps:"));
|
|
79
|
+
if (!options.projectName) {
|
|
80
|
+
console.log(" 1. Configure AI provider: task-o-matic config set-ai-provider <provider> <model>");
|
|
81
|
+
console.log(" 2. Bootstrap your project: task-o-matic init bootstrap <project-name>");
|
|
82
|
+
console.log(' 3. Create your first task: task-o-matic tasks create --title "Your first task"');
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
console.log(` 1. cd ${options.projectName}`);
|
|
86
|
+
console.log(' 2. Create your first task: task-o-matic tasks create --title "Your first task"');
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
async function initializeProjectStructure(options) {
|
|
46
90
|
const taskOMaticDir = config_1.configManager.getTaskOMaticDir();
|
|
47
91
|
console.log(chalk_1.default.blue(`🔍 Checking for task-o-matic directory: ${taskOMaticDir}`));
|
|
48
|
-
if ((0, fs_1.existsSync)(taskOMaticDir)) {
|
|
49
|
-
console.log(chalk_1.default.yellow("⚠️ This
|
|
92
|
+
if ((0, fs_1.existsSync)((0, path_1.join)(taskOMaticDir, "config.json"))) {
|
|
93
|
+
console.log(chalk_1.default.yellow("⚠️ This project is already initialized with task-o-matic."));
|
|
50
94
|
return;
|
|
51
95
|
}
|
|
52
96
|
console.log(chalk_1.default.blue("🚀 Initializing task-o-matic project..."));
|
|
@@ -88,31 +132,7 @@ exports.initCommand
|
|
|
88
132
|
(0, fs_1.writeFileSync)(mcpFilePath, JSON.stringify(mcpConfig, null, 2));
|
|
89
133
|
console.log(chalk_1.default.green(` ✓ Created ${mcpFilePath}`));
|
|
90
134
|
console.log(chalk_1.default.green("\n✅ TaskOMatic project initialized successfully!"));
|
|
91
|
-
|
|
92
|
-
if (options.projectName && !options.noBootstrap) {
|
|
93
|
-
console.log(chalk_1.default.blue("\n🚀 Running bootstrap..."));
|
|
94
|
-
// Use working directory for Better-T-Stack execution
|
|
95
|
-
const workingDir = options.directory || process.cwd();
|
|
96
|
-
try {
|
|
97
|
-
const result = await (0, better_t_stack_cli_1.runBetterTStackCLI)(options, workingDir);
|
|
98
|
-
if (result.success) {
|
|
99
|
-
console.log(chalk_1.default.green(result.message));
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
throw new Error(result.message);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
catch (error) {
|
|
106
|
-
// No chdir needed anymore
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
console.log(chalk_1.default.cyan("\nNext steps:"));
|
|
111
|
-
console.log(" 1. Configure AI provider: task-o-matic config set-ai-provider <provider> <model>");
|
|
112
|
-
console.log(" 2. Bootstrap your project: task-o-matic init bootstrap <project-name>");
|
|
113
|
-
console.log(' 3. Create your first task: task-o-matic tasks create --title "Your first task"');
|
|
114
|
-
}
|
|
115
|
-
});
|
|
135
|
+
}
|
|
116
136
|
// Bootstrap project with Better-T-Stack
|
|
117
137
|
exports.initCommand
|
|
118
138
|
.command("bootstrap")
|
|
@@ -131,6 +151,7 @@ exports.initCommand
|
|
|
131
151
|
.option("--db-setup <setup>", "Database setup (turso/neon/prisma-postgres/mongodb-atlas)")
|
|
132
152
|
.option("--runtime <runtime>", "Runtime (bun/node)", "node")
|
|
133
153
|
.option("--api <type>", "API type (trpc/orpc)")
|
|
154
|
+
.option("--payment <payment>", "Payment provider (none/polar)", "none")
|
|
134
155
|
.action(async (name, options) => {
|
|
135
156
|
const taskOMaticDir = config_1.configManager.getTaskOMaticDir();
|
|
136
157
|
if (!(0, fs_1.existsSync)(taskOMaticDir)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prd.d.ts","sourceRoot":"","sources":["../../src/commands/prd.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"prd.d.ts","sourceRoot":"","sources":["../../src/commands/prd.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,eAAO,MAAM,UAAU,SAEtB,CAAC"}
|
package/dist/commands/prd.js
CHANGED
|
@@ -41,10 +41,211 @@ exports.prdCommand = void 0;
|
|
|
41
41
|
const commander_1 = require("commander");
|
|
42
42
|
const chalk_1 = __importDefault(require("chalk"));
|
|
43
43
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
44
|
+
const fs_1 = require("fs");
|
|
44
45
|
const prd_1 = require("../services/prd");
|
|
45
46
|
const streaming_options_1 = require("../utils/streaming-options");
|
|
46
47
|
const progress_1 = require("../cli/display/progress");
|
|
47
48
|
exports.prdCommand = new commander_1.Command("prd").description("Manage PRDs and generate tasks");
|
|
49
|
+
// Helper to parse model string (provider:model)
|
|
50
|
+
function parseModelString(modelStr) {
|
|
51
|
+
const parts = modelStr.split(":");
|
|
52
|
+
if (parts.length < 2) {
|
|
53
|
+
throw new Error(`Invalid model format: ${modelStr}. Expected provider:model`);
|
|
54
|
+
}
|
|
55
|
+
return { provider: parts[0], model: parts[1] };
|
|
56
|
+
}
|
|
57
|
+
// Create PRD command
|
|
58
|
+
exports.prdCommand
|
|
59
|
+
.command("create")
|
|
60
|
+
.description("Generate PRD(s) from a product description")
|
|
61
|
+
.argument("<description>", "Product description")
|
|
62
|
+
.option("--ai <provider:model...>", "AI model(s) to use for generation (can specify multiple)")
|
|
63
|
+
.option("--combine-ai <provider:model>", "AI model to combine multiple PRDs into master PRD")
|
|
64
|
+
.option("--output-dir <path>", "Directory to save PRDs", ".task-o-matic/prd")
|
|
65
|
+
.option("--stream", "Enable streaming output (only for single AI)")
|
|
66
|
+
.action(async (description, options) => {
|
|
67
|
+
try {
|
|
68
|
+
const aiModels = options.ai || ["openrouter:anthropic/claude-3.5-sonnet"];
|
|
69
|
+
const isSingleModel = aiModels.length === 1;
|
|
70
|
+
// For single model, support streaming
|
|
71
|
+
if (isSingleModel) {
|
|
72
|
+
const modelConfig = parseModelString(aiModels[0]);
|
|
73
|
+
const streamingOptions = (0, streaming_options_1.createStreamingOptions)(options.stream, "Generating PRD");
|
|
74
|
+
const result = await prd_1.prdService.generatePRD({
|
|
75
|
+
description,
|
|
76
|
+
outputDir: options.outputDir,
|
|
77
|
+
filename: `prd-${modelConfig.provider}-${modelConfig.model.replace(/\//g, "-")}.md`,
|
|
78
|
+
aiOptions: {
|
|
79
|
+
aiProvider: modelConfig.provider,
|
|
80
|
+
aiModel: modelConfig.model,
|
|
81
|
+
},
|
|
82
|
+
streamingOptions,
|
|
83
|
+
callbacks: {
|
|
84
|
+
onProgress: progress_1.displayProgress,
|
|
85
|
+
onError: progress_1.displayError,
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
console.log("");
|
|
89
|
+
console.log(chalk_1.default.green(`✓ PRD generated: ${result.path}`));
|
|
90
|
+
console.log(chalk_1.default.cyan(` Duration: ${result.stats.duration}ms`));
|
|
91
|
+
if (result.stats.tokenUsage) {
|
|
92
|
+
console.log(chalk_1.default.cyan(` Tokens: ${result.stats.tokenUsage.total}`));
|
|
93
|
+
}
|
|
94
|
+
if (result.stats.timeToFirstToken) {
|
|
95
|
+
console.log(chalk_1.default.cyan(` TTFT: ${result.stats.timeToFirstToken}ms`));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
// Multiple models - use benchmark-style display
|
|
100
|
+
console.log(chalk_1.default.blue(`\nGenerating ${aiModels.length} PRDs concurrently...\n`));
|
|
101
|
+
const modelMap = new Map();
|
|
102
|
+
const modelStatus = new Map();
|
|
103
|
+
const results = [];
|
|
104
|
+
// Print initial lines
|
|
105
|
+
aiModels.forEach((m, i) => {
|
|
106
|
+
modelMap.set(m, i);
|
|
107
|
+
modelStatus.set(m, "Waiting...");
|
|
108
|
+
console.log(chalk_1.default.dim(`- ${m}: Waiting...`));
|
|
109
|
+
});
|
|
110
|
+
const totalModels = aiModels.length;
|
|
111
|
+
// Generate PRDs concurrently
|
|
112
|
+
const promises = aiModels.map(async (modelStr) => {
|
|
113
|
+
const modelConfig = parseModelString(modelStr);
|
|
114
|
+
const index = modelMap.get(modelStr);
|
|
115
|
+
// Update status: Starting
|
|
116
|
+
const up = totalModels - index;
|
|
117
|
+
process.stdout.write(`\x1B[${up}A`);
|
|
118
|
+
process.stdout.write(`\x1B[2K`);
|
|
119
|
+
process.stdout.write(`- ${chalk_1.default.bold(modelStr)}: ${chalk_1.default.yellow("Starting...")}\r`);
|
|
120
|
+
process.stdout.write(`\x1B[${up}B`);
|
|
121
|
+
try {
|
|
122
|
+
const result = await prd_1.prdService.generatePRD({
|
|
123
|
+
description,
|
|
124
|
+
outputDir: options.outputDir,
|
|
125
|
+
filename: `prd-${modelConfig.provider}-${modelConfig.model.replace(/\//g, "-")}.md`,
|
|
126
|
+
aiOptions: {
|
|
127
|
+
aiProvider: modelConfig.provider,
|
|
128
|
+
aiModel: modelConfig.model,
|
|
129
|
+
},
|
|
130
|
+
callbacks: {
|
|
131
|
+
onProgress: (event) => {
|
|
132
|
+
if (event.type === "progress") {
|
|
133
|
+
const up = totalModels - index;
|
|
134
|
+
process.stdout.write(`\x1B[${up}A`);
|
|
135
|
+
process.stdout.write(`\x1B[2K`);
|
|
136
|
+
process.stdout.write(`- ${chalk_1.default.bold(modelStr)}: ${chalk_1.default.blue(event.message)}\r`);
|
|
137
|
+
process.stdout.write(`\x1B[${up}B`);
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
// Update status: Completed
|
|
143
|
+
const up2 = totalModels - index;
|
|
144
|
+
process.stdout.write(`\x1B[${up2}A`);
|
|
145
|
+
process.stdout.write(`\x1B[2K`);
|
|
146
|
+
process.stdout.write(`- ${chalk_1.default.bold(modelStr)}: ${chalk_1.default.green(`Completed (${result.stats.duration}ms)`)}\r`);
|
|
147
|
+
process.stdout.write(`\x1B[${up2}B`);
|
|
148
|
+
results.push({
|
|
149
|
+
modelId: modelStr,
|
|
150
|
+
path: result.path,
|
|
151
|
+
stats: result.stats,
|
|
152
|
+
});
|
|
153
|
+
return result;
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
const up2 = totalModels - index;
|
|
157
|
+
process.stdout.write(`\x1B[${up2}A`);
|
|
158
|
+
process.stdout.write(`\x1B[2K`);
|
|
159
|
+
process.stdout.write(`- ${chalk_1.default.bold(modelStr)}: ${chalk_1.default.red(`Failed: ${error instanceof Error ? error.message : String(error)}`)}\r`);
|
|
160
|
+
process.stdout.write(`\x1B[${up2}B`);
|
|
161
|
+
throw error;
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
await Promise.all(promises);
|
|
165
|
+
// Display summary
|
|
166
|
+
console.log(chalk_1.default.green(`\n✓ Generated ${results.length} PRDs\n`));
|
|
167
|
+
console.log(chalk_1.default.bold(`${"Model".padEnd(40)} | ${"Duration".padEnd(10)} | ${"TTFT".padEnd(10)} | ${"Tokens".padEnd(10)}`));
|
|
168
|
+
console.log("-".repeat(80));
|
|
169
|
+
results.forEach((r) => {
|
|
170
|
+
const duration = `${r.stats.duration}ms`;
|
|
171
|
+
const ttft = r.stats.timeToFirstToken
|
|
172
|
+
? `${r.stats.timeToFirstToken}ms`
|
|
173
|
+
: "N/A";
|
|
174
|
+
const tokens = r.stats.tokenUsage
|
|
175
|
+
? r.stats.tokenUsage.total.toString()
|
|
176
|
+
: "N/A";
|
|
177
|
+
console.log(`${r.modelId.padEnd(40)} | ${duration.padEnd(10)} | ${ttft.padEnd(10)} | ${tokens.padEnd(10)}`);
|
|
178
|
+
});
|
|
179
|
+
// Combine if requested
|
|
180
|
+
if (options.combineAi) {
|
|
181
|
+
console.log(chalk_1.default.blue("\nCombining PRDs into master PRD..."));
|
|
182
|
+
const combineModelConfig = parseModelString(options.combineAi);
|
|
183
|
+
const prdContents = results.map((r) => (0, fs_1.readFileSync)(r.path, "utf-8"));
|
|
184
|
+
const masterResult = await prd_1.prdService.combinePRDs({
|
|
185
|
+
prds: prdContents,
|
|
186
|
+
originalDescription: description,
|
|
187
|
+
outputDir: options.outputDir,
|
|
188
|
+
filename: "prd-master.md",
|
|
189
|
+
aiOptions: {
|
|
190
|
+
aiProvider: combineModelConfig.provider,
|
|
191
|
+
aiModel: combineModelConfig.model,
|
|
192
|
+
},
|
|
193
|
+
callbacks: {
|
|
194
|
+
onProgress: progress_1.displayProgress,
|
|
195
|
+
onError: progress_1.displayError,
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
console.log(chalk_1.default.green(`\n✓ Master PRD created: ${masterResult.path}`));
|
|
199
|
+
console.log(chalk_1.default.cyan(` Duration: ${masterResult.stats.duration}ms`));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
(0, progress_1.displayError)(error);
|
|
205
|
+
process.exit(1);
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
// Combine PRDs command
|
|
209
|
+
exports.prdCommand
|
|
210
|
+
.command("combine")
|
|
211
|
+
.description("Combine multiple PRD files into a master PRD")
|
|
212
|
+
.requiredOption("--files <paths...>", "PRD files to combine")
|
|
213
|
+
.requiredOption("--description <text>", "Original product description")
|
|
214
|
+
.requiredOption("--ai <provider:model>", "AI model to use for combining")
|
|
215
|
+
.option("--output <path>", "Output file path", "prd-master.md")
|
|
216
|
+
.option("--stream", "Enable streaming output")
|
|
217
|
+
.action(async (options) => {
|
|
218
|
+
try {
|
|
219
|
+
const modelConfig = parseModelString(options.ai);
|
|
220
|
+
const streamingOptions = (0, streaming_options_1.createStreamingOptions)(options.stream, "Combining PRDs");
|
|
221
|
+
// Read all PRD files
|
|
222
|
+
const prdContents = options.files.map((file) => (0, fs_1.readFileSync)(file, "utf-8"));
|
|
223
|
+
const result = await prd_1.prdService.combinePRDs({
|
|
224
|
+
prds: prdContents,
|
|
225
|
+
originalDescription: options.description,
|
|
226
|
+
filename: options.output,
|
|
227
|
+
aiOptions: {
|
|
228
|
+
aiProvider: modelConfig.provider,
|
|
229
|
+
aiModel: modelConfig.model,
|
|
230
|
+
},
|
|
231
|
+
streamingOptions,
|
|
232
|
+
callbacks: {
|
|
233
|
+
onProgress: progress_1.displayProgress,
|
|
234
|
+
onError: progress_1.displayError,
|
|
235
|
+
},
|
|
236
|
+
});
|
|
237
|
+
console.log("");
|
|
238
|
+
console.log(chalk_1.default.green(`✓ Master PRD created: ${result.path}`));
|
|
239
|
+
console.log(chalk_1.default.cyan(` Duration: ${result.stats.duration}ms`));
|
|
240
|
+
if (result.stats.tokenUsage) {
|
|
241
|
+
console.log(chalk_1.default.cyan(` Tokens: ${result.stats.tokenUsage.total}`));
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
(0, progress_1.displayError)(error);
|
|
246
|
+
process.exit(1);
|
|
247
|
+
}
|
|
248
|
+
});
|
|
48
249
|
// Parse PRD into tasks
|
|
49
250
|
exports.prdCommand
|
|
50
251
|
.command("parse")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute-loop.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/execute-loop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"execute-loop.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/execute-loop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmDpC,eAAO,MAAM,kBAAkB,SAwJ3B,CAAC"}
|
|
@@ -52,6 +52,11 @@ exports.executeLoopCommand = new commander_1.Command("execute-loop")
|
|
|
52
52
|
return [...previous, value];
|
|
53
53
|
})
|
|
54
54
|
.option("--auto-commit", "Automatically commit changes after each task", false)
|
|
55
|
+
.option("--plan", "Generate an implementation plan before execution", false)
|
|
56
|
+
.option("--plan-model <model>", "Model/executor to use for planning (e.g., 'opencode:gpt-4o')")
|
|
57
|
+
.option("--review-plan", "Pause for human review of the plan", false)
|
|
58
|
+
.option("--review", "Run AI review after execution", false)
|
|
59
|
+
.option("--review-model <model>", "Model/executor to use for review (e.g., 'opencode:gpt-4o')")
|
|
55
60
|
.option("--dry", "Show what would be executed without running it", false)
|
|
56
61
|
.action(async (options) => {
|
|
57
62
|
try {
|
|
@@ -99,6 +104,11 @@ exports.executeLoopCommand = new commander_1.Command("execute-loop")
|
|
|
99
104
|
verificationCommands: options.verify || [],
|
|
100
105
|
autoCommit: options.autoCommit,
|
|
101
106
|
tryModels,
|
|
107
|
+
plan: options.plan,
|
|
108
|
+
planModel: options.planModel,
|
|
109
|
+
reviewPlan: options.reviewPlan,
|
|
110
|
+
review: options.review,
|
|
111
|
+
reviewModel: options.reviewModel,
|
|
102
112
|
},
|
|
103
113
|
dry: options.dry,
|
|
104
114
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/execute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/execute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,cAAc,SA4CvB,CAAC"}
|
|
@@ -12,6 +12,8 @@ exports.executeCommand = new commander_1.Command("execute")
|
|
|
12
12
|
.requiredOption("--id <id>", "Task ID to execute")
|
|
13
13
|
.option("--tool <tool>", "External tool to use (opencode/claude/gemini/codex)", "opencode")
|
|
14
14
|
.option("--message <message>", "Custom message to send to the tool (uses task plan if not provided)")
|
|
15
|
+
.option("-m, --model <model>", "Model to use with the executor")
|
|
16
|
+
.option("--continue-session", "Continue the last session (for error feedback)", false)
|
|
15
17
|
.option("--dry", "Show what would be executed without running it")
|
|
16
18
|
.option("--validate <command>", "Validation command to run after execution (can be used multiple times)", (value, previous = []) => {
|
|
17
19
|
return [...previous, value];
|
|
@@ -22,6 +24,8 @@ exports.executeCommand = new commander_1.Command("execute")
|
|
|
22
24
|
taskId: options.id,
|
|
23
25
|
tool: options.tool,
|
|
24
26
|
message: options.message,
|
|
27
|
+
model: options.model,
|
|
28
|
+
continueSession: options.continueSession,
|
|
25
29
|
dry: options.dry,
|
|
26
30
|
validate: options.validate || [],
|
|
27
31
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../src/commands/workflow.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsBpC,eAAO,MAAM,eAAe,
|
|
1
|
+
{"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../src/commands/workflow.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsBpC,eAAO,MAAM,eAAe,SAsKxB,CAAC"}
|