task-o-matic 0.0.14 → 0.0.16

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 (125) hide show
  1. package/dist/cli/display/progress.d.ts +15 -2
  2. package/dist/cli/display/progress.d.ts.map +1 -1
  3. package/dist/cli/display/progress.js +72 -4
  4. package/dist/commands/benchmark.d.ts.map +1 -1
  5. package/dist/commands/benchmark.js +11 -3
  6. package/dist/commands/init.d.ts.map +1 -1
  7. package/dist/commands/init.js +19 -4
  8. package/dist/commands/prd.js +7 -1
  9. package/dist/commands/tasks/delete.d.ts.map +1 -1
  10. package/dist/commands/tasks/delete.js +2 -1
  11. package/dist/commands/tasks/document/add.d.ts.map +1 -1
  12. package/dist/commands/tasks/document/add.js +2 -1
  13. package/dist/commands/tasks/document/get.d.ts.map +1 -1
  14. package/dist/commands/tasks/document/get.js +2 -1
  15. package/dist/commands/tasks/plan/set.d.ts.map +1 -1
  16. package/dist/commands/tasks/plan/set.js +11 -3
  17. package/dist/commands/tasks/show.d.ts.map +1 -1
  18. package/dist/commands/tasks/show.js +2 -1
  19. package/dist/commands/tasks/status.d.ts.map +1 -1
  20. package/dist/commands/tasks/status.js +2 -1
  21. package/dist/commands/tasks/update.d.ts.map +1 -1
  22. package/dist/commands/tasks/update.js +7 -1
  23. package/dist/commands/workflow.d.ts.map +1 -1
  24. package/dist/commands/workflow.js +15 -2
  25. package/dist/lib/ai-service/base-operations.d.ts +8 -0
  26. package/dist/lib/ai-service/base-operations.d.ts.map +1 -1
  27. package/dist/lib/ai-service/base-operations.js +23 -10
  28. package/dist/lib/ai-service/model-provider.d.ts.map +1 -1
  29. package/dist/lib/ai-service/model-provider.js +37 -6
  30. package/dist/lib/ai-service/prd-operations.d.ts.map +1 -1
  31. package/dist/lib/ai-service/prd-operations.js +50 -7
  32. package/dist/lib/ai-service/task-operations.d.ts +1 -0
  33. package/dist/lib/ai-service/task-operations.d.ts.map +1 -1
  34. package/dist/lib/ai-service/task-operations.js +158 -171
  35. package/dist/lib/benchmark/registry.d.ts.map +1 -1
  36. package/dist/lib/benchmark/registry.js +6 -10
  37. package/dist/lib/config-validation.d.ts +215 -0
  38. package/dist/lib/config-validation.d.ts.map +1 -0
  39. package/dist/lib/config-validation.js +246 -0
  40. package/dist/lib/config.d.ts.map +1 -1
  41. package/dist/lib/config.js +30 -7
  42. package/dist/lib/index.d.ts +1 -1
  43. package/dist/lib/index.d.ts.map +1 -1
  44. package/dist/lib/index.js +2 -1
  45. package/dist/lib/storage/file-system.d.ts.map +1 -1
  46. package/dist/lib/storage/file-system.js +81 -21
  47. package/dist/lib/task-execution-core.d.ts.map +1 -1
  48. package/dist/lib/task-execution-core.js +3 -2
  49. package/dist/services/prd.d.ts +17 -0
  50. package/dist/services/prd.d.ts.map +1 -1
  51. package/dist/services/prd.js +69 -84
  52. package/dist/services/tasks.d.ts +315 -1
  53. package/dist/services/tasks.d.ts.map +1 -1
  54. package/dist/services/tasks.js +486 -121
  55. package/dist/services/workflow-ai-assistant.d.ts.map +1 -1
  56. package/dist/services/workflow-ai-assistant.js +19 -6
  57. package/dist/services/workflow.d.ts.map +1 -1
  58. package/dist/services/workflow.js +7 -1
  59. package/dist/test/lib/ai-service/task-operations.test.d.ts +2 -0
  60. package/dist/test/lib/ai-service/task-operations.test.d.ts.map +1 -0
  61. package/dist/test/lib/ai-service/task-operations.test.js +362 -0
  62. package/dist/test/mocks/mock-ai-operations.d.ts +15 -0
  63. package/dist/test/mocks/mock-ai-operations.d.ts.map +1 -0
  64. package/dist/test/mocks/mock-ai-operations.js +107 -0
  65. package/dist/test/mocks/mock-context-builder.d.ts +10 -0
  66. package/dist/test/mocks/mock-context-builder.d.ts.map +1 -0
  67. package/dist/test/mocks/mock-context-builder.js +81 -0
  68. package/dist/test/mocks/mock-model-provider.d.ts +7 -0
  69. package/dist/test/mocks/mock-model-provider.d.ts.map +1 -0
  70. package/dist/test/mocks/mock-model-provider.js +21 -0
  71. package/dist/test/mocks/mock-service-factory.d.ts +11 -0
  72. package/dist/test/mocks/mock-service-factory.d.ts.map +1 -0
  73. package/dist/test/mocks/mock-service-factory.js +61 -0
  74. package/dist/test/mocks/mock-storage.d.ts +50 -0
  75. package/dist/test/mocks/mock-storage.d.ts.map +1 -0
  76. package/dist/test/mocks/mock-storage.js +145 -0
  77. package/dist/test/services/task-service.test.d.ts +2 -0
  78. package/dist/test/services/task-service.test.d.ts.map +1 -0
  79. package/dist/test/services/task-service.test.js +459 -0
  80. package/dist/test/test-mock-setup.d.ts +26 -0
  81. package/dist/test/test-mock-setup.d.ts.map +1 -0
  82. package/dist/test/test-mock-setup.js +41 -0
  83. package/dist/test/test-setup.d.ts +9 -0
  84. package/dist/test/test-setup.d.ts.map +1 -0
  85. package/dist/test/test-setup.js +44 -0
  86. package/dist/test/test-utils.d.ts +22 -0
  87. package/dist/test/test-utils.d.ts.map +1 -0
  88. package/dist/test/test-utils.js +37 -0
  89. package/dist/test/utils/ai-operation-utility.test.d.ts +2 -0
  90. package/dist/test/utils/ai-operation-utility.test.d.ts.map +1 -0
  91. package/dist/test/utils/ai-operation-utility.test.js +290 -0
  92. package/dist/test/utils/error-handling.test.d.ts +2 -0
  93. package/dist/test/utils/error-handling.test.d.ts.map +1 -0
  94. package/dist/test/utils/error-handling.test.js +231 -0
  95. package/dist/utils/ai-operation-utility.d.ts +142 -0
  96. package/dist/utils/ai-operation-utility.d.ts.map +1 -0
  97. package/dist/utils/ai-operation-utility.js +279 -0
  98. package/dist/utils/ai-service-factory.d.ts +10 -0
  99. package/dist/utils/ai-service-factory.d.ts.map +1 -1
  100. package/dist/utils/ai-service-factory.js +19 -1
  101. package/dist/utils/cli-validators.d.ts +2 -2
  102. package/dist/utils/cli-validators.d.ts.map +1 -1
  103. package/dist/utils/cli-validators.js +7 -6
  104. package/dist/utils/error-utils.d.ts +3 -3
  105. package/dist/utils/error-utils.d.ts.map +1 -1
  106. package/dist/utils/error-utils.js +5 -4
  107. package/dist/utils/file-utils.d.ts +27 -4
  108. package/dist/utils/file-utils.d.ts.map +1 -1
  109. package/dist/utils/file-utils.js +46 -6
  110. package/dist/utils/id-generator.d.ts +1 -1
  111. package/dist/utils/id-generator.d.ts.map +1 -1
  112. package/dist/utils/id-generator.js +8 -2
  113. package/dist/utils/metadata-utils.d.ts +40 -0
  114. package/dist/utils/metadata-utils.d.ts.map +1 -0
  115. package/dist/utils/metadata-utils.js +43 -0
  116. package/dist/utils/model-executor-parser.d.ts +1 -1
  117. package/dist/utils/model-executor-parser.d.ts.map +1 -1
  118. package/dist/utils/model-executor-parser.js +3 -2
  119. package/dist/utils/storage-utils.d.ts +3 -3
  120. package/dist/utils/storage-utils.d.ts.map +1 -1
  121. package/dist/utils/storage-utils.js +7 -6
  122. package/dist/utils/task-o-matic-error.d.ts +206 -0
  123. package/dist/utils/task-o-matic-error.d.ts.map +1 -0
  124. package/dist/utils/task-o-matic-error.js +304 -0
  125. package/package.json +7 -2
@@ -5,7 +5,20 @@ import type { ProgressEvent } from "../../types/callbacks";
5
5
  */
6
6
  export declare function displayProgress(event: ProgressEvent): void;
7
7
  /**
8
- * Display an error message
8
+ * Display an error message with full TaskOMaticError details
9
+ *
10
+ * If the error is a TaskOMaticError, displays:
11
+ * - Error code (e.g., [TASK_NOT_FOUND])
12
+ * - Error message
13
+ * - Context information
14
+ * - Actionable suggestions
15
+ * - Metadata (in verbose mode)
16
+ * - Stack trace (in debug mode)
17
+ *
18
+ * For regular errors, displays the message and stack trace.
9
19
  */
10
- export declare function displayError(error: Error | unknown): void;
20
+ export declare function displayError(error: Error | unknown, options?: {
21
+ verbose?: boolean;
22
+ debug?: boolean;
23
+ }): void;
11
24
  //# sourceMappingURL=progress.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../../src/cli/display/progress.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAuC1D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,GAAG,IAAI,CAGzD"}
1
+ {"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../../src/cli/display/progress.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAG3D;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAuC1D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,EAAE,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAmE3G"}
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.displayProgress = displayProgress;
7
7
  exports.displayError = displayError;
8
8
  const chalk_1 = __importDefault(require("chalk"));
9
+ const task_o_matic_error_1 = require("../../utils/task-o-matic-error");
9
10
  /**
10
11
  * Display progress events for the CLI
11
12
  * This function is used as a callback for services to report progress
@@ -42,9 +43,76 @@ function displayProgress(event) {
42
43
  }
43
44
  }
44
45
  /**
45
- * Display an error message
46
+ * Display an error message with full TaskOMaticError details
47
+ *
48
+ * If the error is a TaskOMaticError, displays:
49
+ * - Error code (e.g., [TASK_NOT_FOUND])
50
+ * - Error message
51
+ * - Context information
52
+ * - Actionable suggestions
53
+ * - Metadata (in verbose mode)
54
+ * - Stack trace (in debug mode)
55
+ *
56
+ * For regular errors, displays the message and stack trace.
46
57
  */
47
- function displayError(error) {
48
- const message = error instanceof Error ? error.message : "Unknown error";
49
- console.error(chalk_1.default.red("❌ Error:"), message);
58
+ function displayError(error, options) {
59
+ const verbose = options?.verbose ?? false;
60
+ const debug = options?.debug ?? process.env.DEBUG === "true";
61
+ if ((0, task_o_matic_error_1.isTaskOMaticError)(error)) {
62
+ // Display TaskOMaticError with full formatting
63
+ const taskError = error;
64
+ // Error header with code
65
+ console.error(chalk_1.default.red(`❌ [${taskError.code}] ${taskError.message}`));
66
+ // Context information
67
+ if (taskError.context) {
68
+ console.error(chalk_1.default.gray(`\nContext: ${taskError.context}`));
69
+ }
70
+ // Actionable suggestions
71
+ if (taskError.suggestions && taskError.suggestions.length > 0) {
72
+ console.error(chalk_1.default.yellow("\n💡 Suggestions:"));
73
+ taskError.suggestions.forEach((suggestion, index) => {
74
+ console.error(chalk_1.default.yellow(` ${index + 1}. ${suggestion}`));
75
+ });
76
+ }
77
+ // Metadata (only in verbose mode)
78
+ if (verbose && taskError.metadata) {
79
+ console.error(chalk_1.default.gray("\nMetadata:"));
80
+ Object.entries(taskError.metadata).forEach(([key, value]) => {
81
+ console.error(chalk_1.default.gray(` ${key}: ${JSON.stringify(value)}`));
82
+ });
83
+ }
84
+ // Cause chain
85
+ if (taskError.cause && verbose) {
86
+ console.error(chalk_1.default.gray("\nCaused by:"));
87
+ let cause = taskError.cause;
88
+ let depth = 1;
89
+ while (cause && depth <= 3) {
90
+ const causeMsg = cause instanceof Error ? cause.message : String(cause);
91
+ console.error(chalk_1.default.gray(` ${" ".repeat(depth - 1)}↳ ${causeMsg}`));
92
+ cause = cause.cause;
93
+ depth++;
94
+ }
95
+ }
96
+ // Stack trace (only in debug mode)
97
+ if (debug && taskError.stack) {
98
+ console.error(chalk_1.default.gray("\nStack trace:"));
99
+ console.error(chalk_1.default.gray(taskError.stack));
100
+ }
101
+ }
102
+ else if (error instanceof Error) {
103
+ // Regular Error object
104
+ console.error(chalk_1.default.red("❌ Error:"), error.message);
105
+ if (debug && error.stack) {
106
+ console.error(chalk_1.default.gray("\nStack trace:"));
107
+ console.error(chalk_1.default.gray(error.stack));
108
+ }
109
+ }
110
+ else {
111
+ // Unknown error type
112
+ console.error(chalk_1.default.red("❌ Unknown error:"), String(error));
113
+ }
114
+ // Footer with help hint
115
+ if (!verbose && !debug) {
116
+ console.error(chalk_1.default.gray("\n💭 Run with --verbose for more details, or --debug for stack traces"));
117
+ }
50
118
  }
@@ -1 +1 @@
1
- {"version":3,"file":"benchmark.d.ts","sourceRoot":"","sources":["../../src/commands/benchmark.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC,eAAO,MAAM,gBAAgB,SAE5B,CAAC"}
1
+ {"version":3,"file":"benchmark.d.ts","sourceRoot":"","sources":["../../src/commands/benchmark.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC,eAAO,MAAM,gBAAgB,SAE5B,CAAC"}
@@ -40,14 +40,22 @@ exports.benchmarkCommand = void 0;
40
40
  const commander_1 = require("commander");
41
41
  const chalk_1 = __importDefault(require("chalk"));
42
42
  const benchmark_1 = require("../services/benchmark");
43
+ const progress_1 = require("../cli/display/progress");
43
44
  const workflow_prompts_1 = require("../utils/workflow-prompts");
44
45
  exports.benchmarkCommand = new commander_1.Command("benchmark").description("Run and manage AI benchmarks");
46
+ const task_o_matic_error_1 = require("../utils/task-o-matic-error");
45
47
  // Helper to parse model string
46
48
  // Format: provider:model[:reasoning=<tokens>]
47
49
  function parseModelString(modelStr) {
48
50
  const parts = modelStr.split(":");
49
51
  if (parts.length < 2) {
50
- throw new Error(`Invalid model format: ${modelStr}. Expected provider:model[:reasoning=<tokens>]`);
52
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, `Invalid model format: ${modelStr}. Expected provider:model[:reasoning=<tokens>]`, {
53
+ suggestions: [
54
+ "Use the format 'provider:model'",
55
+ "Example: 'anthropic:claude-3.5-sonnet'",
56
+ "Optionally add reasoning tokens: 'openai:gpt-4:reasoning=2048'",
57
+ ],
58
+ });
51
59
  }
52
60
  const provider = parts[0];
53
61
  const model = parts[1];
@@ -192,7 +200,7 @@ exports.benchmarkCommand
192
200
  });
193
201
  }
194
202
  catch (error) {
195
- console.error(chalk_1.default.red("Benchmark failed:"), error.message);
203
+ (0, progress_1.displayError)(error);
196
204
  process.exit(1);
197
205
  }
198
206
  });
@@ -375,7 +383,7 @@ exports.benchmarkCommand
375
383
  await runWorkflowBenchmark(options);
376
384
  }
377
385
  catch (error) {
378
- console.error(chalk_1.default.red("Workflow benchmark failed:"), error.message);
386
+ (0, progress_1.displayError)(error);
379
387
  process.exit(1);
380
388
  }
381
389
  });
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,eAAO,MAAM,WAAW,SAEvB,CAAC"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,eAAO,MAAM,WAAW,SAEvB,CAAC"}
@@ -10,6 +10,8 @@ const chalk_1 = __importDefault(require("chalk"));
10
10
  const fs_1 = require("fs");
11
11
  const path_1 = require("path");
12
12
  const config_1 = require("../lib/config");
13
+ const progress_1 = require("../cli/display/progress");
14
+ const task_o_matic_error_1 = require("../utils/task-o-matic-error");
13
15
  const better_t_stack_cli_1 = require("../lib/better-t-stack-cli");
14
16
  exports.initCommand = new commander_1.Command("init").description("Initialize task-o-matic project and bootstrap projects (web/native/cli/tui)");
15
17
  // Initialize task-o-matic project
@@ -63,13 +65,20 @@ exports.initCommand
63
65
  await config_1.configManager.load();
64
66
  // Initialize task-o-matic structure in the new project directory
65
67
  await initializeProjectStructure(options);
68
+ // ... (existing code)
66
69
  }
67
70
  else {
68
- throw new Error(result.message);
71
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.UNEXPECTED_ERROR, result.message, {
72
+ context: "Bootstrap process failed. The error originated from the 'better-t-stack-cli' tool.",
73
+ suggestions: [
74
+ "Check the output from 'better-t-stack-cli' for more details.",
75
+ "Ensure that 'better-t-stack-cli' is installed and configured correctly.",
76
+ ],
77
+ });
69
78
  }
70
79
  }
71
80
  catch (error) {
72
- console.error(chalk_1.default.red("Bootstrap failed:"), error);
81
+ (0, progress_1.displayError)(error);
73
82
  return; // Stop if bootstrap fails
74
83
  }
75
84
  }
@@ -180,11 +189,17 @@ exports.initCommand
180
189
  console.log(chalk_1.default.green(result.message));
181
190
  }
182
191
  else {
183
- throw new Error(result.message);
192
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.UNEXPECTED_ERROR, result.message, {
193
+ context: "Bootstrap process failed. The error originated from the 'better-t-stack-cli' tool.",
194
+ suggestions: [
195
+ "Check the output from 'better-t-stack-cli' for more details.",
196
+ "Ensure that 'better-t-stack-cli' is installed and configured correctly.",
197
+ ],
198
+ });
184
199
  }
185
200
  }
186
201
  catch (error) {
187
- // No chdir needed anymore
202
+ (0, progress_1.displayError)(error);
188
203
  }
189
204
  });
190
205
  // Default action - show help
@@ -46,11 +46,17 @@ const prd_1 = require("../services/prd");
46
46
  const streaming_options_1 = require("../utils/streaming-options");
47
47
  const progress_1 = require("../cli/display/progress");
48
48
  exports.prdCommand = new commander_1.Command("prd").description("Manage PRDs and generate tasks");
49
+ const task_o_matic_error_1 = require("../utils/task-o-matic-error");
49
50
  // Helper to parse model string (provider:model)
50
51
  function parseModelString(modelStr) {
51
52
  const parts = modelStr.split(":");
52
53
  if (parts.length < 2) {
53
- throw new Error(`Invalid model format: ${modelStr}. Expected provider:model`);
54
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, `Invalid model format: ${modelStr}. Expected provider:model`, {
55
+ suggestions: [
56
+ "Use the format 'provider:model'",
57
+ "Example: 'anthropic:claude-3.5-sonnet'",
58
+ ],
59
+ });
54
60
  }
55
61
  return { provider: parts[0], model: parts[1] };
56
62
  }
@@ -1 +1 @@
1
- {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/delete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,eAAO,MAAM,aAAa,SAmCtB,CAAC"}
1
+ {"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/delete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,eAAO,MAAM,aAAa,SAmCtB,CAAC"}
@@ -9,6 +9,7 @@ const chalk_1 = __importDefault(require("chalk"));
9
9
  const tasks_1 = require("../../services/tasks");
10
10
  const task_1 = require("../../cli/display/task");
11
11
  const progress_1 = require("../../cli/display/progress");
12
+ const task_o_matic_error_1 = require("../../utils/task-o-matic-error");
12
13
  exports.deleteCommand = new commander_1.Command("delete")
13
14
  .description("Delete a task")
14
15
  .requiredOption("--id <id>", "Task ID to delete")
@@ -19,7 +20,7 @@ exports.deleteCommand = new commander_1.Command("delete")
19
20
  if (!options.force) {
20
21
  const task = await tasks_1.taskService.getTask(options.id);
21
22
  if (!task) {
22
- throw new Error(`Task with ID ${options.id} not found`);
23
+ throw (0, task_o_matic_error_1.formatTaskNotFoundError)(options.id);
23
24
  }
24
25
  console.log(chalk_1.default.red(`\n⚠️ Are you sure you want to delete task: ${task.title} (${task.id})?`));
25
26
  console.log(chalk_1.default.red("This action cannot be undone."));
@@ -1 +1 @@
1
- {"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../../src/commands/tasks/document/add.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,eAAO,MAAM,uBAAuB,SAyC/B,CAAC"}
1
+ {"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../../src/commands/tasks/document/add.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,eAAO,MAAM,uBAAuB,SAyC/B,CAAC"}
@@ -8,6 +8,7 @@ const commander_1 = require("commander");
8
8
  const chalk_1 = __importDefault(require("chalk"));
9
9
  const tasks_1 = require("../../../services/tasks");
10
10
  const command_error_handler_1 = require("../../../utils/command-error-handler");
11
+ const task_o_matic_error_1 = require("../../../utils/task-o-matic-error");
11
12
  exports.addDocumentationCommand = new commander_1.Command("add-documentation")
12
13
  .description("Add documentation to a task from a file")
13
14
  .requiredOption("-i, --id <id>", "Task ID")
@@ -16,7 +17,7 @@ exports.addDocumentationCommand = new commander_1.Command("add-documentation")
16
17
  .action((0, command_error_handler_1.wrapCommandHandler)("Add documentation", async (options) => {
17
18
  const task = await tasks_1.taskService.getTask(options.id);
18
19
  if (!task) {
19
- throw new Error(`Task with ID ${options.id} not found`);
20
+ throw (0, task_o_matic_error_1.formatTaskNotFoundError)(options.id);
20
21
  }
21
22
  // Check if documentation already exists
22
23
  const existingDoc = await tasks_1.taskService.getTaskDocumentation(options.id);
@@ -1 +1 @@
1
- {"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../../../src/commands/tasks/document/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,eAAO,MAAM,uBAAuB,SA2B/B,CAAC"}
1
+ {"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../../../src/commands/tasks/document/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,eAAO,MAAM,uBAAuB,SA2B/B,CAAC"}
@@ -8,13 +8,14 @@ const commander_1 = require("commander");
8
8
  const chalk_1 = __importDefault(require("chalk"));
9
9
  const tasks_1 = require("../../../services/tasks");
10
10
  const command_error_handler_1 = require("../../../utils/command-error-handler");
11
+ const task_o_matic_error_1 = require("../../../utils/task-o-matic-error");
11
12
  exports.getDocumentationCommand = new commander_1.Command("get-documentation")
12
13
  .description("Get existing documentation for a task")
13
14
  .requiredOption("--id <id>", "Task ID")
14
15
  .action((0, command_error_handler_1.wrapCommandHandler)("Get documentation", async (options) => {
15
16
  const task = await tasks_1.taskService.getTask(options.id);
16
17
  if (!task) {
17
- throw new Error(`Task with ID ${options.id} not found`);
18
+ throw (0, task_o_matic_error_1.formatTaskNotFoundError)(options.id);
18
19
  }
19
20
  const documentation = await tasks_1.taskService.getTaskDocumentation(options.id);
20
21
  if (!documentation) {
@@ -1 +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"}
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;AAWpC,eAAO,MAAM,cAAc,SAkDxB,CAAC"}
@@ -8,6 +8,7 @@ const commander_1 = require("commander");
8
8
  const chalk_1 = __importDefault(require("chalk"));
9
9
  const tasks_1 = require("../../../services/tasks");
10
10
  const command_error_handler_1 = require("../../../utils/command-error-handler");
11
+ const task_o_matic_error_1 = require("../../../utils/task-o-matic-error");
11
12
  exports.setPlanCommand = new commander_1.Command("set-plan")
12
13
  .description("Set implementation plan for a task")
13
14
  .requiredOption("--id <id>", "Task ID")
@@ -16,13 +17,20 @@ exports.setPlanCommand = new commander_1.Command("set-plan")
16
17
  .action((0, command_error_handler_1.wrapCommandHandler)("Set plan", async (options) => {
17
18
  const task = await tasks_1.taskService.getTask(options.id);
18
19
  if (!task) {
19
- throw new Error(`Task with ID ${options.id} not found`);
20
+ throw (0, task_o_matic_error_1.formatTaskNotFoundError)(options.id);
20
21
  }
21
22
  if (!options.plan && !options.planFile) {
22
- throw new Error("Either --plan or --plan-file must be specified");
23
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, "Either --plan or --plan-file must be specified", {
24
+ suggestions: [
25
+ "Provide the plan directly using --plan '...' ",
26
+ "Provide a file containing the plan using --plan-file <path>",
27
+ ],
28
+ });
23
29
  }
24
30
  if (options.plan && options.planFile) {
25
- throw new Error("Cannot specify both --plan and --plan-file");
31
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, "Cannot specify both --plan and --plan-file", {
32
+ suggestions: ["Provide either --plan or --plan-file, but not both."],
33
+ });
26
34
  }
27
35
  const result = await tasks_1.taskService.setTaskPlan(options.id, options.plan || undefined, options.planFile || undefined);
28
36
  console.log(chalk_1.default.green(`✓ Plan set for task: ${task.title} (${options.id})`));
@@ -1 +1 @@
1
- {"version":3,"file":"show.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/show.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,WAAW,SAgBpB,CAAC"}
1
+ {"version":3,"file":"show.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/show.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,eAAO,MAAM,WAAW,SAgBpB,CAAC"}
@@ -5,6 +5,7 @@ const commander_1 = require("commander");
5
5
  const tasks_1 = require("../../services/tasks");
6
6
  const task_1 = require("../../cli/display/task");
7
7
  const progress_1 = require("../../cli/display/progress");
8
+ const task_o_matic_error_1 = require("../../utils/task-o-matic-error");
8
9
  exports.showCommand = new commander_1.Command("show")
9
10
  .description("Show detailed information about a task")
10
11
  .requiredOption("--id <id>", "Task ID")
@@ -12,7 +13,7 @@ exports.showCommand = new commander_1.Command("show")
12
13
  try {
13
14
  const task = await tasks_1.taskService.getTask(options.id);
14
15
  if (!task) {
15
- throw new Error(`Task with ID ${options.id} not found`);
16
+ throw (0, task_o_matic_error_1.formatTaskNotFoundError)(options.id);
16
17
  }
17
18
  await (0, task_1.displayTaskDetails)(task);
18
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,aAAa,SAyBtB,CAAC"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,eAAO,MAAM,aAAa,SAyBtB,CAAC"}
@@ -5,6 +5,7 @@ const commander_1 = require("commander");
5
5
  const tasks_1 = require("../../services/tasks");
6
6
  const task_1 = require("../../cli/display/task");
7
7
  const progress_1 = require("../../cli/display/progress");
8
+ const task_o_matic_error_1 = require("../../utils/task-o-matic-error");
8
9
  exports.statusCommand = new commander_1.Command("status")
9
10
  .description("Set task status")
10
11
  .requiredOption("-i, --id <id>", "Task ID")
@@ -13,7 +14,7 @@ exports.statusCommand = new commander_1.Command("status")
13
14
  try {
14
15
  const task = await tasks_1.taskService.getTask(options.id);
15
16
  if (!task) {
16
- throw new Error(`Task with ID ${options.id} not found`);
17
+ throw (0, task_o_matic_error_1.formatTaskNotFoundError)(options.id);
17
18
  }
18
19
  const oldStatus = task.status;
19
20
  const updatedTask = await tasks_1.taskService.setTaskStatus(options.id, options.status);
@@ -1 +1 @@
1
- {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,aAAa,SA4BtB,CAAC"}
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/commands/tasks/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,eAAO,MAAM,aAAa,SAqCtB,CAAC"}
@@ -5,6 +5,7 @@ const commander_1 = require("commander");
5
5
  const tasks_1 = require("../../services/tasks");
6
6
  const task_1 = require("../../cli/display/task");
7
7
  const progress_1 = require("../../cli/display/progress");
8
+ const task_o_matic_error_1 = require("../../utils/task-o-matic-error");
8
9
  exports.updateCommand = new commander_1.Command("update")
9
10
  .description("Update an existing task")
10
11
  .requiredOption("--id <id>", "Task ID to update")
@@ -17,7 +18,12 @@ exports.updateCommand = new commander_1.Command("update")
17
18
  try {
18
19
  const { id, ...updates } = options;
19
20
  if (Object.keys(updates).length === 0) {
20
- throw new Error("At least one field must be specified for update");
21
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, "At least one field must be specified for update", {
22
+ suggestions: [
23
+ "Specify a field to update, e.g., --title 'New Title'",
24
+ "Use --help for a list of available options",
25
+ ],
26
+ });
21
27
  }
22
28
  const updatedTask = await tasks_1.taskService.updateTask(id, {
23
29
  title: updates.title,
@@ -1 +1 @@
1
- {"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../src/commands/workflow.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsBpC,eAAO,MAAM,eAAe,SAsKxB,CAAC"}
1
+ {"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../src/commands/workflow.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0BpC,eAAO,MAAM,eAAe,SAsKxB,CAAC"}
@@ -48,6 +48,7 @@ const inquirer_1 = __importDefault(require("inquirer"));
48
48
  const workflow_prompts_1 = require("../utils/workflow-prompts");
49
49
  const streaming_options_1 = require("../utils/streaming-options");
50
50
  const progress_1 = require("../cli/display/progress");
51
+ const task_o_matic_error_1 = require("../utils/task-o-matic-error");
51
52
  exports.workflowCommand = new commander_1.Command("workflow")
52
53
  .description("Interactive workflow for complete project setup and task management")
53
54
  // Existing AI options
@@ -336,7 +337,13 @@ async function stepDefinePRD(state, options, streamingOptions) {
336
337
  multiGenerationModels = modelsInput.split(",").map((m) => {
337
338
  const parts = m.trim().split(":");
338
339
  if (parts.length < 2) {
339
- throw new Error(`Invalid model format: ${m}. Expected provider:model`);
340
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.WORKFLOW_EXECUTION_ERROR, `Invalid model format: ${m}. Expected provider:model`, {
341
+ context: "Model format validation failed during multi-generation setup",
342
+ suggestions: [
343
+ "Use format: provider:model (e.g., anthropic:claude-sonnet-4.5)",
344
+ "Check for typos in provider or model name",
345
+ ],
346
+ });
340
347
  }
341
348
  return { provider: parts[0], model: parts[1] };
342
349
  });
@@ -347,7 +354,13 @@ async function stepDefinePRD(state, options, streamingOptions) {
347
354
  if (combineModelInput && combineModelInput.trim()) {
348
355
  const parts = combineModelInput.trim().split(":");
349
356
  if (parts.length < 2) {
350
- throw new Error(`Invalid model format: ${combineModelInput}. Expected provider:model`);
357
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.WORKFLOW_EXECUTION_ERROR, `Invalid model format: ${combineModelInput}. Expected provider:model`, {
358
+ context: "Model format validation failed during PRD combine setup",
359
+ suggestions: [
360
+ "Use format: provider:model (e.g., anthropic:claude-sonnet-4.5)",
361
+ "Check for typos in provider or model name",
362
+ ],
363
+ });
351
364
  }
352
365
  combineAI = { provider: parts[0], model: parts[1] };
353
366
  }
@@ -30,6 +30,14 @@ export declare class BaseOperations {
30
30
  * ```
31
31
  */
32
32
  protected mergeAIConfig(config?: Partial<AIConfig>): AIConfig;
33
+ /**
34
+ * Handles Context7 tool results by caching documentation.
35
+ * Extracts and saves documentation from get-library-docs tool results.
36
+ *
37
+ * @param chunk - The chunk to check for Context7 tool results
38
+ * @protected
39
+ */
40
+ protected handleContext7ToolResult(chunk: any): void;
33
41
  streamText(prompt: string, config?: Partial<AIConfig>, systemPrompt?: string, userMessage?: string, streamingOptions?: StreamingOptions, retryConfig?: Partial<RetryConfig>): Promise<string>;
34
42
  }
35
43
  //# sourceMappingURL=base-operations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"base-operations.d.ts","sourceRoot":"","sources":["../../../src/lib/ai-service/base-operations.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,qBAAa,cAAc;IACzB,SAAS,CAAC,UAAU,aAAoB;IACxC,SAAS,CAAC,cAAc,iBAAwB;IAChD,SAAS,CAAC,YAAY,eAAsB;IAC5C,SAAS,CAAC,aAAa,gBAAuB;IAE9C;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,SAAS,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ;IAQvD,UAAU,CACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,YAAY,CAAC,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC;CAgFnB"}
1
+ {"version":3,"file":"base-operations.d.ts","sourceRoot":"","sources":["../../../src/lib/ai-service/base-operations.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,qBAAa,cAAc;IACzB,SAAS,CAAC,UAAU,aAAoB;IACxC,SAAS,CAAC,cAAc,iBAAwB;IAChD,SAAS,CAAC,YAAY,eAAsB;IAC5C,SAAS,CAAC,aAAa,gBAAuB;IAE9C;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,SAAS,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ;IAQ7D;;;;;;OAMG;IACH,SAAS,CAAC,wBAAwB,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI;IAqB9C,UAAU,CACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,YAAY,CAAC,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC;CAgEnB"}
@@ -38,6 +38,27 @@ class BaseOperations {
38
38
  // Apply operation-specific overrides (highest priority)
39
39
  return { ...baseConfig, ...config };
40
40
  }
41
+ /**
42
+ * Handles Context7 tool results by caching documentation.
43
+ * Extracts and saves documentation from get-library-docs tool results.
44
+ *
45
+ * @param chunk - The chunk to check for Context7 tool results
46
+ * @protected
47
+ */
48
+ handleContext7ToolResult(chunk) {
49
+ if (chunk.type === "tool-result" &&
50
+ chunk.toolName === "get-library-docs") {
51
+ const docs = chunk.output;
52
+ const libraryID = chunk.input?.context7CompatibleLibraryID || "unknown";
53
+ const topic = chunk.input?.topic || "general";
54
+ if (docs && typeof docs === "object" && "content" in docs) {
55
+ this.context7Client.saveContext7Documentation(libraryID, docs.content, topic);
56
+ }
57
+ else if (docs && typeof docs === "string") {
58
+ this.context7Client.saveContext7Documentation(libraryID, docs, topic);
59
+ }
60
+ }
61
+ }
41
62
  async streamText(prompt, config, systemPrompt, userMessage, streamingOptions, retryConfig) {
42
63
  // Merge config with proper precedence (Bug fix 2.9)
43
64
  const aiConfig = this.mergeAIConfig(config);
@@ -60,16 +81,8 @@ class BaseOperations {
60
81
  else if (chunk.type === "reasoning-delta") {
61
82
  streamingOptions.onReasoning?.(chunk.text);
62
83
  }
63
- else if (chunk.type === "tool-result" &&
64
- chunk.toolName === "get-library-docs") {
65
- const docs = chunk.output;
66
- if (docs && typeof docs === "object" && "content" in docs) {
67
- this.context7Client.saveContext7Documentation(chunk.input?.context7CompatibleLibraryID || "unknown", docs.content, chunk.input?.topic || "general");
68
- }
69
- else if (docs && typeof docs === "string") {
70
- this.context7Client.saveContext7Documentation(chunk.input?.context7CompatibleLibraryID || "unknown", docs, chunk.input?.topic || "general");
71
- }
72
- }
84
+ // Handle Context7 tool result caching
85
+ this.handleContext7ToolResult(chunk);
73
86
  }
74
87
  : undefined,
75
88
  onFinish: streamingOptions?.onFinish
@@ -1 +1 @@
1
- {"version":3,"file":"model-provider.d.ts","sourceRoot":"","sources":["../../../src/lib/ai-service/model-provider.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,qBAAa,aAAa;IACjB,WAAW,IAAI,QAAQ;IAY9B,OAAO,CAAC,YAAY;IAsBpB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,eAAe;CA+B9C"}
1
+ {"version":3,"file":"model-provider.d.ts","sourceRoot":"","sources":["../../../src/lib/ai-service/model-provider.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAOvC,qBAAa,aAAa;IACjB,WAAW,IAAI,QAAQ;IAY9B,OAAO,CAAC,YAAY;IAsBpB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,eAAe;CA0F9C"}
@@ -6,6 +6,7 @@ const anthropic_1 = require("@ai-sdk/anthropic");
6
6
  const openai_compatible_1 = require("@ai-sdk/openai-compatible");
7
7
  const ai_sdk_provider_1 = require("@openrouter/ai-sdk-provider");
8
8
  const config_1 = require("../config");
9
+ const task_o_matic_error_1 = require("../../utils/task-o-matic-error");
9
10
  class ModelProvider {
10
11
  getAIConfig() {
11
12
  const config = config_1.configManager.getAIConfig();
@@ -41,22 +42,47 @@ class ModelProvider {
41
42
  switch (provider) {
42
43
  case "openai":
43
44
  if (!apiKey)
44
- throw new Error("OpenAI API key is required");
45
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.AI_CONFIGURATION_ERROR, "OpenAI API key is required", {
46
+ suggestions: [
47
+ "Set the OPENAI_API_KEY environment variable.",
48
+ "Run `task-o-matic config set-ai-key <key>`",
49
+ ],
50
+ });
45
51
  return (0, openai_1.openai)(model);
46
52
  case "anthropic":
47
53
  if (!apiKey)
48
- throw new Error("Anthropic API key is required");
54
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.AI_CONFIGURATION_ERROR, "Anthropic API key is required", {
55
+ suggestions: [
56
+ "Set the ANTHROPIC_API_KEY environment variable.",
57
+ "Run `task-o-matic config set-ai-key <key>`",
58
+ ],
59
+ });
49
60
  return (0, anthropic_1.anthropic)(model);
50
61
  case "openrouter":
51
62
  if (!apiKey)
52
- throw new Error("OpenRouter API key is required");
63
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.AI_CONFIGURATION_ERROR, "OpenRouter API key is required", {
64
+ suggestions: [
65
+ "Set the OPENROUTER_API_KEY environment variable.",
66
+ "Run `task-o-matic config set-ai-key <key>`",
67
+ ],
68
+ });
53
69
  const openRouterProvider = (0, ai_sdk_provider_1.createOpenRouter)({ apiKey });
54
70
  return openRouterProvider(model);
55
71
  case "custom":
56
72
  if (!apiKey)
57
- throw new Error("Custom API key is required");
73
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.AI_CONFIGURATION_ERROR, "Custom API key is required for custom provider", {
74
+ suggestions: [
75
+ "Set the CUSTOM_API_KEY environment variable.",
76
+ "Run `task-o-matic config set-ai-key <key>`",
77
+ ],
78
+ });
58
79
  if (!baseURL)
59
- throw new Error("Custom provider requires baseURL");
80
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.AI_CONFIGURATION_ERROR, "Custom provider requires baseURL", {
81
+ suggestions: [
82
+ "Set the CUSTOM_API_URL environment variable.",
83
+ "Run `task-o-matic config set-ai-provider-url <url>`",
84
+ ],
85
+ });
60
86
  const customProvider = (0, openai_compatible_1.createOpenAICompatible)({
61
87
  name: "custom",
62
88
  apiKey,
@@ -64,7 +90,12 @@ class ModelProvider {
64
90
  });
65
91
  return customProvider(model);
66
92
  default:
67
- throw new Error(`Unsupported provider: ${provider}`);
93
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.AI_CONFIGURATION_ERROR, `Unsupported provider: ${provider}`, {
94
+ suggestions: [
95
+ "Use one of the supported providers: 'openai', 'anthropic', 'openrouter', 'custom'.",
96
+ "Run `task-o-matic config set-ai-provider <provider>`",
97
+ ],
98
+ });
68
99
  }
69
100
  }
70
101
  }