task-o-matic 0.0.13 → 0.0.15

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 (144) 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 +60 -12
  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 +5 -4
  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/list.js +2 -2
  16. package/dist/commands/tasks/next.js +4 -4
  17. package/dist/commands/tasks/plan/set.d.ts.map +1 -1
  18. package/dist/commands/tasks/plan/set.js +11 -3
  19. package/dist/commands/tasks/show.d.ts.map +1 -1
  20. package/dist/commands/tasks/show.js +2 -1
  21. package/dist/commands/tasks/status.d.ts.map +1 -1
  22. package/dist/commands/tasks/status.js +4 -3
  23. package/dist/commands/tasks/update.d.ts.map +1 -1
  24. package/dist/commands/tasks/update.js +7 -1
  25. package/dist/lib/ai-service/ai-operations.d.ts +1 -1
  26. package/dist/lib/ai-service/ai-operations.d.ts.map +1 -1
  27. package/dist/lib/ai-service/base-operations.d.ts +22 -0
  28. package/dist/lib/ai-service/base-operations.d.ts.map +1 -1
  29. package/dist/lib/ai-service/base-operations.js +29 -1
  30. package/dist/lib/ai-service/model-provider.d.ts.map +1 -1
  31. package/dist/lib/ai-service/model-provider.js +37 -6
  32. package/dist/lib/ai-service/task-operations.d.ts +2 -1
  33. package/dist/lib/ai-service/task-operations.d.ts.map +1 -1
  34. package/dist/lib/ai-service/task-operations.js +135 -173
  35. package/dist/lib/benchmark/registry.d.ts.map +1 -1
  36. package/dist/lib/benchmark/registry.js +6 -10
  37. package/dist/lib/better-t-stack-cli.d.ts +36 -21
  38. package/dist/lib/better-t-stack-cli.d.ts.map +1 -1
  39. package/dist/lib/better-t-stack-cli.js +212 -33
  40. package/dist/lib/bootstrap/cli-bootstrap.d.ts +14 -0
  41. package/dist/lib/bootstrap/cli-bootstrap.d.ts.map +1 -0
  42. package/dist/lib/bootstrap/cli-bootstrap.js +325 -0
  43. package/dist/lib/bootstrap/index.d.ts +4 -0
  44. package/dist/lib/bootstrap/index.d.ts.map +1 -0
  45. package/dist/lib/bootstrap/index.js +19 -0
  46. package/dist/lib/bootstrap/medusa-bootstrap.d.ts +14 -0
  47. package/dist/lib/bootstrap/medusa-bootstrap.d.ts.map +1 -0
  48. package/dist/lib/bootstrap/medusa-bootstrap.js +218 -0
  49. package/dist/lib/bootstrap/opentui-bootstrap.d.ts +11 -0
  50. package/dist/lib/bootstrap/opentui-bootstrap.d.ts.map +1 -0
  51. package/dist/lib/bootstrap/opentui-bootstrap.js +342 -0
  52. package/dist/lib/config-validation.d.ts +215 -0
  53. package/dist/lib/config-validation.d.ts.map +1 -0
  54. package/dist/lib/config-validation.js +246 -0
  55. package/dist/lib/config.d.ts +14 -0
  56. package/dist/lib/config.d.ts.map +1 -1
  57. package/dist/lib/config.js +37 -5
  58. package/dist/lib/storage/file-system.d.ts.map +1 -1
  59. package/dist/lib/storage/file-system.js +81 -21
  60. package/dist/lib/task-execution-core.d.ts.map +1 -1
  61. package/dist/lib/task-execution-core.js +3 -2
  62. package/dist/services/prd.d.ts +17 -0
  63. package/dist/services/prd.d.ts.map +1 -1
  64. package/dist/services/prd.js +67 -60
  65. package/dist/services/tasks.d.ts +317 -3
  66. package/dist/services/tasks.d.ts.map +1 -1
  67. package/dist/services/tasks.js +531 -185
  68. package/dist/services/workflow-ai-assistant.d.ts.map +1 -1
  69. package/dist/services/workflow-ai-assistant.js +19 -6
  70. package/dist/test/lib/ai-service/task-operations.test.d.ts +2 -0
  71. package/dist/test/lib/ai-service/task-operations.test.d.ts.map +1 -0
  72. package/dist/test/lib/ai-service/task-operations.test.js +362 -0
  73. package/dist/test/mocks/mock-ai-operations.d.ts +15 -0
  74. package/dist/test/mocks/mock-ai-operations.d.ts.map +1 -0
  75. package/dist/test/mocks/mock-ai-operations.js +107 -0
  76. package/dist/test/mocks/mock-context-builder.d.ts +10 -0
  77. package/dist/test/mocks/mock-context-builder.d.ts.map +1 -0
  78. package/dist/test/mocks/mock-context-builder.js +81 -0
  79. package/dist/test/mocks/mock-model-provider.d.ts +7 -0
  80. package/dist/test/mocks/mock-model-provider.d.ts.map +1 -0
  81. package/dist/test/mocks/mock-model-provider.js +21 -0
  82. package/dist/test/mocks/mock-service-factory.d.ts +11 -0
  83. package/dist/test/mocks/mock-service-factory.d.ts.map +1 -0
  84. package/dist/test/mocks/mock-service-factory.js +61 -0
  85. package/dist/test/mocks/mock-storage.d.ts +50 -0
  86. package/dist/test/mocks/mock-storage.d.ts.map +1 -0
  87. package/dist/test/mocks/mock-storage.js +145 -0
  88. package/dist/test/services/task-service.test.d.ts +2 -0
  89. package/dist/test/services/task-service.test.d.ts.map +1 -0
  90. package/dist/test/services/task-service.test.js +352 -0
  91. package/dist/test/test-mock-setup.d.ts +26 -0
  92. package/dist/test/test-mock-setup.d.ts.map +1 -0
  93. package/dist/test/test-mock-setup.js +41 -0
  94. package/dist/test/test-setup.d.ts +9 -0
  95. package/dist/test/test-setup.d.ts.map +1 -0
  96. package/dist/test/test-setup.js +44 -0
  97. package/dist/test/test-utils.d.ts +22 -0
  98. package/dist/test/test-utils.d.ts.map +1 -0
  99. package/dist/test/test-utils.js +37 -0
  100. package/dist/test/utils/ai-operation-utility.test.d.ts +2 -0
  101. package/dist/test/utils/ai-operation-utility.test.d.ts.map +1 -0
  102. package/dist/test/utils/ai-operation-utility.test.js +290 -0
  103. package/dist/test/utils/error-handling.test.d.ts +2 -0
  104. package/dist/test/utils/error-handling.test.d.ts.map +1 -0
  105. package/dist/test/utils/error-handling.test.js +231 -0
  106. package/dist/types/index.d.ts +36 -1
  107. package/dist/types/index.d.ts.map +1 -1
  108. package/dist/types/results.d.ts +60 -6
  109. package/dist/types/results.d.ts.map +1 -1
  110. package/dist/utils/ai-operation-utility.d.ts +142 -0
  111. package/dist/utils/ai-operation-utility.d.ts.map +1 -0
  112. package/dist/utils/ai-operation-utility.js +288 -0
  113. package/dist/utils/ai-service-factory.d.ts +10 -0
  114. package/dist/utils/ai-service-factory.d.ts.map +1 -1
  115. package/dist/utils/ai-service-factory.js +19 -1
  116. package/dist/utils/cli-validators.d.ts +2 -2
  117. package/dist/utils/cli-validators.d.ts.map +1 -1
  118. package/dist/utils/cli-validators.js +7 -6
  119. package/dist/utils/error-utils.d.ts +70 -0
  120. package/dist/utils/error-utils.d.ts.map +1 -0
  121. package/dist/utils/error-utils.js +104 -0
  122. package/dist/utils/file-utils.d.ts +49 -0
  123. package/dist/utils/file-utils.d.ts.map +1 -0
  124. package/dist/utils/file-utils.js +82 -0
  125. package/dist/utils/id-generator.d.ts +92 -0
  126. package/dist/utils/id-generator.d.ts.map +1 -0
  127. package/dist/utils/id-generator.js +146 -0
  128. package/dist/utils/model-executor-parser.d.ts +1 -1
  129. package/dist/utils/model-executor-parser.d.ts.map +1 -1
  130. package/dist/utils/model-executor-parser.js +3 -2
  131. package/dist/utils/stack-formatter.d.ts +2 -1
  132. package/dist/utils/stack-formatter.d.ts.map +1 -1
  133. package/dist/utils/stack-formatter.js +8 -2
  134. package/dist/utils/storage-utils.d.ts +49 -0
  135. package/dist/utils/storage-utils.d.ts.map +1 -0
  136. package/dist/utils/storage-utils.js +80 -0
  137. package/dist/utils/streaming-utils.d.ts +38 -0
  138. package/dist/utils/streaming-utils.d.ts.map +1 -0
  139. package/dist/utils/streaming-utils.js +56 -0
  140. package/dist/utils/task-o-matic-error.d.ts +206 -0
  141. package/dist/utils/task-o-matic-error.d.ts.map +1 -0
  142. package/dist/utils/task-o-matic-error.js +304 -0
  143. package/docs/agents/cli.md +58 -149
  144. package/package.json +2 -2
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.validateMutuallyExclusive = validateMutuallyExclusive;
4
4
  exports.validateOneRequired = validateOneRequired;
5
5
  exports.parseCsvOption = parseCsvOption;
6
+ const task_o_matic_error_1 = require("./task-o-matic-error");
6
7
  /**
7
8
  * Validate that exactly one of two mutually exclusive options is provided
8
9
  *
@@ -11,7 +12,7 @@ exports.parseCsvOption = parseCsvOption;
11
12
  * @param field2 - Second field name in options
12
13
  * @param field1Label - Display label for first field (defaults to field1)
13
14
  * @param field2Label - Display label for second field (defaults to field2)
14
- * @throws Error if neither or both fields are provided
15
+ * @throws TaskOMaticError if neither or both fields are provided
15
16
  *
16
17
  * @example
17
18
  * ```typescript
@@ -22,10 +23,10 @@ function validateMutuallyExclusive(options, field1, field2, field1Label = field1
22
23
  const has1 = Boolean(options[field1]);
23
24
  const has2 = Boolean(options[field2]);
24
25
  if (!has1 && !has2) {
25
- throw new Error(`Either --${field1Label} or --${field2Label} must be specified`);
26
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, `Either --${field1Label} or --${field2Label} must be specified`);
26
27
  }
27
28
  if (has1 && has2) {
28
- throw new Error(`Cannot specify both --${field1Label} and --${field2Label}`);
29
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, `Cannot specify both --${field1Label} and --${field2Label}`);
29
30
  }
30
31
  }
31
32
  /**
@@ -33,7 +34,7 @@ function validateMutuallyExclusive(options, field1, field2, field1Label = field1
33
34
  *
34
35
  * @param options - The command options object
35
36
  * @param fields - Array of field specifications
36
- * @throws Error if none or multiple fields are provided
37
+ * @throws TaskOMaticError if none or multiple fields are provided
37
38
  *
38
39
  * @example
39
40
  * ```typescript
@@ -48,11 +49,11 @@ function validateOneRequired(options, ...fields) {
48
49
  const provided = fields.filter((f) => Boolean(options[f.name]));
49
50
  if (provided.length === 0) {
50
51
  const labels = fields.map((f) => `--${f.label}`).join(", ");
51
- throw new Error(`One of ${labels} must be specified`);
52
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, `One of ${labels} must be specified`);
52
53
  }
53
54
  if (provided.length > 1) {
54
55
  const labels = provided.map((f) => `--${f.label}`).join(", ");
55
- throw new Error(`Cannot specify multiple options: ${labels}`);
56
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, `Cannot specify multiple options: ${labels}`);
56
57
  }
57
58
  }
58
59
  /**
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Extracts a readable error message from an unknown error value.
3
+ * Handles Error objects, strings, objects with message property, and unknown types.
4
+ *
5
+ * @param error - The error value to extract message from
6
+ * @returns A string error message
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * try {
11
+ * throw new Error("Something went wrong");
12
+ * } catch (error) {
13
+ * console.log(getErrorMessage(error)); // "Something went wrong"
14
+ * }
15
+ * ```
16
+ */
17
+ export declare function getErrorMessage(error: unknown): string;
18
+ /**
19
+ * Formats an error with optional context information.
20
+ * Useful for adding context to error messages when rethrowing.
21
+ *
22
+ * @param error - The error value
23
+ * @param context - Optional context string to prepend to the error message
24
+ * @returns Formatted error message
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * try {
29
+ * await fetchData();
30
+ * } catch (error) {
31
+ * throw new Error(formatError(error, "Failed to fetch data"));
32
+ * // Result: "Failed to fetch data: Connection timeout"
33
+ * }
34
+ * ```
35
+ */
36
+ export declare function formatError(error: unknown, context?: string): string;
37
+ /**
38
+ * Creates an error with a formatted message including context.
39
+ *
40
+ * @param error - The original error
41
+ * @param context - Context to add to the error
42
+ * @returns A new TaskOMaticError instance with formatted message
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * try {
47
+ * await operation();
48
+ * } catch (error) {
49
+ * throw createContextError(error, "Operation failed");
50
+ * }
51
+ * ```
52
+ */
53
+ export declare function createContextError(error: unknown, context: string): import("./task-o-matic-error").TaskOMaticError;
54
+ /**
55
+ * Type guard to check if an error is an Error instance.
56
+ *
57
+ * @param error - Value to check
58
+ * @returns true if error is an Error instance
59
+ */
60
+ export declare function isError(error: unknown): error is Error;
61
+ /**
62
+ * Safely converts any value to an Error instance.
63
+ * If the value is already an Error, returns it unchanged.
64
+ * Otherwise, creates a new Error with the string representation.
65
+ *
66
+ * @param error - Value to convert
67
+ * @returns An Error instance
68
+ */
69
+ export declare function toError(error: unknown): import("./task-o-matic-error").TaskOMaticError;
70
+ //# sourceMappingURL=error-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-utils.d.ts","sourceRoot":"","sources":["../../src/utils/error-utils.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAkBtD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAGpE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,MAAM,GACd,OAAO,sBAAsB,EAAE,eAAe,CAMhD;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,KAAK,CAEtD;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CACrB,KAAK,EAAE,OAAO,GACb,OAAO,sBAAsB,EAAE,eAAe,CAYhD"}
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getErrorMessage = getErrorMessage;
4
+ exports.formatError = formatError;
5
+ exports.createContextError = createContextError;
6
+ exports.isError = isError;
7
+ exports.toError = toError;
8
+ const task_o_matic_error_1 = require("./task-o-matic-error");
9
+ /**
10
+ * Extracts a readable error message from an unknown error value.
11
+ * Handles Error objects, strings, objects with message property, and unknown types.
12
+ *
13
+ * @param error - The error value to extract message from
14
+ * @returns A string error message
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * try {
19
+ * throw new Error("Something went wrong");
20
+ * } catch (error) {
21
+ * console.log(getErrorMessage(error)); // "Something went wrong"
22
+ * }
23
+ * ```
24
+ */
25
+ function getErrorMessage(error) {
26
+ // Error instance
27
+ if (error instanceof Error) {
28
+ return error.message;
29
+ }
30
+ // String error
31
+ if (typeof error === "string") {
32
+ return error;
33
+ }
34
+ // Object with message property
35
+ if (error && typeof error === "object" && "message" in error) {
36
+ return String(error.message);
37
+ }
38
+ // Unknown type - convert to string
39
+ return "Unknown error occurred";
40
+ }
41
+ /**
42
+ * Formats an error with optional context information.
43
+ * Useful for adding context to error messages when rethrowing.
44
+ *
45
+ * @param error - The error value
46
+ * @param context - Optional context string to prepend to the error message
47
+ * @returns Formatted error message
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * try {
52
+ * await fetchData();
53
+ * } catch (error) {
54
+ * throw new Error(formatError(error, "Failed to fetch data"));
55
+ * // Result: "Failed to fetch data: Connection timeout"
56
+ * }
57
+ * ```
58
+ */
59
+ function formatError(error, context) {
60
+ const message = getErrorMessage(error);
61
+ return context ? `${context}: ${message}` : message;
62
+ }
63
+ /**
64
+ * Creates an error with a formatted message including context.
65
+ *
66
+ * @param error - The original error
67
+ * @param context - Context to add to the error
68
+ * @returns A new TaskOMaticError instance with formatted message
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * try {
73
+ * await operation();
74
+ * } catch (error) {
75
+ * throw createContextError(error, "Operation failed");
76
+ * }
77
+ * ```
78
+ */
79
+ function createContextError(error, context) {
80
+ return (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.UNEXPECTED_ERROR, formatError(error, context), { cause: error instanceof Error ? error : undefined });
81
+ }
82
+ /**
83
+ * Type guard to check if an error is an Error instance.
84
+ *
85
+ * @param error - Value to check
86
+ * @returns true if error is an Error instance
87
+ */
88
+ function isError(error) {
89
+ return error instanceof Error;
90
+ }
91
+ /**
92
+ * Safely converts any value to an Error instance.
93
+ * If the value is already an Error, returns it unchanged.
94
+ * Otherwise, creates a new Error with the string representation.
95
+ *
96
+ * @param error - Value to convert
97
+ * @returns An Error instance
98
+ */
99
+ function toError(error) {
100
+ if (error instanceof Error) {
101
+ return (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.UNEXPECTED_ERROR, error.message, { cause: error });
102
+ }
103
+ return (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.UNEXPECTED_ERROR, getErrorMessage(error));
104
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Validates that a file exists at the given path (synchronous).
3
+ * Throws an error with a custom message if the file doesn't exist.
4
+ *
5
+ * @param filePath - Path to the file to validate
6
+ * @param customMessage - Optional custom error message
7
+ * @throws TaskOMaticError if file doesn't exist
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * validateFileExists("./config.json", "Configuration file not found");
12
+ * // Throws: TaskOMaticError with code INVALID_INPUT if file doesn't exist
13
+ * ```
14
+ */
15
+ export declare function validateFileExists(filePath: string, customMessage?: string): void;
16
+ /**
17
+ * Validates that a file exists at the given path (asynchronous).
18
+ * Throws an error with a custom message if the file doesn't exist.
19
+ *
20
+ * @param filePath - Path to the file to validate
21
+ * @param customMessage - Optional custom error message
22
+ * @throws TaskOMaticError if file doesn't exist
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * await validateFileExistsAsync("./data.json");
27
+ * // Throws: TaskOMaticError with code INVALID_INPUT if file doesn't exist
28
+ * ```
29
+ */
30
+ export declare function validateFileExistsAsync(filePath: string, customMessage?: string): Promise<void>;
31
+ /**
32
+ * Checks if a file exists at the given path (synchronous).
33
+ * Returns true if file exists, false otherwise.
34
+ * Unlike validateFileExists, this doesn't throw an error.
35
+ *
36
+ * @param filePath - Path to check
37
+ * @returns true if file exists, false otherwise
38
+ */
39
+ export declare function fileExists(filePath: string): boolean;
40
+ /**
41
+ * Checks if a file exists at the given path (asynchronous).
42
+ * Returns true if file exists, false otherwise.
43
+ * Unlike validateFileExistsAsync, this doesn't throw an error.
44
+ *
45
+ * @param filePath - Path to check
46
+ * @returns Promise resolving to true if file exists, false otherwise
47
+ */
48
+ export declare function fileExistsAsync(filePath: string): Promise<boolean>;
49
+ //# sourceMappingURL=file-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-utils.d.ts","sourceRoot":"","sources":["../../src/utils/file-utils.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,aAAa,CAAC,EAAE,MAAM,GACrB,IAAI,CAUN;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,MAAM,EAChB,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOxE"}
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateFileExists = validateFileExists;
4
+ exports.validateFileExistsAsync = validateFileExistsAsync;
5
+ exports.fileExists = fileExists;
6
+ exports.fileExistsAsync = fileExistsAsync;
7
+ const fs_1 = require("fs");
8
+ const promises_1 = require("fs/promises");
9
+ const task_o_matic_error_1 = require("./task-o-matic-error");
10
+ /**
11
+ * Validates that a file exists at the given path (synchronous).
12
+ * Throws an error with a custom message if the file doesn't exist.
13
+ *
14
+ * @param filePath - Path to the file to validate
15
+ * @param customMessage - Optional custom error message
16
+ * @throws TaskOMaticError if file doesn't exist
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * validateFileExists("./config.json", "Configuration file not found");
21
+ * // Throws: TaskOMaticError with code INVALID_INPUT if file doesn't exist
22
+ * ```
23
+ */
24
+ function validateFileExists(filePath, customMessage) {
25
+ if (!(0, fs_1.existsSync)(filePath)) {
26
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, customMessage || `File not found: ${filePath}`, {
27
+ suggestions: ["Verify the file path is correct."],
28
+ });
29
+ }
30
+ }
31
+ /**
32
+ * Validates that a file exists at the given path (asynchronous).
33
+ * Throws an error with a custom message if the file doesn't exist.
34
+ *
35
+ * @param filePath - Path to the file to validate
36
+ * @param customMessage - Optional custom error message
37
+ * @throws TaskOMaticError if file doesn't exist
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * await validateFileExistsAsync("./data.json");
42
+ * // Throws: TaskOMaticError with code INVALID_INPUT if file doesn't exist
43
+ * ```
44
+ */
45
+ async function validateFileExistsAsync(filePath, customMessage) {
46
+ try {
47
+ await (0, promises_1.access)(filePath, promises_1.constants.F_OK);
48
+ }
49
+ catch {
50
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, customMessage || `File not found: ${filePath}`, {
51
+ suggestions: ["Verify the file path is correct."],
52
+ });
53
+ }
54
+ }
55
+ /**
56
+ * Checks if a file exists at the given path (synchronous).
57
+ * Returns true if file exists, false otherwise.
58
+ * Unlike validateFileExists, this doesn't throw an error.
59
+ *
60
+ * @param filePath - Path to check
61
+ * @returns true if file exists, false otherwise
62
+ */
63
+ function fileExists(filePath) {
64
+ return (0, fs_1.existsSync)(filePath);
65
+ }
66
+ /**
67
+ * Checks if a file exists at the given path (asynchronous).
68
+ * Returns true if file exists, false otherwise.
69
+ * Unlike validateFileExistsAsync, this doesn't throw an error.
70
+ *
71
+ * @param filePath - Path to check
72
+ * @returns Promise resolving to true if file exists, false otherwise
73
+ */
74
+ async function fileExistsAsync(filePath) {
75
+ try {
76
+ await (0, promises_1.access)(filePath, promises_1.constants.F_OK);
77
+ return true;
78
+ }
79
+ catch {
80
+ return false;
81
+ }
82
+ }
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Generates unique task IDs with consistent format.
3
+ * Uses timestamp + random hex for uniqueness.
4
+ */
5
+ export declare class TaskIDGenerator {
6
+ /**
7
+ * Generates a unique task ID with format: prefix-timestamp-random
8
+ *
9
+ * @param prefix - Prefix for the ID (default: "task")
10
+ * @returns Unique task ID
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const id = TaskIDGenerator.generate();
15
+ * // Returns: "task-1733750400000-a1b2c3d4"
16
+ *
17
+ * const customId = TaskIDGenerator.generate("subtask");
18
+ * // Returns: "subtask-1733750400000-e5f6g7h8"
19
+ * ```
20
+ */
21
+ static generate(prefix?: string): string;
22
+ /**
23
+ * Validates a task ID format.
24
+ * Accepts three formats:
25
+ * - Timestamped: "task-1234567890-abcd1234"
26
+ * - Hierarchical: "1.2.3"
27
+ * - Numeric: "123"
28
+ *
29
+ * @param id - Task ID to validate
30
+ * @returns true if ID format is valid
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * TaskIDGenerator.validate("task-1234-abcd"); // true
35
+ * TaskIDGenerator.validate("1.2.3"); // true
36
+ * TaskIDGenerator.validate("123"); // true
37
+ * TaskIDGenerator.validate("invalid!"); // false
38
+ * ```
39
+ */
40
+ static validate(id: string): boolean;
41
+ /**
42
+ * Checks if an ID is unique within a set of existing IDs.
43
+ *
44
+ * @param id - ID to check
45
+ * @param existingIds - Set of existing IDs
46
+ * @returns true if ID is unique
47
+ */
48
+ static isUnique(id: string, existingIds: Set<string>): boolean;
49
+ /**
50
+ * Generates a unique ID that doesn't exist in the provided set.
51
+ * Retries up to maxAttempts times if collisions occur.
52
+ *
53
+ * @param existingIds - Set of existing IDs to avoid
54
+ * @param prefix - Prefix for the ID
55
+ * @param maxAttempts - Maximum number of generation attempts
56
+ * @returns Unique task ID
57
+ * @throws TaskOMaticError if unable to generate unique ID after maxAttempts
58
+ */
59
+ static generateUnique(existingIds: Set<string>, prefix?: string, maxAttempts?: number): string;
60
+ /**
61
+ * Generates a hierarchical child ID from a parent ID.
62
+ * If parent is "1.2", generates "1.2.1", "1.2.2", etc.
63
+ *
64
+ * @param parentId - Parent task ID
65
+ * @param childIndex - Index of the child (1-based)
66
+ * @returns Child task ID
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * TaskIDGenerator.generateChildId("1", 1); // "1.1"
71
+ * TaskIDGenerator.generateChildId("1.2", 3); // "1.2.3"
72
+ * ```
73
+ */
74
+ static generateChildId(parentId: string, childIndex: number): string;
75
+ /**
76
+ * Parses a hierarchical ID to extract parent ID and child index.
77
+ *
78
+ * @param id - Hierarchical task ID
79
+ * @returns Object with parentId and childIndex, or null if not hierarchical
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * TaskIDGenerator.parseHierarchicalId("1.2.3");
84
+ * // Returns: { parentId: "1.2", childIndex: 3 }
85
+ * ```
86
+ */
87
+ static parseHierarchicalId(id: string): {
88
+ parentId: string;
89
+ childIndex: number;
90
+ } | null;
91
+ }
92
+ //# sourceMappingURL=id-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"id-generator.d.ts","sourceRoot":"","sources":["../../src/utils/id-generator.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,qBAAa,eAAe;IAC1B;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAE,MAAe,GAAG,MAAM;IAMhD;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IA0BpC;;;;;;OAMG;IACH,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO;IAI9D;;;;;;;;;OASG;IACH,MAAM,CAAC,cAAc,CACnB,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EACxB,MAAM,GAAE,MAAe,EACvB,WAAW,GAAE,MAAW,GACvB,MAAM;IAoBT;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM;IAIpE;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,mBAAmB,CACxB,EAAE,EAAE,MAAM,GACT;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;CAcnD"}
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TaskIDGenerator = void 0;
4
+ const crypto_1 = require("crypto");
5
+ const task_o_matic_error_1 = require("./task-o-matic-error");
6
+ /**
7
+ * Generates unique task IDs with consistent format.
8
+ * Uses timestamp + random hex for uniqueness.
9
+ */
10
+ class TaskIDGenerator {
11
+ /**
12
+ * Generates a unique task ID with format: prefix-timestamp-random
13
+ *
14
+ * @param prefix - Prefix for the ID (default: "task")
15
+ * @returns Unique task ID
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const id = TaskIDGenerator.generate();
20
+ * // Returns: "task-1733750400000-a1b2c3d4"
21
+ *
22
+ * const customId = TaskIDGenerator.generate("subtask");
23
+ * // Returns: "subtask-1733750400000-e5f6g7h8"
24
+ * ```
25
+ */
26
+ static generate(prefix = "task") {
27
+ const timestamp = Date.now();
28
+ const random = (0, crypto_1.randomBytes)(4).toString("hex");
29
+ return `${prefix}-${timestamp}-${random}`;
30
+ }
31
+ /**
32
+ * Validates a task ID format.
33
+ * Accepts three formats:
34
+ * - Timestamped: "task-1234567890-abcd1234"
35
+ * - Hierarchical: "1.2.3"
36
+ * - Numeric: "123"
37
+ *
38
+ * @param id - Task ID to validate
39
+ * @returns true if ID format is valid
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * TaskIDGenerator.validate("task-1234-abcd"); // true
44
+ * TaskIDGenerator.validate("1.2.3"); // true
45
+ * TaskIDGenerator.validate("123"); // true
46
+ * TaskIDGenerator.validate("invalid!"); // false
47
+ * ```
48
+ */
49
+ static validate(id) {
50
+ if (!id || typeof id !== "string") {
51
+ return false;
52
+ }
53
+ // Format 1: Timestamped (task-timestamp-random)
54
+ const timestampedPattern = /^[a-z]+-\d+-[a-f0-9]{8}$/;
55
+ if (timestampedPattern.test(id)) {
56
+ return true;
57
+ }
58
+ // Format 2: Hierarchical (1.2.3)
59
+ const hierarchicalPattern = /^[\d.]+$/;
60
+ if (hierarchicalPattern.test(id)) {
61
+ return true;
62
+ }
63
+ // Format 3: Numeric (123)
64
+ const numericPattern = /^\d+$/;
65
+ if (numericPattern.test(id)) {
66
+ return true;
67
+ }
68
+ return false;
69
+ }
70
+ /**
71
+ * Checks if an ID is unique within a set of existing IDs.
72
+ *
73
+ * @param id - ID to check
74
+ * @param existingIds - Set of existing IDs
75
+ * @returns true if ID is unique
76
+ */
77
+ static isUnique(id, existingIds) {
78
+ return !existingIds.has(id);
79
+ }
80
+ /**
81
+ * Generates a unique ID that doesn't exist in the provided set.
82
+ * Retries up to maxAttempts times if collisions occur.
83
+ *
84
+ * @param existingIds - Set of existing IDs to avoid
85
+ * @param prefix - Prefix for the ID
86
+ * @param maxAttempts - Maximum number of generation attempts
87
+ * @returns Unique task ID
88
+ * @throws TaskOMaticError if unable to generate unique ID after maxAttempts
89
+ */
90
+ static generateUnique(existingIds, prefix = "task", maxAttempts = 10) {
91
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
92
+ const id = this.generate(prefix);
93
+ if (this.isUnique(id, existingIds)) {
94
+ return id;
95
+ }
96
+ }
97
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.UNEXPECTED_ERROR, `Failed to generate unique ID after ${maxAttempts} attempts`, {
98
+ context: `Could not find a unique ID with prefix '${prefix}' after ${maxAttempts} attempts.`,
99
+ suggestions: [
100
+ "Increase maxAttempts if you have a very large number of tasks.",
101
+ ],
102
+ });
103
+ }
104
+ /**
105
+ * Generates a hierarchical child ID from a parent ID.
106
+ * If parent is "1.2", generates "1.2.1", "1.2.2", etc.
107
+ *
108
+ * @param parentId - Parent task ID
109
+ * @param childIndex - Index of the child (1-based)
110
+ * @returns Child task ID
111
+ *
112
+ * @example
113
+ * ```typescript
114
+ * TaskIDGenerator.generateChildId("1", 1); // "1.1"
115
+ * TaskIDGenerator.generateChildId("1.2", 3); // "1.2.3"
116
+ * ```
117
+ */
118
+ static generateChildId(parentId, childIndex) {
119
+ return `${parentId}.${childIndex}`;
120
+ }
121
+ /**
122
+ * Parses a hierarchical ID to extract parent ID and child index.
123
+ *
124
+ * @param id - Hierarchical task ID
125
+ * @returns Object with parentId and childIndex, or null if not hierarchical
126
+ *
127
+ * @example
128
+ * ```typescript
129
+ * TaskIDGenerator.parseHierarchicalId("1.2.3");
130
+ * // Returns: { parentId: "1.2", childIndex: 3 }
131
+ * ```
132
+ */
133
+ static parseHierarchicalId(id) {
134
+ const parts = id.split(".");
135
+ if (parts.length < 2) {
136
+ return null;
137
+ }
138
+ const childIndex = parseInt(parts[parts.length - 1], 10);
139
+ if (isNaN(childIndex)) {
140
+ return null;
141
+ }
142
+ const parentId = parts.slice(0, -1).join(".");
143
+ return { parentId, childIndex };
144
+ }
145
+ }
146
+ exports.TaskIDGenerator = TaskIDGenerator;
@@ -12,7 +12,7 @@ export declare const VALID_EXECUTORS: ExecutorTool[];
12
12
  *
13
13
  * @param value - Comma-separated model/executor specifications
14
14
  * @returns Array of model attempt configurations
15
- * @throws Error if an invalid executor is specified
15
+ * @throws TaskOMaticError if an invalid executor is specified
16
16
  *
17
17
  * @example
18
18
  * ```typescript
@@ -1 +1 @@
1
- {"version":3,"file":"model-executor-parser.d.ts","sourceRoot":"","sources":["../../src/utils/model-executor-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAE5D;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,YAAY,EAKzC,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,EAAE,CA2BlE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,IAAI,YAAY,CAE3E"}
1
+ {"version":3,"file":"model-executor-parser.d.ts","sourceRoot":"","sources":["../../src/utils/model-executor-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAM5D;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,YAAY,EAKzC,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,EAAE,CA4BlE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,IAAI,YAAY,CAE3E"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VALID_EXECUTORS = void 0;
4
4
  exports.parseTryModels = parseTryModels;
5
5
  exports.validateExecutor = validateExecutor;
6
+ const task_o_matic_error_1 = require("./task-o-matic-error");
6
7
  /**
7
8
  * Valid executor tools
8
9
  */
@@ -21,7 +22,7 @@ exports.VALID_EXECUTORS = [
21
22
  *
22
23
  * @param value - Comma-separated model/executor specifications
23
24
  * @returns Array of model attempt configurations
24
- * @throws Error if an invalid executor is specified
25
+ * @throws TaskOMaticError if an invalid executor is specified
25
26
  *
26
27
  * @example
27
28
  * ```typescript
@@ -36,7 +37,7 @@ function parseTryModels(value) {
36
37
  if (trimmed.includes(":")) {
37
38
  const [executor, model] = trimmed.split(":");
38
39
  if (!exports.VALID_EXECUTORS.includes(executor)) {
39
- throw new Error(`Invalid executor "${executor}" in --try-models. Must be one of: ${exports.VALID_EXECUTORS.join(", ")}`);
40
+ throw (0, task_o_matic_error_1.createStandardError)(task_o_matic_error_1.TaskOMaticErrorCodes.INVALID_INPUT, `Invalid executor "${executor}" in --try-models. Must be one of: ${exports.VALID_EXECUTORS.join(", ")}`);
40
41
  }
41
42
  return {
42
43
  executor: executor,
@@ -1,5 +1,6 @@
1
+ import type { BTSFrontend } from "../types/index.js";
1
2
  export interface StackInfo {
2
- frontend: string;
3
+ frontend: BTSFrontend | BTSFrontend[];
3
4
  backend: string;
4
5
  database: string;
5
6
  orm: string;
@@ -1 +1 @@
1
- {"version":3,"file":"stack-formatter.d.ts","sourceRoot":"","sources":["../../src/utils/stack-formatter.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAyB3E;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAMjF"}
1
+ {"version":3,"file":"stack-formatter.d.ts","sourceRoot":"","sources":["../../src/utils/stack-formatter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,WAAW,GAAG,WAAW,EAAE,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CA6B3E;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAUjF"}