task-o-matic 0.0.1
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/LICENSE +21 -0
- package/README.md +552 -0
- package/dist/cli/bin.d.ts +3 -0
- package/dist/cli/bin.d.ts.map +1 -0
- package/dist/cli/bin.js +8 -0
- package/dist/cli/display/common.d.ts +5 -0
- package/dist/cli/display/common.d.ts.map +1 -0
- package/dist/cli/display/common.js +44 -0
- package/dist/cli/display/plan.d.ts +11 -0
- package/dist/cli/display/plan.d.ts.map +1 -0
- package/dist/cli/display/plan.js +42 -0
- package/dist/cli/display/progress.d.ts +11 -0
- package/dist/cli/display/progress.d.ts.map +1 -0
- package/dist/cli/display/progress.js +47 -0
- package/dist/cli/display/task.d.ts +18 -0
- package/dist/cli/display/task.d.ts.map +1 -0
- package/dist/cli/display/task.js +250 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +61 -0
- package/dist/commands/init.d.ts +4 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +197 -0
- package/dist/commands/prd.d.ts +4 -0
- package/dist/commands/prd.d.ts.map +1 -0
- package/dist/commands/prd.js +131 -0
- package/dist/commands/prompt.d.ts +3 -0
- package/dist/commands/prompt.d.ts.map +1 -0
- package/dist/commands/prompt.js +192 -0
- package/dist/commands/tasks.d.ts +3 -0
- package/dist/commands/tasks.d.ts.map +1 -0
- package/dist/commands/tasks.js +599 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +67 -0
- package/dist/lib/ai-service/ai-operations.d.ts +31 -0
- package/dist/lib/ai-service/ai-operations.d.ts.map +1 -0
- package/dist/lib/ai-service/ai-operations.js +648 -0
- package/dist/lib/ai-service/json-parser.d.ts +9 -0
- package/dist/lib/ai-service/json-parser.d.ts.map +1 -0
- package/dist/lib/ai-service/json-parser.js +37 -0
- package/dist/lib/ai-service/mcp-client.d.ts +9 -0
- package/dist/lib/ai-service/mcp-client.d.ts.map +1 -0
- package/dist/lib/ai-service/mcp-client.js +48 -0
- package/dist/lib/ai-service/model-provider.d.ts +8 -0
- package/dist/lib/ai-service/model-provider.d.ts.map +1 -0
- package/dist/lib/ai-service/model-provider.js +71 -0
- package/dist/lib/ai-service/research-tools.d.ts +4 -0
- package/dist/lib/ai-service/research-tools.d.ts.map +1 -0
- package/dist/lib/ai-service/research-tools.js +8 -0
- package/dist/lib/ai-service/retry-handler.d.ts +8 -0
- package/dist/lib/ai-service/retry-handler.d.ts.map +1 -0
- package/dist/lib/ai-service/retry-handler.js +62 -0
- package/dist/lib/better-t-stack-cli.d.ts +35 -0
- package/dist/lib/better-t-stack-cli.d.ts.map +1 -0
- package/dist/lib/better-t-stack-cli.js +118 -0
- package/dist/lib/config.d.ts +24 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +160 -0
- package/dist/lib/context-builder.d.ts +53 -0
- package/dist/lib/context-builder.d.ts.map +1 -0
- package/dist/lib/context-builder.js +294 -0
- package/dist/lib/executors/executor-factory.d.ts +5 -0
- package/dist/lib/executors/executor-factory.d.ts.map +1 -0
- package/dist/lib/executors/executor-factory.js +21 -0
- package/dist/lib/executors/opencode-executor.d.ts +6 -0
- package/dist/lib/executors/opencode-executor.d.ts.map +1 -0
- package/dist/lib/executors/opencode-executor.js +46 -0
- package/dist/lib/index.d.ts +89 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +134 -0
- package/dist/lib/prompt-builder.d.ts +50 -0
- package/dist/lib/prompt-builder.d.ts.map +1 -0
- package/dist/lib/prompt-builder.js +171 -0
- package/dist/lib/prompt-registry.d.ts +22 -0
- package/dist/lib/prompt-registry.d.ts.map +1 -0
- package/dist/lib/prompt-registry.js +201 -0
- package/dist/lib/storage.d.ts +60 -0
- package/dist/lib/storage.d.ts.map +1 -0
- package/dist/lib/storage.js +768 -0
- package/dist/lib/task-execution.d.ts +3 -0
- package/dist/lib/task-execution.d.ts.map +1 -0
- package/dist/lib/task-execution.js +130 -0
- package/dist/lib/validation.d.ts +4 -0
- package/dist/lib/validation.d.ts.map +1 -0
- package/dist/lib/validation.js +52 -0
- package/dist/mcp/prompts.d.ts +3 -0
- package/dist/mcp/prompts.d.ts.map +1 -0
- package/dist/mcp/prompts.js +7 -0
- package/dist/mcp/resources.d.ts +3 -0
- package/dist/mcp/resources.d.ts.map +1 -0
- package/dist/mcp/resources.js +7 -0
- package/dist/mcp/server.d.ts +3 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +25 -0
- package/dist/mcp/tools.d.ts +3 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +99 -0
- package/dist/prompts/documentation-detection.d.ts +2 -0
- package/dist/prompts/documentation-detection.d.ts.map +1 -0
- package/dist/prompts/documentation-detection.js +24 -0
- package/dist/prompts/index.d.ts +7 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +22 -0
- package/dist/prompts/prd-parsing.d.ts +3 -0
- package/dist/prompts/prd-parsing.d.ts.map +1 -0
- package/dist/prompts/prd-parsing.js +172 -0
- package/dist/prompts/prd-rework.d.ts +3 -0
- package/dist/prompts/prd-rework.d.ts.map +1 -0
- package/dist/prompts/prd-rework.js +81 -0
- package/dist/prompts/task-breakdown.d.ts +3 -0
- package/dist/prompts/task-breakdown.d.ts.map +1 -0
- package/dist/prompts/task-breakdown.js +151 -0
- package/dist/prompts/task-enhancement.d.ts +3 -0
- package/dist/prompts/task-enhancement.d.ts.map +1 -0
- package/dist/prompts/task-enhancement.js +140 -0
- package/dist/prompts/task-planning.d.ts +3 -0
- package/dist/prompts/task-planning.d.ts.map +1 -0
- package/dist/prompts/task-planning.js +66 -0
- package/dist/services/prd.d.ts +32 -0
- package/dist/services/prd.d.ts.map +1 -0
- package/dist/services/prd.js +191 -0
- package/dist/services/tasks.d.ts +67 -0
- package/dist/services/tasks.d.ts.map +1 -0
- package/dist/services/tasks.js +596 -0
- package/dist/test/commands.test.d.ts +2 -0
- package/dist/test/commands.test.d.ts.map +1 -0
- package/dist/test/commands.test.js +74 -0
- package/dist/test/storage.test.d.ts +2 -0
- package/dist/test/storage.test.d.ts.map +1 -0
- package/dist/test/storage.test.js +207 -0
- package/dist/types/callbacks.d.ts +27 -0
- package/dist/types/callbacks.d.ts.map +1 -0
- package/dist/types/callbacks.js +2 -0
- package/dist/types/index.d.ts +252 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/mcp.d.ts +3 -0
- package/dist/types/mcp.d.ts.map +1 -0
- package/dist/types/mcp.js +3 -0
- package/dist/types/options.d.ts +94 -0
- package/dist/types/options.d.ts.map +1 -0
- package/dist/types/options.js +2 -0
- package/dist/types/results.d.ts +90 -0
- package/dist/types/results.d.ts.map +1 -0
- package/dist/types/results.js +2 -0
- package/dist/utils/ai-config-builder.d.ts +14 -0
- package/dist/utils/ai-config-builder.d.ts.map +1 -0
- package/dist/utils/ai-config-builder.js +22 -0
- package/dist/utils/ai-service-factory.d.ts +10 -0
- package/dist/utils/ai-service-factory.d.ts.map +1 -0
- package/dist/utils/ai-service-factory.js +52 -0
- package/dist/utils/stack-formatter.d.ts +11 -0
- package/dist/utils/stack-formatter.d.ts.map +1 -0
- package/dist/utils/stack-formatter.js +30 -0
- package/dist/utils/streaming-options.d.ts +10 -0
- package/dist/utils/streaming-options.d.ts.map +1 -0
- package/dist/utils/streaming-options.js +53 -0
- package/package.json +82 -0
|
@@ -0,0 +1,599 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.tasksCommand = void 0;
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const tasks_1 = require("../services/tasks");
|
|
10
|
+
const task_execution_1 = require("../lib/task-execution");
|
|
11
|
+
const streaming_options_1 = require("../utils/streaming-options");
|
|
12
|
+
const progress_1 = require("../cli/display/progress");
|
|
13
|
+
const task_1 = require("../cli/display/task");
|
|
14
|
+
const plan_1 = require("../cli/display/plan");
|
|
15
|
+
const common_1 = require("../cli/display/common");
|
|
16
|
+
exports.tasksCommand = new commander_1.Command("tasks");
|
|
17
|
+
// List tasks
|
|
18
|
+
exports.tasksCommand
|
|
19
|
+
.command("list")
|
|
20
|
+
.description("List all tasks")
|
|
21
|
+
.option("--status <status>", "Filter by status (todo/in-progress/completed)")
|
|
22
|
+
.option("--tag <tag>", "Filter by tag")
|
|
23
|
+
.action(async (options) => {
|
|
24
|
+
try {
|
|
25
|
+
const tasks = await tasks_1.taskService.listTasks({
|
|
26
|
+
status: options.status,
|
|
27
|
+
tag: options.tag,
|
|
28
|
+
});
|
|
29
|
+
(0, task_1.displayTaskList)(tasks);
|
|
30
|
+
for (const task of tasks) {
|
|
31
|
+
await (0, task_1.displayTask)(task, { showSubtasks: true });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
(0, progress_1.displayError)(error);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
// Create task
|
|
40
|
+
exports.tasksCommand
|
|
41
|
+
.command("create")
|
|
42
|
+
.description("Create a new task with AI enhancement using Context7")
|
|
43
|
+
.requiredOption("--title <title>", "Task title")
|
|
44
|
+
.option("--content <content>", "Task content (supports markdown)")
|
|
45
|
+
.option("--effort <effort>", "Estimated effort (small/medium/large)")
|
|
46
|
+
.option("--parent-id <id>", "Parent task ID (creates subtask)")
|
|
47
|
+
.option("--ai-enhance", "Enhance task with AI using Context7 documentation")
|
|
48
|
+
.option("--stream", "Show streaming AI output during enhancement")
|
|
49
|
+
.option("--ai-provider <provider>", "AI provider override")
|
|
50
|
+
.option("--ai-model <model>", "AI model override")
|
|
51
|
+
.option("--ai-key <key>", "AI API key override")
|
|
52
|
+
.option("--ai-provider-url <url>", "AI provider URL override")
|
|
53
|
+
.option("--reasoning <tokens>", "Enable reasoning for OpenRouter models (max reasoning tokens)")
|
|
54
|
+
.action(async (options) => {
|
|
55
|
+
try {
|
|
56
|
+
const streamingOptions = (0, streaming_options_1.createStreamingOptions)(options.aiEnhance && options.stream, "Enhancement");
|
|
57
|
+
const result = await tasks_1.taskService.createTask({
|
|
58
|
+
title: options.title,
|
|
59
|
+
content: options.content,
|
|
60
|
+
parentId: options.parentId,
|
|
61
|
+
effort: options.effort,
|
|
62
|
+
aiEnhance: options.aiEnhance,
|
|
63
|
+
aiOptions: {
|
|
64
|
+
aiProvider: options.aiProvider,
|
|
65
|
+
aiModel: options.aiModel,
|
|
66
|
+
aiKey: options.aiKey,
|
|
67
|
+
aiProviderUrl: options.aiProviderUrl,
|
|
68
|
+
aiReasoning: options.reasoning,
|
|
69
|
+
},
|
|
70
|
+
streamingOptions,
|
|
71
|
+
callbacks: {
|
|
72
|
+
onProgress: progress_1.displayProgress,
|
|
73
|
+
onError: progress_1.displayError,
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
(0, common_1.displayEnhancementResult)(options.aiEnhance && options.stream);
|
|
77
|
+
(0, task_1.displayCreatedTask)(result.task, result.aiMetadata);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
(0, progress_1.displayError)(error);
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
// Show task details
|
|
85
|
+
exports.tasksCommand
|
|
86
|
+
.command("show")
|
|
87
|
+
.description("Show detailed information about a task")
|
|
88
|
+
.requiredOption("--id <id>", "Task ID")
|
|
89
|
+
.action(async (options) => {
|
|
90
|
+
try {
|
|
91
|
+
const task = await tasks_1.taskService.getTask(options.id);
|
|
92
|
+
if (!task) {
|
|
93
|
+
throw new Error(`Task with ID ${options.id} not found`);
|
|
94
|
+
}
|
|
95
|
+
await (0, task_1.displayTaskDetails)(task);
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
(0, progress_1.displayError)(error);
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
// Document task
|
|
103
|
+
exports.tasksCommand
|
|
104
|
+
.command("document")
|
|
105
|
+
.description("Analyze and fetch documentation for a task using AI with Context7")
|
|
106
|
+
.requiredOption("--task-id <id>", "Task ID")
|
|
107
|
+
.option("--force", "Force refresh documentation even if recent")
|
|
108
|
+
.option("--stream", "Show streaming AI output during analysis")
|
|
109
|
+
.option("--ai-provider <provider>", "AI provider override")
|
|
110
|
+
.option("--ai-model <model>", "AI model override")
|
|
111
|
+
.option("--ai-key <key>", "AI API key override")
|
|
112
|
+
.option("--ai-provider-url <url>", "AI provider URL override")
|
|
113
|
+
.option("--reasoning <tokens>", "Enable reasoning for OpenRouter models (max reasoning tokens)")
|
|
114
|
+
.action(async (options) => {
|
|
115
|
+
try {
|
|
116
|
+
const streamingOptions = (0, streaming_options_1.createStreamingOptions)(options.stream, "Analysis");
|
|
117
|
+
const result = await tasks_1.taskService.documentTask(options.taskId, options.force, {
|
|
118
|
+
aiProvider: options.aiProvider,
|
|
119
|
+
aiModel: options.aiModel,
|
|
120
|
+
aiKey: options.aiKey,
|
|
121
|
+
aiProviderUrl: options.aiProviderUrl,
|
|
122
|
+
aiReasoning: options.reasoning,
|
|
123
|
+
}, streamingOptions, {
|
|
124
|
+
onProgress: progress_1.displayProgress,
|
|
125
|
+
onError: progress_1.displayError,
|
|
126
|
+
});
|
|
127
|
+
if (result.documentation && !options.force) {
|
|
128
|
+
const daysSinceFetch = (Date.now() - result.documentation.lastFetched) / (24 * 60 * 60 * 1000);
|
|
129
|
+
console.log(chalk_1.default.green(`✓ Documentation is fresh (${Math.round(daysSinceFetch)} days old)`));
|
|
130
|
+
console.log(chalk_1.default.cyan(`Recap: ${result.documentation.recap}`));
|
|
131
|
+
console.log(chalk_1.default.blue(`Libraries: ${result.documentation.libraries.join(", ")}`));
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (result.analysis) {
|
|
135
|
+
(0, common_1.displayDocumentationAnalysis)(result.analysis);
|
|
136
|
+
}
|
|
137
|
+
if (result.documentation?.research) {
|
|
138
|
+
(0, common_1.displayResearchSummary)(result.documentation);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
(0, progress_1.displayError)(error);
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
// Enhance existing task
|
|
147
|
+
exports.tasksCommand
|
|
148
|
+
.command("enhance")
|
|
149
|
+
.description("Enhance an existing task with AI using Context7 documentation")
|
|
150
|
+
.option("--task-id <id>", "Task ID to enhance")
|
|
151
|
+
.option("--all", "Enhance all existing tasks")
|
|
152
|
+
.option("--stream", "Show streaming AI output during enhancement")
|
|
153
|
+
.option("--ai-provider <provider>", "AI provider override")
|
|
154
|
+
.option("--ai-model <model>", "AI model override")
|
|
155
|
+
.option("--ai-key <key>", "AI API key override")
|
|
156
|
+
.option("--ai-provider-url <url>", "AI provider URL override")
|
|
157
|
+
.option("--reasoning <tokens>", "Enable reasoning for OpenRouter models (max reasoning tokens)")
|
|
158
|
+
.action(async (options) => {
|
|
159
|
+
try {
|
|
160
|
+
if (!options.taskId && !options.all) {
|
|
161
|
+
throw new Error("Either --task-id or --all must be specified");
|
|
162
|
+
}
|
|
163
|
+
if (options.taskId && options.all) {
|
|
164
|
+
throw new Error("Cannot specify both --task-id and --all");
|
|
165
|
+
}
|
|
166
|
+
const enhanceSingleTask = async (taskId) => {
|
|
167
|
+
const streamingOptions = (0, streaming_options_1.createStreamingOptions)(options.stream, "Enhancement");
|
|
168
|
+
const result = await tasks_1.taskService.enhanceTask(taskId, {
|
|
169
|
+
aiProvider: options.aiProvider,
|
|
170
|
+
aiModel: options.aiModel,
|
|
171
|
+
aiKey: options.aiKey,
|
|
172
|
+
aiProviderUrl: options.aiProviderUrl,
|
|
173
|
+
aiReasoning: options.reasoning,
|
|
174
|
+
}, streamingOptions, {
|
|
175
|
+
onProgress: progress_1.displayProgress,
|
|
176
|
+
onError: progress_1.displayError,
|
|
177
|
+
});
|
|
178
|
+
if (result.enhancedContent.length > 200) {
|
|
179
|
+
console.log(chalk_1.default.cyan(` Enhanced content saved to file.`));
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
console.log(chalk_1.default.cyan(` Enhanced content updated in task description.`));
|
|
183
|
+
}
|
|
184
|
+
console.log(chalk_1.default.green("✓ Task enhanced with Context7 documentation"));
|
|
185
|
+
console.log(chalk_1.default.magenta(` 🤖 Enhanced using Context7 MCP tools`));
|
|
186
|
+
};
|
|
187
|
+
if (options.taskId) {
|
|
188
|
+
await enhanceSingleTask(options.taskId);
|
|
189
|
+
}
|
|
190
|
+
else if (options.all) {
|
|
191
|
+
const allTasks = await tasks_1.taskService.listTasks({});
|
|
192
|
+
if (allTasks.length === 0) {
|
|
193
|
+
console.log(chalk_1.default.yellow("No tasks found to enhance."));
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
console.log(chalk_1.default.blue(`🤖 Enhancing ${allTasks.length} tasks in order...`));
|
|
197
|
+
for (let i = 0; i < allTasks.length; i++) {
|
|
198
|
+
const task = allTasks[i];
|
|
199
|
+
console.log(chalk_1.default.cyan(`\n[${i + 1}/${allTasks.length}] Enhancing: ${task.title} (${task.id})`));
|
|
200
|
+
try {
|
|
201
|
+
await enhanceSingleTask(task.id);
|
|
202
|
+
console.log(chalk_1.default.green(`✓ Enhanced task ${task.id}`));
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
console.log(chalk_1.default.red(`❌ Failed to enhance task ${task.id}: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
console.log(chalk_1.default.green(`\n✓ Bulk enhancement complete! Processed ${allTasks.length} tasks.`));
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
(0, progress_1.displayError)(error);
|
|
213
|
+
process.exit(1);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
// Split task into subtasks
|
|
217
|
+
exports.tasksCommand
|
|
218
|
+
.command("split")
|
|
219
|
+
.description("Split a task into smaller subtasks using AI")
|
|
220
|
+
.option("--task-id <id>", "Task ID to split")
|
|
221
|
+
.option("--all", "Split all existing tasks that don't have subtasks")
|
|
222
|
+
.option("--stream", "Show streaming AI output during breakdown")
|
|
223
|
+
.option("--ai-provider <provider>", "AI provider override")
|
|
224
|
+
.option("--ai-model <model>", "AI model override")
|
|
225
|
+
.option("--ai-key <key>", "AI API key override")
|
|
226
|
+
.option("--ai-provider-url <url>", "AI provider URL override")
|
|
227
|
+
.option("--reasoning <tokens>", "Enable reasoning for OpenRouter models (max reasoning tokens)")
|
|
228
|
+
.action(async (options) => {
|
|
229
|
+
try {
|
|
230
|
+
if (!options.taskId && !options.all) {
|
|
231
|
+
throw new Error("Either --task-id or --all must be specified");
|
|
232
|
+
}
|
|
233
|
+
if (options.taskId && options.all) {
|
|
234
|
+
throw new Error("Cannot specify both --task-id and --all");
|
|
235
|
+
}
|
|
236
|
+
const splitSingleTask = async (taskId) => {
|
|
237
|
+
const streamingOptions = (0, streaming_options_1.createStreamingOptions)(options.stream, "Task breakdown");
|
|
238
|
+
try {
|
|
239
|
+
const result = await tasks_1.taskService.splitTask(taskId, {
|
|
240
|
+
aiProvider: options.aiProvider,
|
|
241
|
+
aiModel: options.aiModel,
|
|
242
|
+
aiKey: options.aiKey,
|
|
243
|
+
aiProviderUrl: options.aiProviderUrl,
|
|
244
|
+
aiReasoning: options.reasoning,
|
|
245
|
+
}, undefined, undefined, streamingOptions, {
|
|
246
|
+
onProgress: progress_1.displayProgress,
|
|
247
|
+
onError: progress_1.displayError,
|
|
248
|
+
});
|
|
249
|
+
(0, task_1.displaySubtaskCreation)(result.subtasks);
|
|
250
|
+
// Display AI metadata
|
|
251
|
+
console.log(chalk_1.default.gray(`\n📊 AI Splitting Details:`));
|
|
252
|
+
console.log(chalk_1.default.gray(` Provider: ${result.metadata.aiProvider}`));
|
|
253
|
+
console.log(chalk_1.default.gray(` Model: ${result.metadata.aiModel}`));
|
|
254
|
+
console.log(chalk_1.default.gray(` Subtasks created: ${result.subtasks.length}`));
|
|
255
|
+
console.log(chalk_1.default.gray(` Confidence: ${result.metadata.confidence ? (result.metadata.confidence * 100).toFixed(1) : "N/A"}%`));
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
if (error instanceof Error && error.message.includes("already has")) {
|
|
259
|
+
console.log(chalk_1.default.yellow(`⚠️ ${error.message}`));
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
throw error;
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
if (options.taskId) {
|
|
266
|
+
await splitSingleTask(options.taskId);
|
|
267
|
+
}
|
|
268
|
+
else if (options.all) {
|
|
269
|
+
const allTasks = await tasks_1.taskService.listTasks({});
|
|
270
|
+
if (allTasks.length === 0) {
|
|
271
|
+
console.log(chalk_1.default.yellow("No tasks found to split."));
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
console.log(chalk_1.default.blue(`🔧 Splitting ${allTasks.length} tasks...`));
|
|
275
|
+
for (let i = 0; i < allTasks.length; i++) {
|
|
276
|
+
const task = allTasks[i];
|
|
277
|
+
console.log(chalk_1.default.cyan(`\n[${i + 1}/${allTasks.length}] Splitting: ${task.title}`));
|
|
278
|
+
try {
|
|
279
|
+
await splitSingleTask(task.id);
|
|
280
|
+
}
|
|
281
|
+
catch (error) {
|
|
282
|
+
console.log(chalk_1.default.red(`❌ Failed to split task ${task.id}: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
console.log(chalk_1.default.green(`\n✓ Bulk splitting complete! Processed ${allTasks.length} tasks.`));
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
catch (error) {
|
|
289
|
+
(0, progress_1.displayError)(error);
|
|
290
|
+
process.exit(1);
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
// Plan task implementation
|
|
294
|
+
exports.tasksCommand
|
|
295
|
+
.command("plan")
|
|
296
|
+
.description("Create detailed implementation plan for a task or subtask")
|
|
297
|
+
.requiredOption("--id <id>", "Task or subtask ID to plan")
|
|
298
|
+
.option("--stream", "Show streaming AI output during planning")
|
|
299
|
+
.option("--ai-provider <provider>", "AI provider override")
|
|
300
|
+
.option("--ai-model <model>", "AI model override")
|
|
301
|
+
.option("--ai-key <key>", "AI API key override")
|
|
302
|
+
.option("--ai-provider-url <url>", "AI provider URL override")
|
|
303
|
+
.option("--reasoning <tokens>", "Enable reasoning for OpenRouter models (max reasoning tokens)")
|
|
304
|
+
.action(async (options) => {
|
|
305
|
+
try {
|
|
306
|
+
const streamingOptions = (0, streaming_options_1.createStreamingOptions)(options.stream, "Planning");
|
|
307
|
+
const result = await tasks_1.taskService.planTask(options.id, {
|
|
308
|
+
aiProvider: options.aiProvider,
|
|
309
|
+
aiModel: options.aiModel,
|
|
310
|
+
aiKey: options.aiKey,
|
|
311
|
+
aiProviderUrl: options.aiProviderUrl,
|
|
312
|
+
aiReasoning: options.reasoning,
|
|
313
|
+
}, streamingOptions, {
|
|
314
|
+
onProgress: progress_1.displayProgress,
|
|
315
|
+
onError: progress_1.displayError,
|
|
316
|
+
});
|
|
317
|
+
// Display the plan
|
|
318
|
+
(0, plan_1.displayPlanCreation)(options.id, result.task.title);
|
|
319
|
+
console.log(chalk_1.default.cyan(result.plan));
|
|
320
|
+
}
|
|
321
|
+
catch (error) {
|
|
322
|
+
(0, progress_1.displayError)(error);
|
|
323
|
+
process.exit(1);
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
// Get plan command
|
|
327
|
+
exports.tasksCommand
|
|
328
|
+
.command("get-plan")
|
|
329
|
+
.description("View existing implementation plan for a task or subtask")
|
|
330
|
+
.requiredOption("--id <id>", "Task or subtask ID")
|
|
331
|
+
.action(async (options) => {
|
|
332
|
+
try {
|
|
333
|
+
const plan = await tasks_1.taskService.getTaskPlan(options.id);
|
|
334
|
+
if (!plan) {
|
|
335
|
+
console.log(chalk_1.default.yellow(`⚠️ No plan found for task/subtask ${options.id}`));
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
const task = await tasks_1.taskService.getTask(options.id);
|
|
339
|
+
const taskTitle = task ? task.title : options.id;
|
|
340
|
+
(0, plan_1.displayPlanView)(taskTitle, options.id, plan.plan, plan.createdAt, plan.updatedAt);
|
|
341
|
+
}
|
|
342
|
+
catch (error) {
|
|
343
|
+
(0, progress_1.displayError)(error);
|
|
344
|
+
process.exit(1);
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
// List plans command
|
|
348
|
+
exports.tasksCommand
|
|
349
|
+
.command("list-plan")
|
|
350
|
+
.description("List all available implementation plans")
|
|
351
|
+
.action(async () => {
|
|
352
|
+
try {
|
|
353
|
+
const plans = await tasks_1.taskService.listTaskPlans();
|
|
354
|
+
// Get task titles for each plan
|
|
355
|
+
const plansWithTitles = await Promise.all(plans.map(async (plan) => {
|
|
356
|
+
const task = await tasks_1.taskService.getTask(plan.taskId);
|
|
357
|
+
return {
|
|
358
|
+
...plan,
|
|
359
|
+
taskTitle: task ? task.title : plan.taskId,
|
|
360
|
+
};
|
|
361
|
+
}));
|
|
362
|
+
(0, plan_1.displayPlanList)(plansWithTitles);
|
|
363
|
+
}
|
|
364
|
+
catch (error) {
|
|
365
|
+
(0, progress_1.displayError)(error);
|
|
366
|
+
process.exit(1);
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
// Update task command
|
|
370
|
+
exports.tasksCommand
|
|
371
|
+
.command("update")
|
|
372
|
+
.description("Update an existing task")
|
|
373
|
+
.requiredOption("--id <id>", "Task ID to update")
|
|
374
|
+
.option("--title <title>", "New task title")
|
|
375
|
+
.option("--description <description>", "New task description")
|
|
376
|
+
.option("--status <status>", "New status (todo/in-progress/completed)")
|
|
377
|
+
.option("--effort <effort>", "New estimated effort (small/medium/large)")
|
|
378
|
+
.option("--tags <tags>", "New tags (comma-separated)")
|
|
379
|
+
.action(async (options) => {
|
|
380
|
+
try {
|
|
381
|
+
const { id, ...updates } = options;
|
|
382
|
+
if (Object.keys(updates).length === 0) {
|
|
383
|
+
throw new Error("At least one field must be specified for update");
|
|
384
|
+
}
|
|
385
|
+
const updatedTask = await tasks_1.taskService.updateTask(id, {
|
|
386
|
+
title: updates.title,
|
|
387
|
+
description: updates.description,
|
|
388
|
+
status: updates.status,
|
|
389
|
+
effort: updates.effort,
|
|
390
|
+
tags: updates.tags,
|
|
391
|
+
});
|
|
392
|
+
(0, task_1.displayTaskUpdate)(updatedTask, updates);
|
|
393
|
+
}
|
|
394
|
+
catch (error) {
|
|
395
|
+
(0, progress_1.displayError)(error);
|
|
396
|
+
process.exit(1);
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
// Delete task command
|
|
400
|
+
exports.tasksCommand
|
|
401
|
+
.command("delete")
|
|
402
|
+
.description("Delete a task")
|
|
403
|
+
.requiredOption("--id <id>", "Task ID to delete")
|
|
404
|
+
.option("--force", "Skip confirmation and delete anyway")
|
|
405
|
+
.option("--cascade", "Delete all subtasks as well")
|
|
406
|
+
.action(async (options) => {
|
|
407
|
+
try {
|
|
408
|
+
if (!options.force) {
|
|
409
|
+
const task = await tasks_1.taskService.getTask(options.id);
|
|
410
|
+
if (!task) {
|
|
411
|
+
throw new Error(`Task with ID ${options.id} not found`);
|
|
412
|
+
}
|
|
413
|
+
console.log(chalk_1.default.red(`\n⚠️ Are you sure you want to delete task: ${task.title} (${task.id})?`));
|
|
414
|
+
console.log(chalk_1.default.red("This action cannot be undone."));
|
|
415
|
+
// Simple confirmation - in a real CLI you might want a proper prompt
|
|
416
|
+
console.log(chalk_1.default.yellow("Use --force to confirm deletion."));
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
const result = await tasks_1.taskService.deleteTask(options.id, {
|
|
420
|
+
cascade: options.cascade,
|
|
421
|
+
force: options.force,
|
|
422
|
+
});
|
|
423
|
+
(0, task_1.displayTaskDelete)(result.deleted, result.orphanedSubtasks);
|
|
424
|
+
}
|
|
425
|
+
catch (error) {
|
|
426
|
+
(0, progress_1.displayError)(error);
|
|
427
|
+
process.exit(1);
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
// Set status command
|
|
431
|
+
exports.tasksCommand
|
|
432
|
+
.command("status")
|
|
433
|
+
.description("Set task status")
|
|
434
|
+
.requiredOption("--id <id>", "Task ID")
|
|
435
|
+
.requiredOption("--status <status>", "New status (todo/in-progress/completed)")
|
|
436
|
+
.action(async (options) => {
|
|
437
|
+
try {
|
|
438
|
+
const task = await tasks_1.taskService.getTask(options.id);
|
|
439
|
+
if (!task) {
|
|
440
|
+
throw new Error(`Task with ID ${options.id} not found`);
|
|
441
|
+
}
|
|
442
|
+
const oldStatus = task.status;
|
|
443
|
+
const updatedTask = await tasks_1.taskService.setTaskStatus(options.id, options.status);
|
|
444
|
+
(0, task_1.displayTaskStatusChange)(updatedTask, oldStatus, options.status);
|
|
445
|
+
}
|
|
446
|
+
catch (error) {
|
|
447
|
+
(0, progress_1.displayError)(error);
|
|
448
|
+
process.exit(1);
|
|
449
|
+
}
|
|
450
|
+
});
|
|
451
|
+
// Add tags command
|
|
452
|
+
exports.tasksCommand
|
|
453
|
+
.command("add-tags")
|
|
454
|
+
.description("Add tags to a task")
|
|
455
|
+
.requiredOption("--id <id>", "Task ID")
|
|
456
|
+
.requiredOption("--tags <tags>", "Tags to add (comma-separated)")
|
|
457
|
+
.action(async (options) => {
|
|
458
|
+
try {
|
|
459
|
+
const tags = options.tags.split(',').map((tag) => tag.trim());
|
|
460
|
+
const updatedTask = await tasks_1.taskService.addTags(options.id, tags);
|
|
461
|
+
(0, task_1.displayTagsUpdate)(updatedTask, tags, []);
|
|
462
|
+
}
|
|
463
|
+
catch (error) {
|
|
464
|
+
(0, progress_1.displayError)(error);
|
|
465
|
+
process.exit(1);
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
// Remove tags command
|
|
469
|
+
exports.tasksCommand
|
|
470
|
+
.command("remove-tags")
|
|
471
|
+
.description("Remove tags from a task")
|
|
472
|
+
.requiredOption("--id <id>", "Task ID")
|
|
473
|
+
.requiredOption("--tags <tags>", "Tags to remove (comma-separated)")
|
|
474
|
+
.action(async (options) => {
|
|
475
|
+
try {
|
|
476
|
+
const tags = options.tags.split(',').map((tag) => tag.trim());
|
|
477
|
+
const updatedTask = await tasks_1.taskService.removeTags(options.id, tags);
|
|
478
|
+
(0, task_1.displayTagsUpdate)(updatedTask, [], tags);
|
|
479
|
+
}
|
|
480
|
+
catch (error) {
|
|
481
|
+
(0, progress_1.displayError)(error);
|
|
482
|
+
process.exit(1);
|
|
483
|
+
}
|
|
484
|
+
});
|
|
485
|
+
// Delete plan command
|
|
486
|
+
exports.tasksCommand
|
|
487
|
+
.command("delete-plan")
|
|
488
|
+
.description("Delete implementation plan for a task")
|
|
489
|
+
.requiredOption("--id <id>", "Task ID")
|
|
490
|
+
.action(async (options) => {
|
|
491
|
+
try {
|
|
492
|
+
const success = await tasks_1.taskService.deleteTaskPlan(options.id);
|
|
493
|
+
(0, plan_1.displayPlanDeletion)(options.id, success);
|
|
494
|
+
}
|
|
495
|
+
catch (error) {
|
|
496
|
+
(0, progress_1.displayError)(error);
|
|
497
|
+
process.exit(1);
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
// List subtasks command
|
|
501
|
+
exports.tasksCommand
|
|
502
|
+
.command("subtasks")
|
|
503
|
+
.description("List subtasks for a task")
|
|
504
|
+
.requiredOption("--id <id>", "Parent task ID")
|
|
505
|
+
.action(async (options) => {
|
|
506
|
+
try {
|
|
507
|
+
const subtasks = await tasks_1.taskService.getSubtasks(options.id);
|
|
508
|
+
if (subtasks.length === 0) {
|
|
509
|
+
console.log(chalk_1.default.yellow(`No subtasks found for task ${options.id}`));
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
const parentTask = await tasks_1.taskService.getTask(options.id);
|
|
513
|
+
const parentTitle = parentTask ? parentTask.title : options.id;
|
|
514
|
+
console.log(chalk_1.default.blue(`\n📋 Subtasks for ${parentTitle} (${options.id}):`));
|
|
515
|
+
console.log("");
|
|
516
|
+
for (let i = 0; i < subtasks.length; i++) {
|
|
517
|
+
const subtask = subtasks[i];
|
|
518
|
+
await (0, task_1.displayTask)(subtask, { indent: ' ', showSubtasks: false });
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
catch (error) {
|
|
522
|
+
(0, progress_1.displayError)(error);
|
|
523
|
+
process.exit(1);
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
// Task tree command
|
|
527
|
+
exports.tasksCommand
|
|
528
|
+
.command("tree")
|
|
529
|
+
.description("Display hierarchical task tree")
|
|
530
|
+
.option("--id <id>", "Root task ID (optional - shows full tree if not specified)")
|
|
531
|
+
.action(async (options) => {
|
|
532
|
+
try {
|
|
533
|
+
const tasks = await tasks_1.taskService.getTaskTree(options.id);
|
|
534
|
+
await (0, task_1.displayTaskTree)(tasks, options.id);
|
|
535
|
+
}
|
|
536
|
+
catch (error) {
|
|
537
|
+
(0, progress_1.displayError)(error);
|
|
538
|
+
process.exit(1);
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
// Get next task command
|
|
542
|
+
exports.tasksCommand
|
|
543
|
+
.command("get-next")
|
|
544
|
+
.description("Get the next task to work on (defaults to hierarchical order)")
|
|
545
|
+
.option("--status <status>", "Filter by status (todo/in-progress)")
|
|
546
|
+
.option("--tag <tag>", "Filter by tag")
|
|
547
|
+
.option("--effort <effort>", "Filter by effort (small/medium/large)")
|
|
548
|
+
.option("--priority <priority>", "Sort priority (newest/oldest/effort)", "hierarchical")
|
|
549
|
+
.action(async (options) => {
|
|
550
|
+
try {
|
|
551
|
+
// Default to todo status if not specified
|
|
552
|
+
const searchOptions = {
|
|
553
|
+
...options,
|
|
554
|
+
status: options.status || "todo"
|
|
555
|
+
};
|
|
556
|
+
const nextTask = await tasks_1.taskService.getNextTask(searchOptions);
|
|
557
|
+
if (!nextTask) {
|
|
558
|
+
console.log(chalk_1.default.yellow("No tasks found matching the criteria."));
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
561
|
+
const criteria = [
|
|
562
|
+
searchOptions.status && `status: ${searchOptions.status}`,
|
|
563
|
+
options.tag && `tag: ${options.tag}`,
|
|
564
|
+
options.effort && `effort: ${options.effort}`,
|
|
565
|
+
options.priority && `priority: ${options.priority}`
|
|
566
|
+
].filter(Boolean).join(", ");
|
|
567
|
+
(0, task_1.displayNextTask)(nextTask, criteria || "next todo task");
|
|
568
|
+
}
|
|
569
|
+
catch (error) {
|
|
570
|
+
(0, progress_1.displayError)(error);
|
|
571
|
+
process.exit(1);
|
|
572
|
+
}
|
|
573
|
+
});
|
|
574
|
+
// Execute task command
|
|
575
|
+
exports.tasksCommand
|
|
576
|
+
.command("execute")
|
|
577
|
+
.description("Execute a task using an external coding assistant")
|
|
578
|
+
.requiredOption("--id <id>", "Task ID to execute")
|
|
579
|
+
.option("--tool <tool>", "External tool to use (opencode/claude/gemini/codex)", "opencode")
|
|
580
|
+
.option("--message <message>", "Custom message to send to the tool (uses task plan if not provided)")
|
|
581
|
+
.option("--dry", "Show what would be executed without running it")
|
|
582
|
+
.option("--validate <command>", "Validation command to run after execution (can be used multiple times)", (value, previous = []) => {
|
|
583
|
+
return [...previous, value];
|
|
584
|
+
})
|
|
585
|
+
.action(async (options) => {
|
|
586
|
+
try {
|
|
587
|
+
await (0, task_execution_1.executeTask)({
|
|
588
|
+
taskId: options.id,
|
|
589
|
+
tool: options.tool,
|
|
590
|
+
message: options.message,
|
|
591
|
+
dry: options.dry,
|
|
592
|
+
validate: options.validate || [],
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
catch (error) {
|
|
596
|
+
console.error(chalk_1.default.red("Execution failed:"), error instanceof Error ? error.message : "Unknown error");
|
|
597
|
+
process.exit(1);
|
|
598
|
+
}
|
|
599
|
+
});
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* task-o-matic CLI Logic
|
|
3
|
+
*
|
|
4
|
+
* This module contains the CLI setup and command definitions.
|
|
5
|
+
* It can be imported and used by the binary or for testing.
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from "commander";
|
|
8
|
+
declare const program: Command;
|
|
9
|
+
/**
|
|
10
|
+
* Run the CLI
|
|
11
|
+
* This is the main entry point for the CLI, called by the bin script
|
|
12
|
+
*/
|
|
13
|
+
export declare const runCLI: () => Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Export the program for testing purposes
|
|
16
|
+
*/
|
|
17
|
+
export { program };
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,QAAA,MAAM,OAAO,SAAgB,CAAC;AA6C9B;;;GAGG;AACH,eAAO,MAAM,MAAM,qBAUlB,CAAC;AAEF;;GAEG;AACH,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* task-o-matic CLI Logic
|
|
4
|
+
*
|
|
5
|
+
* This module contains the CLI setup and command definitions.
|
|
6
|
+
* It can be imported and used by the binary or for testing.
|
|
7
|
+
*/
|
|
8
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.program = exports.runCLI = void 0;
|
|
13
|
+
const commander_1 = require("commander");
|
|
14
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
15
|
+
const config_1 = require("./commands/config");
|
|
16
|
+
const tasks_1 = require("./commands/tasks");
|
|
17
|
+
const prd_1 = require("./commands/prd");
|
|
18
|
+
const init_1 = require("./commands/init");
|
|
19
|
+
const prompt_1 = require("./commands/prompt");
|
|
20
|
+
const config_2 = require("./lib/config");
|
|
21
|
+
const program = new commander_1.Command();
|
|
22
|
+
exports.program = program;
|
|
23
|
+
program
|
|
24
|
+
.name("task-o-matic")
|
|
25
|
+
.description("AI-powered Task Management CLI for Single Projects")
|
|
26
|
+
.version("0.1.0")
|
|
27
|
+
.option("-v, --verbose", "Enable verbose logging");
|
|
28
|
+
// Add subcommands
|
|
29
|
+
program.addCommand(config_1.configCommand);
|
|
30
|
+
program.addCommand(tasks_1.tasksCommand);
|
|
31
|
+
program.addCommand(prd_1.prdCommand);
|
|
32
|
+
program.addCommand(prompt_1.promptCommand);
|
|
33
|
+
program.addCommand(init_1.initCommand);
|
|
34
|
+
// Default action - show help
|
|
35
|
+
program.action(() => {
|
|
36
|
+
console.log(chalk_1.default.blue("🚀 AI-Powered Task Management CLI"));
|
|
37
|
+
console.log(chalk_1.default.cyan(`Project Directory: ${config_2.configManager.getTaskOMaticDir()}`));
|
|
38
|
+
console.log("");
|
|
39
|
+
console.log(chalk_1.default.yellow("Quick Start:"));
|
|
40
|
+
console.log(" 1. Initialize project: task-o-matic init");
|
|
41
|
+
console.log(" 2. Configure AI provider: task-o-matic config set-ai-provider openrouter anthropic/claude-3.5-sonnet");
|
|
42
|
+
console.log(' 3. Create a task: task-o-matic tasks create --title "Your first task"');
|
|
43
|
+
console.log(" 4. List tasks: task-o-matic tasks list");
|
|
44
|
+
console.log("");
|
|
45
|
+
program.outputHelp();
|
|
46
|
+
});
|
|
47
|
+
// Error handling
|
|
48
|
+
program.on("command:*", (operands) => {
|
|
49
|
+
console.error(chalk_1.default.red(`Unknown command: ${operands[0]}`));
|
|
50
|
+
console.log(chalk_1.default.blue("Available commands: config, tasks, prd, prompt, init"));
|
|
51
|
+
console.log(chalk_1.default.blue("Use --help for available commands"));
|
|
52
|
+
process.exit(1);
|
|
53
|
+
});
|
|
54
|
+
/**
|
|
55
|
+
* Run the CLI
|
|
56
|
+
* This is the main entry point for the CLI, called by the bin script
|
|
57
|
+
*/
|
|
58
|
+
const runCLI = async () => {
|
|
59
|
+
try {
|
|
60
|
+
await program.parseAsync(process.argv);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
console.error(chalk_1.default.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
exports.runCLI = runCLI;
|