task-o-matic 0.0.11 → 0.0.13

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 (123) hide show
  1. package/dist/commands/tasks/create.d.ts.map +1 -1
  2. package/dist/commands/tasks/create.js +6 -13
  3. package/dist/commands/tasks/document/add.d.ts +3 -0
  4. package/dist/commands/tasks/document/add.d.ts.map +1 -0
  5. package/dist/commands/tasks/document/add.js +35 -0
  6. package/dist/commands/tasks/document/analyze.d.ts +3 -0
  7. package/dist/commands/tasks/document/analyze.d.ts.map +1 -0
  8. package/dist/commands/tasks/document/analyze.js +49 -0
  9. package/dist/commands/tasks/document/get.d.ts +3 -0
  10. package/dist/commands/tasks/document/get.d.ts.map +1 -0
  11. package/dist/commands/tasks/document/get.js +29 -0
  12. package/dist/commands/tasks/document/index.d.ts +8 -0
  13. package/dist/commands/tasks/document/index.d.ts.map +1 -0
  14. package/dist/commands/tasks/document/index.js +13 -0
  15. package/dist/commands/tasks/enhance.d.ts.map +1 -1
  16. package/dist/commands/tasks/enhance.js +64 -61
  17. package/dist/commands/tasks/execute-loop.d.ts.map +1 -1
  18. package/dist/commands/tasks/execute-loop.js +66 -97
  19. package/dist/commands/tasks/execute.d.ts.map +1 -1
  20. package/dist/commands/tasks/execute.js +52 -16
  21. package/dist/commands/tasks/plan/create.d.ts +3 -0
  22. package/dist/commands/tasks/plan/create.d.ts.map +1 -0
  23. package/dist/commands/tasks/plan/create.js +37 -0
  24. package/dist/commands/tasks/plan/delete.d.ts +3 -0
  25. package/dist/commands/tasks/plan/delete.d.ts.map +1 -0
  26. package/dist/commands/tasks/plan/delete.js +14 -0
  27. package/dist/commands/tasks/plan/get.d.ts +3 -0
  28. package/dist/commands/tasks/plan/get.d.ts.map +1 -0
  29. package/dist/commands/tasks/plan/get.js +24 -0
  30. package/dist/commands/tasks/plan/index.d.ts +10 -0
  31. package/dist/commands/tasks/plan/index.d.ts.map +1 -0
  32. package/dist/commands/tasks/plan/index.js +17 -0
  33. package/dist/commands/tasks/plan/list.d.ts +3 -0
  34. package/dist/commands/tasks/plan/list.d.ts.map +1 -0
  35. package/dist/commands/tasks/plan/list.js +21 -0
  36. package/dist/commands/tasks/plan/set.d.ts +3 -0
  37. package/dist/commands/tasks/plan/set.d.ts.map +1 -0
  38. package/dist/commands/tasks/plan/set.js +33 -0
  39. package/dist/commands/tasks/split.d.ts.map +1 -1
  40. package/dist/commands/tasks/split.js +65 -60
  41. package/dist/lib/ai-service/documentation-operations.d.ts.map +1 -1
  42. package/dist/lib/ai-service/documentation-operations.js +22 -12
  43. package/dist/lib/ai-service/prd-operations.d.ts.map +1 -1
  44. package/dist/lib/ai-service/prd-operations.js +18 -25
  45. package/dist/lib/executors/opencode-executor.d.ts.map +1 -1
  46. package/dist/lib/executors/opencode-executor.js +3 -1
  47. package/dist/lib/git-utils.d.ts +45 -0
  48. package/dist/lib/git-utils.d.ts.map +1 -0
  49. package/dist/lib/git-utils.js +160 -0
  50. package/dist/lib/prompt-builder.d.ts +11 -0
  51. package/dist/lib/prompt-builder.d.ts.map +1 -1
  52. package/dist/lib/prompt-builder.js +59 -0
  53. package/dist/lib/prompt-registry.d.ts.map +1 -1
  54. package/dist/lib/prompt-registry.js +158 -0
  55. package/dist/lib/task-execution-core.d.ts +7 -0
  56. package/dist/lib/task-execution-core.d.ts.map +1 -0
  57. package/dist/lib/task-execution-core.js +360 -0
  58. package/dist/lib/task-execution.d.ts +4 -0
  59. package/dist/lib/task-execution.d.ts.map +1 -1
  60. package/dist/lib/task-execution.js +31 -178
  61. package/dist/lib/task-loop-execution.d.ts +1 -19
  62. package/dist/lib/task-loop-execution.d.ts.map +1 -1
  63. package/dist/lib/task-loop-execution.js +50 -592
  64. package/dist/lib/task-planning.d.ts +28 -0
  65. package/dist/lib/task-planning.d.ts.map +1 -0
  66. package/dist/lib/task-planning.js +109 -0
  67. package/dist/lib/task-review.d.ts +27 -0
  68. package/dist/lib/task-review.d.ts.map +1 -0
  69. package/dist/lib/task-review.js +106 -0
  70. package/dist/lib/validation.d.ts +20 -3
  71. package/dist/lib/validation.d.ts.map +1 -1
  72. package/dist/lib/validation.js +39 -10
  73. package/dist/prompts/documentation-recap.d.ts +3 -0
  74. package/dist/prompts/documentation-recap.d.ts.map +1 -0
  75. package/dist/prompts/documentation-recap.js +13 -0
  76. package/dist/prompts/index.d.ts +4 -0
  77. package/dist/prompts/index.d.ts.map +1 -1
  78. package/dist/prompts/index.js +4 -0
  79. package/dist/prompts/prd-question-answer.d.ts +3 -0
  80. package/dist/prompts/prd-question-answer.d.ts.map +1 -0
  81. package/dist/prompts/prd-question-answer.js +27 -0
  82. package/dist/prompts/task-execution.d.ts +3 -0
  83. package/dist/prompts/task-execution.d.ts.map +1 -0
  84. package/dist/prompts/task-execution.js +21 -0
  85. package/dist/prompts/workflow-prompts.d.ts +9 -0
  86. package/dist/prompts/workflow-prompts.d.ts.map +1 -0
  87. package/dist/prompts/workflow-prompts.js +93 -0
  88. package/dist/services/workflow-ai-assistant.d.ts.map +1 -1
  89. package/dist/services/workflow-ai-assistant.js +72 -94
  90. package/dist/test/task-loop-git.test.js +6 -6
  91. package/dist/types/cli-options.d.ts +138 -0
  92. package/dist/types/cli-options.d.ts.map +1 -0
  93. package/dist/types/cli-options.js +6 -0
  94. package/dist/types/index.d.ts +38 -0
  95. package/dist/types/index.d.ts.map +1 -1
  96. package/dist/utils/bulk-operations.d.ts +51 -0
  97. package/dist/utils/bulk-operations.d.ts.map +1 -0
  98. package/dist/utils/bulk-operations.js +68 -0
  99. package/dist/utils/cli-validators.d.ts +54 -0
  100. package/dist/utils/cli-validators.d.ts.map +1 -0
  101. package/dist/utils/cli-validators.js +75 -0
  102. package/dist/utils/command-error-handler.d.ts +32 -0
  103. package/dist/utils/command-error-handler.d.ts.map +1 -0
  104. package/dist/utils/command-error-handler.js +52 -0
  105. package/dist/utils/confirmation.d.ts +19 -0
  106. package/dist/utils/confirmation.d.ts.map +1 -0
  107. package/dist/utils/confirmation.js +39 -0
  108. package/dist/utils/display-helpers.d.ts +81 -0
  109. package/dist/utils/display-helpers.d.ts.map +1 -0
  110. package/dist/utils/display-helpers.js +109 -0
  111. package/dist/utils/model-executor-parser.d.ts +38 -0
  112. package/dist/utils/model-executor-parser.d.ts.map +1 -0
  113. package/dist/utils/model-executor-parser.js +67 -0
  114. package/dist/utils/progress-tracking.d.ts +28 -0
  115. package/dist/utils/progress-tracking.d.ts.map +1 -0
  116. package/dist/utils/progress-tracking.js +43 -0
  117. package/package.json +1 -1
  118. package/dist/commands/tasks/document.d.ts +0 -5
  119. package/dist/commands/tasks/document.d.ts.map +0 -1
  120. package/dist/commands/tasks/document.js +0 -118
  121. package/dist/commands/tasks/plan.d.ts +0 -7
  122. package/dist/commands/tasks/plan.d.ts.map +0 -1
  123. package/dist/commands/tasks/plan.js +0 -131
@@ -7,6 +7,8 @@ exports.executeCommand = void 0;
7
7
  const commander_1 = require("commander");
8
8
  const chalk_1 = __importDefault(require("chalk"));
9
9
  const task_execution_1 = require("../../lib/task-execution");
10
+ const model_executor_parser_1 = require("../../utils/model-executor-parser");
11
+ const command_error_handler_1 = require("../../utils/command-error-handler");
10
12
  exports.executeCommand = new commander_1.Command("execute")
11
13
  .description("Execute a task using an external coding assistant")
12
14
  .requiredOption("--id <id>", "Task ID to execute")
@@ -15,23 +17,57 @@ exports.executeCommand = new commander_1.Command("execute")
15
17
  .option("-m, --model <model>", "Model to use with the executor")
16
18
  .option("--continue-session", "Continue the last session (for error feedback)", false)
17
19
  .option("--dry", "Show what would be executed without running it")
18
- .option("--validate <command>", "Validation command to run after execution (can be used multiple times)", (value, previous = []) => {
20
+ .option("--validate <command>", "Validation/verification command to run after execution (can be used multiple times)", (value, previous = []) => {
19
21
  return [...previous, value];
20
22
  })
21
- .action(async (options) => {
22
- try {
23
- await (0, task_execution_1.executeTask)({
24
- taskId: options.id,
25
- tool: options.tool,
26
- message: options.message,
27
- model: options.model,
28
- continueSession: options.continueSession,
29
- dry: options.dry,
30
- validate: options.validate || [],
31
- });
32
- }
33
- catch (error) {
34
- console.error(chalk_1.default.red("Execution failed:"), error instanceof Error ? error.message : "Unknown error");
23
+ .option("--verify <command>", "Alias for --validate (verification command)", (value, previous = []) => {
24
+ return [...previous, value];
25
+ })
26
+ .option("--max-retries <number>", "Maximum number of retries (opt-in, enables retry logic)", (value) => parseInt(value, 10))
27
+ .option("--try-models <models>", "Progressive model/executor configs for retries (e.g., 'gpt-4o-mini,claude:sonnet-4')")
28
+ .option("--plan", "Generate an implementation plan before execution", false)
29
+ .option("--plan-model <model>", "Model/executor to use for planning (e.g., 'opencode:gpt-4o' or 'gpt-4o')")
30
+ .option("--review-plan", "Pause for human review of the plan", false)
31
+ .option("--review", "Run AI review after execution", false)
32
+ .option("--review-model <model>", "Model/executor to use for review (e.g., 'opencode:gpt-4o' or 'gpt-4o')")
33
+ .option("--auto-commit", "Automatically commit changes after execution", false)
34
+ .action((0, command_error_handler_1.wrapCommandHandler)("Task execution", async (options) => {
35
+ // Validate executor tool
36
+ if (!(0, model_executor_parser_1.validateExecutor)(options.tool)) {
37
+ console.error(chalk_1.default.red(`Invalid tool: ${options.tool}. Must be one of: ${model_executor_parser_1.VALID_EXECUTORS.join(", ")}`));
35
38
  process.exit(1);
36
39
  }
37
- });
40
+ // Combine both --validate and --verify options
41
+ const validations = [
42
+ ...(options.validate || []),
43
+ ...(options.verify || []),
44
+ ];
45
+ // Parse tryModels if provided
46
+ let tryModels;
47
+ if (options.tryModels) {
48
+ try {
49
+ tryModels = (0, model_executor_parser_1.parseTryModels)(options.tryModels);
50
+ }
51
+ catch (error) {
52
+ console.error(chalk_1.default.red(`Failed to parse --try-models: ${error instanceof Error ? error.message : "Unknown error"}`));
53
+ process.exit(1);
54
+ }
55
+ }
56
+ await (0, task_execution_1.executeTask)({
57
+ taskId: options.id,
58
+ tool: options.tool,
59
+ message: options.message,
60
+ model: options.model,
61
+ continueSession: options.continueSession,
62
+ dry: options.dry,
63
+ validate: validations,
64
+ maxRetries: options.maxRetries,
65
+ tryModels,
66
+ plan: options.plan,
67
+ planModel: options.planModel,
68
+ reviewPlan: options.reviewPlan,
69
+ review: options.review,
70
+ reviewModel: options.reviewModel,
71
+ autoCommit: options.autoCommit,
72
+ });
73
+ }));
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const planCommand: Command;
3
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../../src/commands/tasks/plan/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,eAAO,MAAM,WAAW,SAmCnB,CAAC"}
@@ -0,0 +1,37 @@
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.planCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const tasks_1 = require("../../../services/tasks");
10
+ const streaming_options_1 = require("../../../utils/streaming-options");
11
+ const plan_1 = require("../../../cli/display/plan");
12
+ const progress_tracking_1 = require("../../../utils/progress-tracking");
13
+ const command_error_handler_1 = require("../../../utils/command-error-handler");
14
+ exports.planCommand = new commander_1.Command("plan")
15
+ .description("Create detailed implementation plan for a task or subtask")
16
+ .requiredOption("--id <id>", "Task or subtask ID to plan")
17
+ .option("--stream", "Show streaming AI output during planning")
18
+ .option("--ai-provider <provider>", "AI provider override")
19
+ .option("--ai-model <model>", "AI model override")
20
+ .option("--ai-key <key>", "AI API key override")
21
+ .option("--ai-provider-url <url>", "AI provider URL override")
22
+ .option("--reasoning <tokens>", "Enable reasoning for OpenRouter models (max reasoning tokens)")
23
+ .action((0, command_error_handler_1.wrapCommandHandler)("Task planning", async (options) => {
24
+ const streamingOptions = (0, streaming_options_1.createStreamingOptions)(options.stream, "Planning");
25
+ const result = await (0, progress_tracking_1.withProgressTracking)(async () => {
26
+ return await tasks_1.taskService.planTask(options.id, {
27
+ aiProvider: options.aiProvider,
28
+ aiModel: options.aiModel,
29
+ aiKey: options.aiKey,
30
+ aiProviderUrl: options.aiProviderUrl,
31
+ aiReasoning: options.reasoning,
32
+ }, streamingOptions);
33
+ });
34
+ // Display the plan
35
+ (0, plan_1.displayPlanCreation)(options.id, result.task.title);
36
+ console.log(chalk_1.default.cyan(result.plan));
37
+ }));
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const deletePlanCommand: Command;
3
+ //# sourceMappingURL=delete.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../../src/commands/tasks/plan/delete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,eAAO,MAAM,iBAAiB,SAMzB,CAAC"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deletePlanCommand = void 0;
4
+ const commander_1 = require("commander");
5
+ const tasks_1 = require("../../../services/tasks");
6
+ const plan_1 = require("../../../cli/display/plan");
7
+ const command_error_handler_1 = require("../../../utils/command-error-handler");
8
+ exports.deletePlanCommand = new commander_1.Command("delete-plan")
9
+ .description("Delete implementation plan for a task")
10
+ .requiredOption("--id <id>", "Task ID")
11
+ .action((0, command_error_handler_1.wrapCommandHandler)("Delete plan", async (options) => {
12
+ const success = await tasks_1.taskService.deleteTaskPlan(options.id);
13
+ (0, plan_1.displayPlanDeletion)(options.id, success);
14
+ }));
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const getPlanCommand: Command;
3
+ //# sourceMappingURL=get.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../../../src/commands/tasks/plan/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,eAAO,MAAM,cAAc,SAuBtB,CAAC"}
@@ -0,0 +1,24 @@
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.getPlanCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const tasks_1 = require("../../../services/tasks");
10
+ const plan_1 = require("../../../cli/display/plan");
11
+ const command_error_handler_1 = require("../../../utils/command-error-handler");
12
+ exports.getPlanCommand = new commander_1.Command("get-plan")
13
+ .description("View existing implementation plan for a task or subtask")
14
+ .requiredOption("--id <id>", "Task or subtask ID")
15
+ .action((0, command_error_handler_1.wrapCommandHandler)("Get plan", async (options) => {
16
+ const plan = await tasks_1.taskService.getTaskPlan(options.id);
17
+ if (!plan) {
18
+ console.log(chalk_1.default.yellow(`⚠️ No plan found for task/subtask ${options.id}`));
19
+ return;
20
+ }
21
+ const task = await tasks_1.taskService.getTask(options.id);
22
+ const taskTitle = task ? task.title : options.id;
23
+ (0, plan_1.displayPlanView)(taskTitle, options.id, plan.plan, plan.createdAt, plan.updatedAt);
24
+ }));
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Plan command submodules
3
+ * Each command is in its own file for better organization
4
+ */
5
+ export { planCommand } from "./create";
6
+ export { getPlanCommand } from "./get";
7
+ export { listPlanCommand } from "./list";
8
+ export { deletePlanCommand } from "./delete";
9
+ export { setPlanCommand } from "./set";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/tasks/plan/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ /**
3
+ * Plan command submodules
4
+ * Each command is in its own file for better organization
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.setPlanCommand = exports.deletePlanCommand = exports.listPlanCommand = exports.getPlanCommand = exports.planCommand = void 0;
8
+ var create_1 = require("./create");
9
+ Object.defineProperty(exports, "planCommand", { enumerable: true, get: function () { return create_1.planCommand; } });
10
+ var get_1 = require("./get");
11
+ Object.defineProperty(exports, "getPlanCommand", { enumerable: true, get: function () { return get_1.getPlanCommand; } });
12
+ var list_1 = require("./list");
13
+ Object.defineProperty(exports, "listPlanCommand", { enumerable: true, get: function () { return list_1.listPlanCommand; } });
14
+ var delete_1 = require("./delete");
15
+ Object.defineProperty(exports, "deletePlanCommand", { enumerable: true, get: function () { return delete_1.deletePlanCommand; } });
16
+ var set_1 = require("./set");
17
+ Object.defineProperty(exports, "setPlanCommand", { enumerable: true, get: function () { return set_1.setPlanCommand; } });
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const listPlanCommand: Command;
3
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../../src/commands/tasks/plan/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,eAAe,SAiBvB,CAAC"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.listPlanCommand = void 0;
4
+ const commander_1 = require("commander");
5
+ const tasks_1 = require("../../../services/tasks");
6
+ const plan_1 = require("../../../cli/display/plan");
7
+ const command_error_handler_1 = require("../../../utils/command-error-handler");
8
+ exports.listPlanCommand = new commander_1.Command("list-plan")
9
+ .description("List all available implementation plans")
10
+ .action((0, command_error_handler_1.wrapCommandHandler)("List plans", async () => {
11
+ const plans = await tasks_1.taskService.listTaskPlans();
12
+ // Get task titles for each plan
13
+ const plansWithTitles = await Promise.all(plans.map(async (plan) => {
14
+ const task = await tasks_1.taskService.getTask(plan.taskId);
15
+ return {
16
+ ...plan,
17
+ taskTitle: task ? task.title : plan.taskId,
18
+ };
19
+ }));
20
+ (0, plan_1.displayPlanList)(plansWithTitles);
21
+ }));
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const setPlanCommand: Command;
3
+ //# sourceMappingURL=set.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../../../../src/commands/tasks/plan/set.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,eAAO,MAAM,cAAc,SAiCtB,CAAC"}
@@ -0,0 +1,33 @@
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.setPlanCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const tasks_1 = require("../../../services/tasks");
10
+ const command_error_handler_1 = require("../../../utils/command-error-handler");
11
+ exports.setPlanCommand = new commander_1.Command("set-plan")
12
+ .description("Set implementation plan for a task")
13
+ .requiredOption("--id <id>", "Task ID")
14
+ .option("--plan <text>", "Plan text (use quotes for multi-line)")
15
+ .option("--plan-file <path>", "Path to file containing the plan")
16
+ .action((0, command_error_handler_1.wrapCommandHandler)("Set plan", async (options) => {
17
+ const task = await tasks_1.taskService.getTask(options.id);
18
+ if (!task) {
19
+ throw new Error(`Task with ID ${options.id} not found`);
20
+ }
21
+ if (!options.plan && !options.planFile) {
22
+ throw new Error("Either --plan or --plan-file must be specified");
23
+ }
24
+ if (options.plan && options.planFile) {
25
+ throw new Error("Cannot specify both --plan and --plan-file");
26
+ }
27
+ const result = await tasks_1.taskService.setTaskPlan(options.id, options.plan || undefined, options.planFile || undefined);
28
+ console.log(chalk_1.default.green(`✓ Plan set for task: ${task.title} (${options.id})`));
29
+ console.log(chalk_1.default.gray(` Plan file: ${result.planFile}`));
30
+ if (options.planFile) {
31
+ console.log(chalk_1.default.gray(` Source file: ${options.planFile}`));
32
+ }
33
+ }));
@@ -1 +1 @@
1
- {"version":3,"file":"split.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/split.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,eAAO,MAAM,YAAY,SAyHrB,CAAC"}
1
+ {"version":3,"file":"split.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/split.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,eAAO,MAAM,YAAY,SAsHpB,CAAC"}
@@ -7,14 +7,21 @@ exports.splitCommand = void 0;
7
7
  const commander_1 = require("commander");
8
8
  const chalk_1 = __importDefault(require("chalk"));
9
9
  const tasks_1 = require("../../services/tasks");
10
- const hooks_1 = require("../../lib/hooks");
11
10
  const streaming_options_1 = require("../../utils/streaming-options");
12
- const progress_1 = require("../../cli/display/progress");
13
11
  const task_1 = require("../../cli/display/task");
12
+ const progress_tracking_1 = require("../../utils/progress-tracking");
13
+ const cli_validators_1 = require("../../utils/cli-validators");
14
+ const bulk_operations_1 = require("../../utils/bulk-operations");
15
+ const confirmation_1 = require("../../utils/confirmation");
16
+ const command_error_handler_1 = require("../../utils/command-error-handler");
14
17
  exports.splitCommand = new commander_1.Command("split")
15
18
  .description("Split a task into smaller subtasks using AI")
16
19
  .option("--task-id <id>", "Task ID to split")
17
20
  .option("--all", "Split all existing tasks that don't have subtasks")
21
+ .option("--status <status>", "Filter tasks by status (todo/in-progress/completed)")
22
+ .option("--tag <tag>", "Filter tasks by tag")
23
+ .option("--dry", "Preview what would be split without making changes")
24
+ .option("--force", "Skip confirmation prompt for bulk operations")
18
25
  .option("--stream", "Show streaming AI output during breakdown")
19
26
  .option("--ai-provider <provider>", "AI provider override")
20
27
  .option("--ai-model <model>", "AI model override")
@@ -22,74 +29,72 @@ exports.splitCommand = new commander_1.Command("split")
22
29
  .option("--ai-provider-url <url>", "AI provider URL override")
23
30
  .option("--reasoning <tokens>", "Enable reasoning for OpenRouter models (max reasoning tokens)")
24
31
  .option("--tools", "Enable filesystem tools for project analysis")
25
- .action(async (options) => {
26
- try {
27
- if (!options.taskId && !options.all) {
28
- throw new Error("Either --task-id or --all must be specified");
29
- }
30
- if (options.taskId && options.all) {
31
- throw new Error("Cannot specify both --task-id and --all");
32
+ .action((0, command_error_handler_1.wrapCommandHandler)("Task splitting", async (options) => {
33
+ // Validate mutual exclusivity (only if no filters provided)
34
+ if (!options.status && !options.tag) {
35
+ (0, cli_validators_1.validateMutuallyExclusive)(options, "taskId", "all", "task-id", "all");
36
+ }
37
+ const splitSingleTask = async (taskId) => {
38
+ if (options.dry) {
39
+ const task = await tasks_1.taskService.getTask(taskId);
40
+ console.log(chalk_1.default.blue(`[DRY RUN] Would split: ${task?.title || taskId}`));
41
+ return;
32
42
  }
33
- const splitSingleTask = async (taskId) => {
34
- const streamingOptions = (0, streaming_options_1.createStreamingOptions)(options.stream, "Task breakdown");
35
- const progressHandler = (payload) => {
36
- (0, progress_1.displayProgress)(payload);
37
- };
38
- hooks_1.hooks.on("task:progress", progressHandler);
39
- try {
40
- const result = await tasks_1.taskService.splitTask(taskId, {
43
+ const streamingOptions = (0, streaming_options_1.createStreamingOptions)(options.stream, "Task breakdown");
44
+ try {
45
+ const result = await (0, progress_tracking_1.withProgressTracking)(async () => {
46
+ return await tasks_1.taskService.splitTask(taskId, {
41
47
  aiProvider: options.aiProvider,
42
48
  aiModel: options.aiModel,
43
49
  aiKey: options.aiKey,
44
50
  aiProviderUrl: options.aiProviderUrl,
45
51
  aiReasoning: options.reasoning,
46
52
  }, undefined, undefined, streamingOptions, options.tools);
47
- (0, task_1.displaySubtaskCreation)(result.subtasks);
48
- // Display AI metadata
49
- console.log(chalk_1.default.gray(`\n📊 AI Splitting Details:`));
50
- console.log(chalk_1.default.gray(` Provider: ${result.metadata.aiProvider}`));
51
- console.log(chalk_1.default.gray(` Model: ${result.metadata.aiModel}`));
52
- console.log(chalk_1.default.gray(` Subtasks created: ${result.subtasks.length}`));
53
- console.log(chalk_1.default.gray(` Confidence: ${result.metadata.confidence
54
- ? (result.metadata.confidence * 100).toFixed(1)
55
- : "N/A"}%`));
56
- }
57
- catch (error) {
58
- if (error instanceof Error && error.message.includes("already has")) {
59
- console.log(chalk_1.default.yellow(`⚠️ ${error.message}`));
60
- return;
61
- }
62
- throw error;
63
- }
64
- finally {
65
- hooks_1.hooks.off("task:progress", progressHandler);
66
- }
67
- };
68
- if (options.taskId) {
69
- await splitSingleTask(options.taskId);
53
+ });
54
+ (0, task_1.displaySubtaskCreation)(result.subtasks);
55
+ // Display AI metadata
56
+ console.log(chalk_1.default.gray(`\n📊 AI Splitting Details:`));
57
+ console.log(chalk_1.default.gray(` Provider: ${result.metadata.aiProvider}`));
58
+ console.log(chalk_1.default.gray(` Model: ${result.metadata.aiModel}`));
59
+ console.log(chalk_1.default.gray(` Subtasks created: ${result.subtasks.length}`));
60
+ console.log(chalk_1.default.gray(` Confidence: ${result.metadata.confidence
61
+ ? (result.metadata.confidence * 100).toFixed(1)
62
+ : "N/A"}%`));
70
63
  }
71
- else if (options.all) {
72
- const allTasks = await tasks_1.taskService.listTasks({});
73
- if (allTasks.length === 0) {
74
- console.log(chalk_1.default.yellow("No tasks found to split."));
64
+ catch (error) {
65
+ if (error instanceof Error && error.message.includes("already has")) {
66
+ console.log(chalk_1.default.yellow(`⚠️ ${error.message}`));
75
67
  return;
76
68
  }
77
- console.log(chalk_1.default.blue(`🔧 Splitting ${allTasks.length} tasks...`));
78
- for (let i = 0; i < allTasks.length; i++) {
79
- const task = allTasks[i];
80
- console.log(chalk_1.default.cyan(`\n[${i + 1}/${allTasks.length}] Splitting: ${task.title}`));
81
- try {
82
- await splitSingleTask(task.id);
83
- }
84
- catch (error) {
85
- console.log(chalk_1.default.red(`❌ Failed to split task ${task.id}: ${error instanceof Error ? error.message : "Unknown error"}`));
86
- }
87
- }
88
- console.log(chalk_1.default.green(`\n✓ Bulk splitting complete! Processed ${allTasks.length} tasks.`));
69
+ throw error;
89
70
  }
71
+ };
72
+ if (options.taskId) {
73
+ await splitSingleTask(options.taskId);
90
74
  }
91
- catch (error) {
92
- (0, progress_1.displayError)(error);
93
- process.exit(1);
75
+ else {
76
+ // Build filters for bulk operation
77
+ const filters = {};
78
+ if (options.status)
79
+ filters.status = options.status;
80
+ if (options.tag)
81
+ filters.tag = options.tag;
82
+ // Get task count for confirmation
83
+ const tasks = await tasks_1.taskService.listTasks(filters);
84
+ if (tasks.length === 0) {
85
+ console.log(chalk_1.default.yellow("No tasks found matching the filters"));
86
+ return;
87
+ }
88
+ // Confirm bulk operation
89
+ const confirmed = await (0, confirmation_1.confirmBulkOperation)("split", tasks.length, options.force);
90
+ if (!confirmed) {
91
+ console.log(chalk_1.default.yellow("Operation cancelled"));
92
+ return;
93
+ }
94
+ await (0, bulk_operations_1.executeBulkOperation)((taskId) => splitSingleTask(taskId), {
95
+ operationName: "Splitting",
96
+ operationEmoji: "🔧",
97
+ filters,
98
+ });
94
99
  }
95
- });
100
+ }));
@@ -1 +1 @@
1
- {"version":3,"file":"documentation-operations.d.ts","sourceRoot":"","sources":["../../../src/lib/ai-service/documentation-operations.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,QAAQ,EACR,sBAAsB,EACtB,gBAAgB,EAChB,WAAW,EACX,iBAAiB,EAClB,MAAM,aAAa,CAAC;AAKrB,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,qBAAa,uBAAwB,SAAQ,cAAc;IACnD,4BAA4B,CAChC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EACvB,SAAS,CAAC,EAAE,MAAM,EAClB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,EAClC,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,GACvE,OAAO,CAAC,MAAM,CAAC;IAiJZ,yBAAyB,CAC7B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EACvB,SAAS,CAAC,EAAE,MAAM,EAClB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,EAClC,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,gBAAgB,CAAC,EAAE,CAAC,iBAAiB,GAAG,SAAS,CAAC,EAAE,GACnD,OAAO,CAAC,sBAAsB,CAAC;IAiM5B,0BAA0B,CAC9B,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,EACtE,gBAAgB,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,EAC7D,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC;CA8BnB"}
1
+ {"version":3,"file":"documentation-operations.d.ts","sourceRoot":"","sources":["../../../src/lib/ai-service/documentation-operations.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,QAAQ,EACR,sBAAsB,EACtB,gBAAgB,EAChB,WAAW,EACX,iBAAiB,EAClB,MAAM,aAAa,CAAC;AAKrB,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,qBAAa,uBAAwB,SAAQ,cAAc;IACnD,4BAA4B,CAChC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EACvB,SAAS,CAAC,EAAE,MAAM,EAClB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,EAClC,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,GACvE,OAAO,CAAC,MAAM,CAAC;IAiJZ,yBAAyB,CAC7B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EACvB,SAAS,CAAC,EAAE,MAAM,EAClB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,EAClC,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,gBAAgB,CAAC,EAAE,CAAC,iBAAiB,GAAG,SAAS,CAAC,EAAE,GACnD,OAAO,CAAC,sBAAsB,CAAC;IAiM5B,0BAA0B,CAC9B,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,EACtE,gBAAgB,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,EAC7D,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC;CA8CnB"}
@@ -270,21 +270,31 @@ ${existingResearchContext}`,
270
270
  });
271
271
  }
272
272
  async generateDocumentationRecap(libraries, documentContents, streamingOptions, retryConfig) {
273
- const prompt = `Create a concise recap of the documentation fetched for these libraries:
274
-
275
- Libraries:
276
- ${libraries
273
+ // Build variables for PromptBuilder
274
+ const librariesList = libraries
277
275
  .map((lib) => `- ${lib.name} (${lib.context7Id}): ${lib.reason}`)
278
- .join("\n")}
279
-
280
- Documentation Contents:
281
- ${documentContents
276
+ .join("\n");
277
+ const documentationContents = documentContents
282
278
  .map((doc) => `## ${doc.library}\n${doc.content.substring(0, 500)}...`)
283
- .join("\n\n")}
284
-
285
- Please provide a 2-3 sentence summary of what documentation is available and how it relates to the task.`;
279
+ .join("\n\n");
280
+ const promptResult = prompt_builder_1.PromptBuilder.buildPrompt({
281
+ name: "documentation-recap",
282
+ type: "user",
283
+ variables: {
284
+ LIBRARIES_LIST: librariesList,
285
+ DOCUMENTATION_CONTENTS: documentationContents,
286
+ },
287
+ });
288
+ if (!promptResult.success) {
289
+ throw new Error(`Failed to build documentation recap prompt: ${promptResult.error}`);
290
+ }
291
+ const systemPromptResult = prompt_builder_1.PromptBuilder.buildPrompt({
292
+ name: "documentation-recap",
293
+ type: "system",
294
+ variables: {},
295
+ });
286
296
  return this.retryHandler.executeWithRetry(async () => {
287
- return this.streamText(prompt, undefined, "You are a technical writer who creates concise summaries of documentation collections.", undefined, streamingOptions, { maxAttempts: 1 });
297
+ return this.streamText(promptResult.prompt, undefined, systemPromptResult.prompt, undefined, streamingOptions, { maxAttempts: 1 });
288
298
  }, retryConfig, "Documentation recap generation");
289
299
  }
290
300
  }
@@ -1 +1 @@
1
- {"version":3,"file":"prd-operations.d.ts","sourceRoot":"","sources":["../../../src/lib/ai-service/prd-operations.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,QAAQ,EAER,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EAIZ,MAAM,aAAa,CAAC;AAYrB,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,qBAAa,aAAc,SAAQ,cAAc;IACzC,QAAQ,CACZ,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,cAAc,CAAC,EAAE,MAAM,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,EAClC,gBAAgB,CAAC,EAAE,MAAM,EACzB,qBAAqB,CAAC,EAAE,OAAO,GAC9B,OAAO,CAAC,gBAAgB,CAAC;IAyKtB,SAAS,CACb,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,cAAc,CAAC,EAAE,MAAM,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,EAClC,gBAAgB,CAAC,EAAE,MAAM,EACzB,qBAAqB,CAAC,EAAE,OAAO,GAC9B,OAAO,CAAC,MAAM,CAAC;IAuGZ,oBAAoB,CACxB,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,cAAc,CAAC,EAAE,MAAM,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,EAClC,gBAAgB,CAAC,EAAE,MAAM,EACzB,qBAAqB,CAAC,EAAE,OAAO,GAC9B,OAAO,CAAC,MAAM,EAAE,CAAC;IAyGd,kBAAkB,CACtB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EAAE,EACnB,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,WAAW,CAAC,EAAE;QACZ,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;KAC7B,EACD,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAiF5B,WAAW,CACf,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,cAAc,CAAC,EAAE,MAAM,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC;IAqBZ,WAAW,CACf,IAAI,EAAE,MAAM,EAAE,EACd,mBAAmB,EAAE,MAAM,EAC3B,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,cAAc,CAAC,EAAE,MAAM,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC;CA0BnB"}
1
+ {"version":3,"file":"prd-operations.d.ts","sourceRoot":"","sources":["../../../src/lib/ai-service/prd-operations.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,QAAQ,EAER,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EAIZ,MAAM,aAAa,CAAC;AAYrB,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,qBAAa,aAAc,SAAQ,cAAc;IACzC,QAAQ,CACZ,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,cAAc,CAAC,EAAE,MAAM,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,EAClC,gBAAgB,CAAC,EAAE,MAAM,EACzB,qBAAqB,CAAC,EAAE,OAAO,GAC9B,OAAO,CAAC,gBAAgB,CAAC;IAyKtB,SAAS,CACb,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,cAAc,CAAC,EAAE,MAAM,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,EAClC,gBAAgB,CAAC,EAAE,MAAM,EACzB,qBAAqB,CAAC,EAAE,OAAO,GAC9B,OAAO,CAAC,MAAM,CAAC;IAuGZ,oBAAoB,CACxB,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,cAAc,CAAC,EAAE,MAAM,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,EAClC,gBAAgB,CAAC,EAAE,MAAM,EACzB,qBAAqB,CAAC,EAAE,OAAO,GAC9B,OAAO,CAAC,MAAM,EAAE,CAAC;IAyGd,kBAAkB,CACtB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EAAE,EACnB,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,WAAW,CAAC,EAAE;QACZ,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;KAC7B,EACD,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IA6E5B,WAAW,CACf,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,cAAc,CAAC,EAAE,MAAM,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC;IAqBZ,WAAW,CACf,IAAI,EAAE,MAAM,EAAE,EACd,mBAAmB,EAAE,MAAM,EAC3B,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,cAAc,CAAC,EAAE,MAAM,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC;CA0BnB"}
@@ -341,31 +341,24 @@ Use these tools to understand the current project structure, existing code patte
341
341
  ? `Project Description: ${contextInfo.projectDescription}\n`
342
342
  : ""}`
343
343
  : "";
344
- const prompt = `You are a product expert helping to clarify a PRD.
345
-
346
- PRD Content:
347
- ${prdContent}${contextText}
348
-
349
- Please answer the following questions based on the PRD and context:
350
-
351
- ${questionsText}
352
-
353
- Provide thoughtful, specific answers that will help refine the PRD.
354
- Format your response as JSON with the following structure:
355
- {
356
- "answers": {
357
- "1": "answer to question 1",
358
- "2": "answer to question 2",
359
- ...
360
- }
361
- }`;
362
- const systemPrompt = `You are a product expert analyzing PRDs and answering clarifying questions.
363
- Your answers should be:
364
- - Specific and actionable
365
- - Based on the PRD content and project context
366
- - Helpful for refining the PRD
367
- - Formatted as JSON`;
368
- const response = await this.streamText("", config, systemPrompt, prompt, streamingOptions, { maxAttempts: 1 });
344
+ const promptResult = prompt_builder_1.PromptBuilder.buildPrompt({
345
+ name: "prd-question-answer",
346
+ type: "user",
347
+ variables: {
348
+ PRD_CONTENT: prdContent,
349
+ QUESTIONS_TEXT: questionsText,
350
+ CONTEXT_TEXT: contextText,
351
+ },
352
+ });
353
+ if (!promptResult.success) {
354
+ throw new Error(`Failed to build PRD question answer prompt: ${promptResult.error}`);
355
+ }
356
+ const systemPromptResult = prompt_builder_1.PromptBuilder.buildPrompt({
357
+ name: "prd-question-answer",
358
+ type: "system",
359
+ variables: {},
360
+ });
361
+ const response = await this.streamText("", config, systemPromptResult.prompt, promptResult.prompt, streamingOptions, { maxAttempts: 1 });
369
362
  const parseResult = this.jsonParser.parseJSONFromResponse(response);
370
363
  if (!parseResult.success) {
371
364
  throw new Error(parseResult.error || "Failed to parse PRD answers response");
@@ -1 +1 @@
1
- {"version":3,"file":"opencode-executor.d.ts","sourceRoot":"","sources":["../../../src/lib/executors/opencode-executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAI/D,qBAAa,gBAAiB,YAAW,gBAAgB;IACvD,IAAI,SAAc;IAClB,OAAO,CAAC,MAAM,CAAC,CAAiB;gBAEpB,MAAM,CAAC,EAAE,cAAc;IAInC,yBAAyB,IAAI,OAAO;IAI9B,OAAO,CACX,OAAO,EAAE,MAAM,EACf,GAAG,GAAE,OAAe,EACpB,MAAM,CAAC,EAAE,cAAc,GACtB,OAAO,CAAC,IAAI,CAAC;CAuDjB"}
1
+ {"version":3,"file":"opencode-executor.d.ts","sourceRoot":"","sources":["../../../src/lib/executors/opencode-executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAI/D,qBAAa,gBAAiB,YAAW,gBAAgB;IACvD,IAAI,SAAc;IAClB,OAAO,CAAC,MAAM,CAAC,CAAiB;gBAEpB,MAAM,CAAC,EAAE,cAAc;IAInC,yBAAyB,IAAI,OAAO;IAI9B,OAAO,CACX,OAAO,EAAE,MAAM,EACf,GAAG,GAAE,OAAe,EACpB,MAAM,CAAC,EAAE,cAAc,GACtB,OAAO,CAAC,IAAI,CAAC;CA2DjB"}
@@ -38,7 +38,9 @@ class OpencodeExecutor {
38
38
  args.push("-p", message);
39
39
  if (dry) {
40
40
  console.log(chalk_1.default.cyan(`🔧 Using executor: ${this.name}`));
41
- console.log(chalk_1.default.cyan(`opencode ${args.join(" ")}`));
41
+ // Quote arguments that contain spaces for display
42
+ const quotedArgs = args.map((arg) => arg.includes(" ") ? `"${arg.replace(/"/g, '\\"')}"` : arg);
43
+ console.log(chalk_1.default.cyan(`opencode ${quotedArgs.join(" ")}`));
42
44
  return;
43
45
  }
44
46
  // Launch opencode and wait for it to complete