task-o-matic 0.0.3 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/README.md +96 -40
  2. package/dist/cli/bin.js +0 -0
  3. package/dist/commands/tasks/create.d.ts +3 -0
  4. package/dist/commands/tasks/create.d.ts.map +1 -0
  5. package/dist/commands/tasks/create.js +58 -0
  6. package/dist/commands/tasks/delete.d.ts +3 -0
  7. package/dist/commands/tasks/delete.d.ts.map +1 -0
  8. package/dist/commands/tasks/delete.js +40 -0
  9. package/dist/commands/tasks/document.d.ts +5 -0
  10. package/dist/commands/tasks/document.d.ts.map +1 -0
  11. package/dist/commands/tasks/document.js +118 -0
  12. package/dist/commands/tasks/enhance.d.ts +3 -0
  13. package/dist/commands/tasks/enhance.d.ts.map +1 -0
  14. package/dist/commands/tasks/enhance.js +86 -0
  15. package/dist/commands/tasks/execute.d.ts +3 -0
  16. package/dist/commands/tasks/execute.d.ts.map +1 -0
  17. package/dist/commands/tasks/execute.js +33 -0
  18. package/dist/commands/tasks/index.d.ts +16 -0
  19. package/dist/commands/tasks/index.d.ts.map +1 -0
  20. package/dist/commands/tasks/index.js +31 -0
  21. package/dist/commands/tasks/list.d.ts +3 -0
  22. package/dist/commands/tasks/list.d.ts.map +1 -0
  23. package/dist/commands/tasks/list.js +27 -0
  24. package/dist/commands/tasks/next.d.ts +3 -0
  25. package/dist/commands/tasks/next.d.ts.map +1 -0
  26. package/dist/commands/tasks/next.js +44 -0
  27. package/dist/commands/tasks/plan.d.ts +7 -0
  28. package/dist/commands/tasks/plan.d.ts.map +1 -0
  29. package/dist/commands/tasks/plan.js +131 -0
  30. package/dist/commands/tasks/show.d.ts +3 -0
  31. package/dist/commands/tasks/show.d.ts.map +1 -0
  32. package/dist/commands/tasks/show.js +23 -0
  33. package/dist/commands/tasks/split.d.ts +3 -0
  34. package/dist/commands/tasks/split.d.ts.map +1 -0
  35. package/dist/commands/tasks/split.js +95 -0
  36. package/dist/commands/tasks/status.d.ts +3 -0
  37. package/dist/commands/tasks/status.d.ts.map +1 -0
  38. package/dist/commands/tasks/status.js +26 -0
  39. package/dist/commands/tasks/subtasks.d.ts +3 -0
  40. package/dist/commands/tasks/subtasks.d.ts.map +1 -0
  41. package/dist/commands/tasks/subtasks.js +35 -0
  42. package/dist/commands/tasks/tags.d.ts +4 -0
  43. package/dist/commands/tasks/tags.d.ts.map +1 -0
  44. package/dist/commands/tasks/tags.js +37 -0
  45. package/dist/commands/tasks/tree.d.ts +3 -0
  46. package/dist/commands/tasks/tree.d.ts.map +1 -0
  47. package/dist/commands/tasks/tree.js +20 -0
  48. package/dist/commands/tasks/update.d.ts +3 -0
  49. package/dist/commands/tasks/update.d.ts.map +1 -0
  50. package/dist/commands/tasks/update.js +35 -0
  51. package/dist/commands/tasks.d.ts.map +1 -1
  52. package/dist/commands/tasks.js +23 -686
  53. package/dist/commands/workflow.d.ts +4 -0
  54. package/dist/commands/workflow.d.ts.map +1 -0
  55. package/dist/commands/workflow.js +503 -0
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +3 -1
  58. package/dist/lib/ai-service/ai-operations.d.ts.map +1 -1
  59. package/dist/lib/ai-service/ai-operations.js +54 -22
  60. package/dist/lib/ai-service/research-tools.d.ts.map +1 -1
  61. package/dist/lib/ai-service/research-tools.js +2 -2
  62. package/dist/lib/better-t-stack-cli.d.ts +1 -0
  63. package/dist/lib/better-t-stack-cli.d.ts.map +1 -1
  64. package/dist/lib/better-t-stack-cli.js +8 -2
  65. package/dist/lib/context-builder.d.ts +2 -1
  66. package/dist/lib/context-builder.d.ts.map +1 -1
  67. package/dist/lib/context-builder.js +3 -8
  68. package/dist/lib/hooks/logger.d.ts +2 -0
  69. package/dist/lib/hooks/logger.d.ts.map +1 -0
  70. package/dist/lib/hooks/logger.js +27 -0
  71. package/dist/lib/hooks.d.ts +64 -0
  72. package/dist/lib/hooks.d.ts.map +1 -0
  73. package/dist/lib/hooks.js +60 -0
  74. package/dist/lib/index.d.ts +18 -17
  75. package/dist/lib/index.d.ts.map +1 -1
  76. package/dist/lib/index.js +3 -3
  77. package/dist/lib/prompt-builder.d.ts.map +1 -1
  78. package/dist/lib/prompt-builder.js +16 -8
  79. package/dist/lib/{storage.d.ts → storage/file-system.d.ts} +4 -3
  80. package/dist/lib/storage/file-system.d.ts.map +1 -0
  81. package/dist/lib/{storage.js → storage/file-system.js} +141 -152
  82. package/dist/lib/storage/types.d.ts +43 -0
  83. package/dist/lib/storage/types.d.ts.map +1 -0
  84. package/dist/lib/storage/types.js +2 -0
  85. package/dist/lib/task-execution.d.ts.map +1 -1
  86. package/dist/lib/task-execution.js +22 -3
  87. package/dist/mcp/server.js +0 -0
  88. package/dist/prompts/workflow-assistance.d.ts +32 -0
  89. package/dist/prompts/workflow-assistance.d.ts.map +1 -0
  90. package/dist/prompts/workflow-assistance.js +130 -0
  91. package/dist/services/tasks.d.ts +4 -6
  92. package/dist/services/tasks.d.ts.map +1 -1
  93. package/dist/services/tasks.js +115 -96
  94. package/dist/services/workflow-ai-assistant.d.ts +74 -0
  95. package/dist/services/workflow-ai-assistant.d.ts.map +1 -0
  96. package/dist/services/workflow-ai-assistant.js +223 -0
  97. package/dist/test/hooks.test.d.ts +2 -0
  98. package/dist/test/hooks.test.d.ts.map +1 -0
  99. package/dist/test/hooks.test.js +58 -0
  100. package/dist/test/storage.test.js +16 -16
  101. package/dist/types/options.d.ts +35 -0
  102. package/dist/types/options.d.ts.map +1 -1
  103. package/dist/utils/ai-service-factory.d.ts +5 -5
  104. package/dist/utils/ai-service-factory.d.ts.map +1 -1
  105. package/dist/utils/ai-service-factory.js +4 -3
  106. package/dist/utils/workflow-prompts.d.ts +17 -0
  107. package/dist/utils/workflow-prompts.d.ts.map +1 -0
  108. package/dist/utils/workflow-prompts.js +88 -0
  109. package/package.json +4 -4
  110. package/dist/lib/storage.d.ts.map +0 -1
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ export declare const workflowCommand: Command;
4
+ //# sourceMappingURL=workflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../src/commands/workflow.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2BpC,eAAO,MAAM,eAAe,SAiExB,CAAC"}
@@ -0,0 +1,503 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.workflowCommand = void 0;
8
+ const commander_1 = require("commander");
9
+ const chalk_1 = __importDefault(require("chalk"));
10
+ const fs_1 = require("fs");
11
+ const path_1 = require("path");
12
+ const config_1 = require("../lib/config");
13
+ const better_t_stack_cli_1 = require("../lib/better-t-stack-cli");
14
+ const prd_1 = require("../services/prd");
15
+ const tasks_1 = require("../services/tasks");
16
+ const workflow_ai_assistant_1 = require("../services/workflow-ai-assistant");
17
+ const workflow_prompts_1 = require("../utils/workflow-prompts");
18
+ const streaming_options_1 = require("../utils/streaming-options");
19
+ const progress_1 = require("../cli/display/progress");
20
+ exports.workflowCommand = new commander_1.Command("workflow")
21
+ .description("Interactive workflow for complete project setup and task management")
22
+ .option("--stream", "Show streaming AI output")
23
+ .option("--ai-provider <provider>", "AI provider override")
24
+ .option("--ai-model <model>", "AI model override")
25
+ .option("--ai-key <key>", "AI API key override")
26
+ .action(async (options) => {
27
+ try {
28
+ console.log(chalk_1.default.blue.bold("\n🚀 Task-O-Matic Interactive Workflow\n"));
29
+ console.log(chalk_1.default.gray("This wizard will guide you through:"));
30
+ console.log(chalk_1.default.gray(" 1. Project initialization & bootstrap"));
31
+ console.log(chalk_1.default.gray(" 2. PRD definition"));
32
+ console.log(chalk_1.default.gray(" 3. PRD refinement"));
33
+ console.log(chalk_1.default.gray(" 4. Task generation"));
34
+ console.log(chalk_1.default.gray(" 5. Task splitting\n"));
35
+ const state = {
36
+ initialized: false,
37
+ currentStep: "initialize",
38
+ projectDir: process.cwd(),
39
+ };
40
+ // Store AI options for later use
41
+ const aiOptions = {
42
+ aiProvider: options.aiProvider,
43
+ aiModel: options.aiModel,
44
+ aiKey: options.aiKey,
45
+ };
46
+ const streamingOptions = (0, streaming_options_1.createStreamingOptions)(options.stream, "Workflow");
47
+ // Step 1: Initialize/Bootstrap
48
+ await stepInitialize(state, aiOptions, streamingOptions);
49
+ // Step 2: Define PRD
50
+ await stepDefinePRD(state, aiOptions, streamingOptions);
51
+ // Step 3: Refine PRD
52
+ await stepRefinePRD(state, aiOptions, streamingOptions);
53
+ // Step 4: Generate Tasks
54
+ await stepGenerateTasks(state, aiOptions, streamingOptions);
55
+ // Step 5: Split Tasks
56
+ await stepSplitTasks(state, aiOptions, streamingOptions);
57
+ // Complete
58
+ state.currentStep = "complete";
59
+ console.log(chalk_1.default.green.bold("\n✅ Workflow Complete!\n"));
60
+ console.log(chalk_1.default.cyan("Next steps:"));
61
+ console.log(chalk_1.default.gray(" • Review your tasks: task-o-matic tasks list"));
62
+ console.log(chalk_1.default.gray(" • View task tree: task-o-matic tasks tree"));
63
+ console.log(chalk_1.default.gray(" • Get next task: task-o-matic tasks next"));
64
+ console.log(chalk_1.default.gray(" • Execute a task: task-o-matic tasks execute <task-id>\n"));
65
+ }
66
+ catch (error) {
67
+ (0, progress_1.displayError)(error);
68
+ process.exit(1);
69
+ }
70
+ });
71
+ /**
72
+ * Step 1: Initialize/Bootstrap
73
+ */
74
+ async function stepInitialize(state, aiOptions, streamingOptions) {
75
+ console.log(chalk_1.default.blue.bold("\n📦 Step 1: Project Initialization\n"));
76
+ // Check if already initialized in current directory
77
+ const taskOMaticDir = config_1.configManager.getTaskOMaticDir();
78
+ const alreadyInitialized = (0, fs_1.existsSync)(taskOMaticDir);
79
+ if (alreadyInitialized) {
80
+ console.log(chalk_1.default.yellow("✓ Project already initialized"));
81
+ const useExisting = await (0, workflow_prompts_1.confirmPrompt)("Use existing configuration?", true);
82
+ if (useExisting) {
83
+ state.initialized = true;
84
+ state.currentStep = "define-prd";
85
+ return;
86
+ }
87
+ }
88
+ const shouldInitialize = await (0, workflow_prompts_1.confirmPrompt)("Initialize a new task-o-matic project?", true);
89
+ if (!shouldInitialize) {
90
+ console.log(chalk_1.default.yellow("⚠ Skipping initialization"));
91
+ state.initialized = false;
92
+ state.currentStep = "define-prd";
93
+ return;
94
+ }
95
+ const projectName = await (0, workflow_prompts_1.textInputPrompt)("What is the name of your project?", "my-app");
96
+ // Choose initialization method
97
+ let initMethod = await (0, workflow_prompts_1.selectPrompt)("How would you like to configure your project?", [
98
+ { name: "Quick start (recommended defaults)", value: "quick" },
99
+ { name: "Custom configuration", value: "custom" },
100
+ { name: "AI-assisted (describe your project)", value: "ai" },
101
+ ]);
102
+ let config;
103
+ if (initMethod === "ai") {
104
+ console.log(chalk_1.default.cyan("\n🤖 AI-Assisted Configuration\n"));
105
+ const description = await (0, workflow_prompts_1.textInputPrompt)("Describe your project (e.g., 'A SaaS app for team collaboration with real-time features'):");
106
+ console.log(chalk_1.default.gray("\n Analyzing your requirements...\n"));
107
+ config = await workflow_ai_assistant_1.workflowAIAssistant.assistInitConfig({
108
+ userDescription: description,
109
+ aiOptions,
110
+ streamingOptions,
111
+ });
112
+ // Override AI's project name with user's choice if they provided one (though we just asked for it, so we should use it)
113
+ config.projectName = projectName;
114
+ console.log(chalk_1.default.green("\n✓ AI Recommendations:"));
115
+ console.log(chalk_1.default.gray(` Project: ${config.projectName}`));
116
+ console.log(chalk_1.default.gray(` AI Provider: ${config.aiProvider}`));
117
+ console.log(chalk_1.default.gray(` Frontend: ${config.frontend || "none"}`));
118
+ console.log(chalk_1.default.gray(` Backend: ${config.backend || "none"}`));
119
+ console.log(chalk_1.default.gray(` Database: ${config.database || "none"}`));
120
+ console.log(chalk_1.default.gray(` Auth: ${config.auth ? "yes" : "no"}`));
121
+ if (config.reasoning) {
122
+ console.log(chalk_1.default.gray(`\n ${config.reasoning}\n`));
123
+ }
124
+ const acceptRecommendation = await (0, workflow_prompts_1.confirmPrompt)("Accept these recommendations?", true);
125
+ if (!acceptRecommendation) {
126
+ console.log(chalk_1.default.yellow("⚠ Falling back to custom configuration"));
127
+ initMethod = "custom";
128
+ }
129
+ }
130
+ if (initMethod === "quick") {
131
+ config = {
132
+ projectName: projectName,
133
+ aiProvider: "openrouter",
134
+ aiModel: "anthropic/claude-3.5-sonnet",
135
+ frontend: "next",
136
+ backend: "hono",
137
+ database: "sqlite",
138
+ auth: true,
139
+ reasoning: "Modern, well-supported stack",
140
+ };
141
+ }
142
+ else if (initMethod === "custom") {
143
+ config = {
144
+ projectName: projectName,
145
+ aiProvider: await (0, workflow_prompts_1.selectPrompt)("AI Provider:", [
146
+ "openrouter",
147
+ "anthropic",
148
+ "openai",
149
+ "custom",
150
+ ]),
151
+ aiModel: await (0, workflow_prompts_1.textInputPrompt)("AI Model:", "anthropic/claude-3.5-sonnet"),
152
+ };
153
+ const shouldBootstrap = await (0, workflow_prompts_1.confirmPrompt)("Bootstrap with Better-T-Stack?", true);
154
+ if (shouldBootstrap) {
155
+ config.frontend = await (0, workflow_prompts_1.selectPrompt)("Frontend framework:", [
156
+ "next",
157
+ "tanstack-router",
158
+ "react-router",
159
+ "vite-react",
160
+ "remix",
161
+ ]);
162
+ config.backend = await (0, workflow_prompts_1.selectPrompt)("Backend framework:", [
163
+ "hono",
164
+ "express",
165
+ "elysia",
166
+ "fastify",
167
+ ]);
168
+ config.database = await (0, workflow_prompts_1.selectPrompt)("Database:", [
169
+ "sqlite",
170
+ "postgres",
171
+ "mysql",
172
+ "mongodb",
173
+ "turso",
174
+ "neon",
175
+ ]);
176
+ config.auth = await (0, workflow_prompts_1.confirmPrompt)("Include authentication?", true);
177
+ }
178
+ }
179
+ // Bootstrap Logic
180
+ let projectDir = process.cwd();
181
+ let didBootstrap = false;
182
+ if (config.frontend || config.backend) {
183
+ const shouldBootstrap = await (0, workflow_prompts_1.confirmPrompt)("Bootstrap project now?", true);
184
+ if (shouldBootstrap) {
185
+ console.log(chalk_1.default.cyan("\n Bootstrapping with Better-T-Stack...\n"));
186
+ try {
187
+ const result = await (0, better_t_stack_cli_1.runBetterTStackCLI)({
188
+ projectName: config.projectName,
189
+ frontend: config.frontend || "next",
190
+ backend: config.backend || "hono",
191
+ database: config.database || "sqlite",
192
+ noAuth: !config.auth,
193
+ // Default values for required fields that might be missing from simple config
194
+ orm: "drizzle",
195
+ packageManager: "npm",
196
+ runtime: "node",
197
+ noInstall: false,
198
+ noGit: false,
199
+ }, process.cwd());
200
+ if (result.success) {
201
+ console.log(chalk_1.default.green(`\n✓ ${result.message}\n`));
202
+ didBootstrap = true;
203
+ // Update project directory if a new directory was created
204
+ if (result.projectPath) {
205
+ projectDir = (0, path_1.resolve)(process.cwd(), result.projectPath);
206
+ console.log(chalk_1.default.cyan(` 📂 Switching to project directory: ${projectDir}\n`));
207
+ process.chdir(projectDir);
208
+ config_1.configManager.setWorkingDirectory(projectDir);
209
+ state.projectDir = projectDir;
210
+ }
211
+ }
212
+ else {
213
+ console.log(chalk_1.default.red(`\n✗ Bootstrap failed: ${result.message}\n`));
214
+ console.log(chalk_1.default.yellow("You can try running 'task-o-matic init bootstrap' manually later.\n"));
215
+ }
216
+ }
217
+ catch (error) {
218
+ console.log(chalk_1.default.red(`\n✗ Bootstrap failed: ${error}\n`));
219
+ }
220
+ }
221
+ }
222
+ // Initialize task-o-matic in the correct directory (projectDir)
223
+ console.log(chalk_1.default.cyan("\n Initializing task-o-matic...\n"));
224
+ // Re-check task-o-matic dir in the new location
225
+ const newTaskOMaticDir = (0, path_1.join)(projectDir, ".task-o-matic");
226
+ if (!(0, fs_1.existsSync)(newTaskOMaticDir)) {
227
+ (0, fs_1.mkdirSync)(newTaskOMaticDir, { recursive: true });
228
+ ["tasks", "prd", "logs"].forEach((dir) => {
229
+ (0, fs_1.mkdirSync)((0, path_1.join)(newTaskOMaticDir, dir), { recursive: true });
230
+ });
231
+ }
232
+ // Handle .env configuration
233
+ const envPath = (0, path_1.join)(projectDir, ".env");
234
+ let envContent = "";
235
+ if ((0, fs_1.existsSync)(envPath)) {
236
+ envContent = (0, fs_1.readFileSync)(envPath, "utf-8");
237
+ }
238
+ // Check if we need to ask for API key
239
+ const providerKeyName = config.aiProvider === "openai"
240
+ ? "OPENAI_API_KEY"
241
+ : config.aiProvider === "anthropic"
242
+ ? "ANTHROPIC_API_KEY"
243
+ : config.aiProvider === "openrouter"
244
+ ? "OPENROUTER_API_KEY"
245
+ : "AI_API_KEY";
246
+ // Check if key exists in current env OR in the target .env file
247
+ const hasKeyInEnv = process.env[providerKeyName] || envContent.includes(providerKeyName);
248
+ if (!hasKeyInEnv) {
249
+ console.log(chalk_1.default.yellow(`\n⚠️ No API key found for ${config.aiProvider}`));
250
+ const apiKey = await (0, workflow_prompts_1.textInputPrompt)(`Enter your ${config.aiProvider} API Key:`);
251
+ // Prepare .env content
252
+ let newEnvContent = envContent;
253
+ if (newEnvContent && !newEnvContent.endsWith("\n")) {
254
+ newEnvContent += "\n";
255
+ }
256
+ if (!newEnvContent.includes("AI_PROVIDER=")) {
257
+ newEnvContent += `AI_PROVIDER=${config.aiProvider}\n`;
258
+ }
259
+ if (!newEnvContent.includes("AI_MODEL=")) {
260
+ newEnvContent += `AI_MODEL=${config.aiModel}\n`;
261
+ }
262
+ if (!newEnvContent.includes(`${providerKeyName}=`)) {
263
+ newEnvContent += `${providerKeyName}=${apiKey}\n`;
264
+ }
265
+ (0, fs_1.writeFileSync)(envPath, newEnvContent);
266
+ console.log(chalk_1.default.green(`✓ Saved configuration to ${envPath}`));
267
+ // Update process.env for immediate use in this session
268
+ process.env[providerKeyName] = apiKey;
269
+ process.env.AI_PROVIDER = config.aiProvider;
270
+ process.env.AI_MODEL = config.aiModel;
271
+ }
272
+ // Save configuration
273
+ config_1.configManager.setConfig({
274
+ ai: {
275
+ provider: config.aiProvider, // Cast to satisfy AIProvider type
276
+ model: config.aiModel,
277
+ maxTokens: 32768,
278
+ temperature: 0.5,
279
+ apiKey: process.env[providerKeyName], // Ensure key is in config if needed
280
+ },
281
+ });
282
+ config_1.configManager.save();
283
+ console.log(chalk_1.default.green("✓ Project initialized"));
284
+ state.initialized = true;
285
+ state.projectName = config.projectName;
286
+ state.aiConfig = {
287
+ provider: config.aiProvider,
288
+ model: config.aiModel,
289
+ };
290
+ state.currentStep = "define-prd";
291
+ }
292
+ /**
293
+ * Step 2: Define PRD
294
+ */
295
+ async function stepDefinePRD(state, aiOptions, streamingOptions) {
296
+ console.log(chalk_1.default.blue.bold("\n📝 Step 2: Define PRD\n"));
297
+ const prdMethod = await (0, workflow_prompts_1.selectPrompt)("How would you like to define your PRD?", [
298
+ { name: "Upload existing file", value: "upload" },
299
+ { name: "Write manually (open editor)", value: "manual" },
300
+ { name: "AI-assisted creation", value: "ai" },
301
+ { name: "Skip (use existing PRD)", value: "skip" },
302
+ ]);
303
+ const taskOMaticDir = config_1.configManager.getTaskOMaticDir();
304
+ const prdDir = (0, path_1.join)(taskOMaticDir, "prd");
305
+ if (prdMethod === "skip") {
306
+ console.log(chalk_1.default.yellow("⚠ Skipping PRD definition"));
307
+ state.currentStep = "refine-prd";
308
+ return;
309
+ }
310
+ let prdContent = "";
311
+ let prdFilename = "prd.md";
312
+ if (prdMethod === "upload") {
313
+ const filePath = await (0, workflow_prompts_1.textInputPrompt)("Path to PRD file:");
314
+ if (!(0, fs_1.existsSync)(filePath)) {
315
+ console.log(chalk_1.default.red(`✗ File not found: ${filePath}`));
316
+ return stepDefinePRD(state, aiOptions, streamingOptions);
317
+ }
318
+ prdContent = (0, fs_1.readFileSync)(filePath, "utf-8");
319
+ prdFilename = filePath.split("/").pop() || "prd.md";
320
+ }
321
+ else if (prdMethod === "manual") {
322
+ console.log(chalk_1.default.gray("\n Opening editor...\n"));
323
+ prdContent = await (0, workflow_prompts_1.editorPrompt)("Write your PRD (save and close editor when done):", "# Product Requirements Document\n\n## Overview\n\n## Objectives\n\n## Features\n\n");
324
+ }
325
+ else if (prdMethod === "ai") {
326
+ console.log(chalk_1.default.cyan("\n🤖 AI-Assisted PRD Creation\n"));
327
+ const description = await (0, workflow_prompts_1.textInputPrompt)("Describe your product in detail:");
328
+ console.log(chalk_1.default.gray("\n Generating PRD...\n"));
329
+ prdContent = await workflow_ai_assistant_1.workflowAIAssistant.assistPRDCreation({
330
+ userDescription: description,
331
+ aiOptions,
332
+ streamingOptions,
333
+ });
334
+ console.log(chalk_1.default.green("\n✓ PRD generated"));
335
+ console.log(chalk_1.default.gray("\n" + prdContent.substring(0, 500) + "...\n"));
336
+ const acceptPRD = await (0, workflow_prompts_1.confirmPrompt)("Accept this PRD?", true);
337
+ if (!acceptPRD) {
338
+ console.log(chalk_1.default.yellow("⚠ Regenerating..."));
339
+ return stepDefinePRD(state, aiOptions, streamingOptions);
340
+ }
341
+ }
342
+ // Save PRD
343
+ const prdPath = (0, path_1.join)(prdDir, prdFilename);
344
+ (0, fs_1.writeFileSync)(prdPath, prdContent);
345
+ console.log(chalk_1.default.green(`✓ PRD saved to ${prdPath}`));
346
+ state.prdFile = prdPath;
347
+ state.prdContent = prdContent;
348
+ state.currentStep = "refine-prd";
349
+ }
350
+ /**
351
+ * Step 3: Refine PRD
352
+ */
353
+ async function stepRefinePRD(state, aiOptions, streamingOptions) {
354
+ console.log(chalk_1.default.blue.bold("\n✨ Step 3: Refine PRD\n"));
355
+ if (!state.prdFile) {
356
+ console.log(chalk_1.default.yellow("⚠ No PRD file found, skipping refinement"));
357
+ state.currentStep = "generate-tasks";
358
+ return;
359
+ }
360
+ const shouldRefine = await (0, workflow_prompts_1.confirmPrompt)("Refine your PRD?", false);
361
+ if (!shouldRefine) {
362
+ console.log(chalk_1.default.gray(" Skipping refinement"));
363
+ state.currentStep = "generate-tasks";
364
+ return;
365
+ }
366
+ const refineMethod = await (0, workflow_prompts_1.selectPrompt)("How would you like to refine?", [
367
+ { name: "Manual editing (open editor)", value: "manual" },
368
+ { name: "AI-assisted refinement", value: "ai" },
369
+ { name: "Skip", value: "skip" },
370
+ ]);
371
+ if (refineMethod === "skip") {
372
+ state.currentStep = "generate-tasks";
373
+ return;
374
+ }
375
+ let refinedContent = state.prdContent || (0, fs_1.readFileSync)(state.prdFile, "utf-8");
376
+ if (refineMethod === "manual") {
377
+ console.log(chalk_1.default.gray("\n Opening editor...\n"));
378
+ refinedContent = await (0, workflow_prompts_1.editorPrompt)("Edit your PRD (save and close when done):", refinedContent);
379
+ }
380
+ else if (refineMethod === "ai") {
381
+ console.log(chalk_1.default.cyan("\n🤖 AI-Assisted Refinement\n"));
382
+ const feedback = await (0, workflow_prompts_1.textInputPrompt)("What would you like to improve? (e.g., 'Add more technical details', 'Focus on MVP features'):");
383
+ console.log(chalk_1.default.gray("\n Refining PRD...\n"));
384
+ refinedContent = await workflow_ai_assistant_1.workflowAIAssistant.assistPRDRefinement({
385
+ currentPRD: refinedContent,
386
+ userFeedback: feedback,
387
+ aiOptions,
388
+ streamingOptions,
389
+ });
390
+ console.log(chalk_1.default.green("\n✓ PRD refined"));
391
+ console.log(chalk_1.default.gray("\n" + refinedContent.substring(0, 500) + "...\n"));
392
+ const acceptRefinement = await (0, workflow_prompts_1.confirmPrompt)("Accept refinements?", true);
393
+ if (!acceptRefinement) {
394
+ console.log(chalk_1.default.yellow("⚠ Keeping original PRD"));
395
+ state.currentStep = "generate-tasks";
396
+ return;
397
+ }
398
+ }
399
+ // Save refined PRD
400
+ (0, fs_1.writeFileSync)(state.prdFile, refinedContent);
401
+ state.prdContent = refinedContent;
402
+ console.log(chalk_1.default.green(`✓ PRD updated`));
403
+ state.currentStep = "generate-tasks";
404
+ }
405
+ /**
406
+ * Step 4: Generate Tasks
407
+ */
408
+ async function stepGenerateTasks(state, aiOptions, streamingOptions) {
409
+ console.log(chalk_1.default.blue.bold("\n🎯 Step 4: Generate Tasks\n"));
410
+ if (!state.prdFile) {
411
+ console.log(chalk_1.default.yellow("⚠ No PRD file found, skipping task generation"));
412
+ state.currentStep = "split-tasks";
413
+ return;
414
+ }
415
+ const shouldGenerate = await (0, workflow_prompts_1.confirmPrompt)("Generate tasks from PRD?", true);
416
+ if (!shouldGenerate) {
417
+ console.log(chalk_1.default.gray(" Skipping task generation"));
418
+ state.currentStep = "split-tasks";
419
+ return;
420
+ }
421
+ const generationMethod = await (0, workflow_prompts_1.selectPrompt)("Choose generation method:", [
422
+ { name: "Standard parsing", value: "standard" },
423
+ { name: "AI-assisted with custom instructions", value: "ai" },
424
+ ]);
425
+ let customInstructions;
426
+ if (generationMethod === "ai") {
427
+ customInstructions = await (0, workflow_prompts_1.textInputPrompt)("Custom instructions (e.g., 'Focus on MVP features', 'Break into small tasks'):", "");
428
+ }
429
+ console.log(chalk_1.default.cyan("\n Parsing PRD and generating tasks...\n"));
430
+ const result = await prd_1.prdService.parsePRD({
431
+ file: state.prdFile,
432
+ workingDirectory: state.projectDir,
433
+ aiOptions,
434
+ messageOverride: customInstructions,
435
+ streamingOptions,
436
+ callbacks: {
437
+ onProgress: progress_1.displayProgress,
438
+ onError: progress_1.displayError,
439
+ },
440
+ });
441
+ console.log(chalk_1.default.green(`\n✓ Generated ${result.tasks.length} tasks`));
442
+ // Display tasks
443
+ console.log(chalk_1.default.blue("\n Created Tasks:\n"));
444
+ result.tasks.forEach((task, index) => {
445
+ console.log(chalk_1.default.gray(` ${index + 1}. ${task.title} ${task.estimatedEffort ? `(${task.estimatedEffort})` : ""}`));
446
+ });
447
+ state.tasks = result.tasks.map((t) => ({
448
+ id: t.id,
449
+ title: t.title,
450
+ description: t.description,
451
+ }));
452
+ state.currentStep = "split-tasks";
453
+ }
454
+ /**
455
+ * Step 5: Split Complex Tasks
456
+ */
457
+ async function stepSplitTasks(state, aiOptions, streamingOptions) {
458
+ console.log(chalk_1.default.blue.bold("\n🔀 Step 5: Split Complex Tasks\n"));
459
+ if (!state.tasks || state.tasks.length === 0) {
460
+ console.log(chalk_1.default.yellow("⚠ No tasks found, skipping splitting"));
461
+ return;
462
+ }
463
+ const shouldSplit = await (0, workflow_prompts_1.confirmPrompt)("Split any complex tasks into subtasks?", false);
464
+ if (!shouldSplit) {
465
+ console.log(chalk_1.default.gray(" Skipping task splitting"));
466
+ return;
467
+ }
468
+ // Show tasks with effort estimates
469
+ const tasksToSplit = await (0, workflow_prompts_1.multiSelectPrompt)("Select tasks to split:", state.tasks.map((t) => ({
470
+ name: `${t.title}${t.description ? ` - ${t.description.substring(0, 50)}...` : ""}`,
471
+ value: t.id,
472
+ })));
473
+ if (tasksToSplit.length === 0) {
474
+ console.log(chalk_1.default.gray(" No tasks selected"));
475
+ return;
476
+ }
477
+ for (const taskId of tasksToSplit) {
478
+ const task = state.tasks.find((t) => t.id === taskId);
479
+ if (!task)
480
+ continue;
481
+ console.log(chalk_1.default.cyan(`\n Splitting: ${task.title}\n`));
482
+ const splitMethod = await (0, workflow_prompts_1.selectPrompt)("Split method:", [
483
+ { name: "Standard AI split", value: "standard" },
484
+ { name: "Custom instructions", value: "custom" },
485
+ ]);
486
+ let customInstructions;
487
+ if (splitMethod === "custom") {
488
+ customInstructions = await (0, workflow_prompts_1.textInputPrompt)("Custom instructions (e.g., 'Break into 2-4 hour chunks'):", "");
489
+ }
490
+ try {
491
+ const result = await tasks_1.taskService.splitTask(taskId, aiOptions, undefined, // promptOverride
492
+ customInstructions, streamingOptions);
493
+ console.log(chalk_1.default.green(` ✓ Created ${result.subtasks.length} subtasks`));
494
+ result.subtasks.forEach((subtask, index) => {
495
+ console.log(chalk_1.default.gray(` ${index + 1}. ${subtask.title}`));
496
+ });
497
+ }
498
+ catch (error) {
499
+ console.log(chalk_1.default.red(` ✗ Failed to split task: ${error}`));
500
+ }
501
+ }
502
+ console.log(chalk_1.default.green("\n✓ Task splitting complete"));
503
+ }
@@ -1 +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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,QAAA,MAAM,OAAO,SAAgB,CAAC;AA8C9B;;;GAGG;AACH,eAAO,MAAM,MAAM,qBAUlB,CAAC;AAEF;;GAEG;AACH,OAAO,EAAE,OAAO,EAAE,CAAC"}
package/dist/index.js CHANGED
@@ -17,6 +17,7 @@ const tasks_1 = require("./commands/tasks");
17
17
  const prd_1 = require("./commands/prd");
18
18
  const init_1 = require("./commands/init");
19
19
  const prompt_1 = require("./commands/prompt");
20
+ const workflow_1 = require("./commands/workflow");
20
21
  const config_2 = require("./lib/config");
21
22
  const program = new commander_1.Command();
22
23
  exports.program = program;
@@ -31,6 +32,7 @@ program.addCommand(tasks_1.tasksCommand);
31
32
  program.addCommand(prd_1.prdCommand);
32
33
  program.addCommand(prompt_1.promptCommand);
33
34
  program.addCommand(init_1.initCommand);
35
+ program.addCommand(workflow_1.workflowCommand);
34
36
  // Default action - show help
35
37
  program.action(() => {
36
38
  console.log(chalk_1.default.blue("🚀 AI-Powered Task Management CLI"));
@@ -47,7 +49,7 @@ program.action(() => {
47
49
  // Error handling
48
50
  program.on("command:*", (operands) => {
49
51
  console.error(chalk_1.default.red(`Unknown command: ${operands[0]}`));
50
- console.log(chalk_1.default.blue("Available commands: config, tasks, prd, prompt, init"));
52
+ console.log(chalk_1.default.blue("Available commands: config, tasks, prd, prompt, init, workflow"));
51
53
  console.log(chalk_1.default.blue("Use --help for available commands"));
52
54
  process.exit(1);
53
55
  });
@@ -1 +1 @@
1
- {"version":3,"file":"ai-operations.d.ts","sourceRoot":"","sources":["../../../src/lib/ai-service/ai-operations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ai-operations.d.ts","sourceRoot":"","sources":["../../../src/lib/ai-service/ai-operations.ts"],"names":[],"mappings":"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"}