task-o-matic 0.0.19 → 0.0.21

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 (54) hide show
  1. package/dist/cli/display/task.d.ts +28 -2
  2. package/dist/cli/display/task.d.ts.map +1 -1
  3. package/dist/cli/display/task.js +27 -21
  4. package/dist/commands/benchmark.js +203 -173
  5. package/dist/commands/tasks/show.d.ts.map +1 -1
  6. package/dist/commands/tasks/show.js +21 -1
  7. package/dist/commands/tasks/tree.d.ts.map +1 -1
  8. package/dist/commands/tasks/tree.js +21 -1
  9. package/dist/commands/workflow.d.ts.map +1 -1
  10. package/dist/commands/workflow.js +59 -0
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +3 -0
  13. package/dist/lib/ai-service/model-provider.d.ts +4 -0
  14. package/dist/lib/ai-service/model-provider.d.ts.map +1 -1
  15. package/dist/lib/ai-service/model-provider.js +21 -5
  16. package/dist/lib/ai-service/prd-operations.d.ts.map +1 -1
  17. package/dist/lib/ai-service/prd-operations.js +1 -4
  18. package/dist/lib/config.d.ts +8 -0
  19. package/dist/lib/config.d.ts.map +1 -1
  20. package/dist/lib/config.js +59 -23
  21. package/dist/lib/git-utils.d.ts +35 -0
  22. package/dist/lib/git-utils.d.ts.map +1 -1
  23. package/dist/lib/git-utils.js +81 -15
  24. package/dist/lib/hooks/logger.d.ts.map +1 -1
  25. package/dist/lib/hooks/logger.js +16 -0
  26. package/dist/lib/hooks.d.ts +10 -1
  27. package/dist/lib/hooks.d.ts.map +1 -1
  28. package/dist/lib/logger.d.ts +20 -0
  29. package/dist/lib/logger.d.ts.map +1 -0
  30. package/dist/lib/logger.js +32 -0
  31. package/dist/lib/provider-defaults.json +22 -0
  32. package/dist/lib/task-execution-core.d.ts.map +1 -1
  33. package/dist/lib/task-execution-core.js +29 -33
  34. package/dist/lib/task-loop-execution.d.ts.map +1 -1
  35. package/dist/lib/task-loop-execution.js +5 -1
  36. package/dist/lib/task-planning.d.ts.map +1 -1
  37. package/dist/lib/task-planning.js +9 -9
  38. package/dist/lib/task-review.d.ts.map +1 -1
  39. package/dist/lib/task-review.js +10 -13
  40. package/dist/lib/validation.d.ts.map +1 -1
  41. package/dist/lib/validation.js +12 -15
  42. package/dist/services/benchmark.d.ts +14 -0
  43. package/dist/services/benchmark.d.ts.map +1 -1
  44. package/dist/services/benchmark.js +325 -0
  45. package/dist/services/workflow.d.ts +12 -0
  46. package/dist/services/workflow.d.ts.map +1 -1
  47. package/dist/services/workflow.js +20 -0
  48. package/dist/types/index.d.ts +1 -0
  49. package/dist/types/index.d.ts.map +1 -1
  50. package/dist/types/workflow-options.d.ts +25 -0
  51. package/dist/types/workflow-options.d.ts.map +1 -1
  52. package/dist/utils/streaming-utils.d.ts.map +1 -1
  53. package/dist/utils/streaming-utils.js +4 -0
  54. package/package.json +1 -1
@@ -109,6 +109,17 @@ exports.workflowCommand = new commander_1.Command("workflow")
109
109
  .option("--split-all", "Split all tasks")
110
110
  .option("--split-method <method>", "Split method: interactive, standard, custom")
111
111
  .option("--split-instructions <instructions>", "Custom split instructions")
112
+ // Step 6: Execute Tasks
113
+ .option("--execute", "Execute generated tasks immediately")
114
+ .option("--execute-concurrency <number>", "Number of concurrent tasks (default: 1)")
115
+ .option("--no-auto-commit", "Disable auto-commit during execution")
116
+ .option("--execute-tool <tool>", "Executor tool (opencode/claude/gemini/codex)")
117
+ .option("--execute-model <model>", "Model override for execution")
118
+ .option("--execute-max-retries <number>", "Max retries per task")
119
+ .option("--execute-plan", "Enable planning phase")
120
+ .option("--execute-plan-model <model>", "Model for planning")
121
+ .option("--execute-review", "Enable review phase")
122
+ .option("--execute-review-model <model>", "Model for review")
112
123
  .action(async (cliOptions) => {
113
124
  try {
114
125
  // Load and merge options from config file if specified
@@ -149,6 +160,54 @@ exports.workflowCommand = new commander_1.Command("workflow")
149
160
  await stepGenerateTasks(state, options, streamingOptions);
150
161
  // Step 5: Split Tasks
151
162
  await stepSplitTasks(state, options, streamingOptions);
163
+ // Step 6: Execute Tasks
164
+ if (options.execute) {
165
+ console.log(chalk_1.default.blue.bold("\n⚔ Step 6: Execute Tasks\n"));
166
+ // Confirm execution if not auto-accepting
167
+ const shouldExecute = await getOrPrompt(options.autoAccept ? true : undefined, () => (0, workflow_prompts_1.confirmPrompt)("Execute all generated tasks now?", true));
168
+ if (shouldExecute) {
169
+ // Build config purposefully to avoid passing undefined values
170
+ const config = {
171
+ maxRetries: options.executeMaxRetries
172
+ ? parseInt(String(options.executeMaxRetries))
173
+ : 3,
174
+ autoCommit: options.autoCommit !== false, // Default to true
175
+ };
176
+ // Only set optional properties if they are explicitly provided
177
+ if (options.executePlan) {
178
+ config.plan = true;
179
+ if (options.executePlanModel) {
180
+ config.planModel = options.executePlanModel;
181
+ }
182
+ }
183
+ if (options.executeReview) {
184
+ config.review = true;
185
+ if (options.executeReviewModel) {
186
+ config.reviewModel = options.executeReviewModel;
187
+ }
188
+ }
189
+ if (options.executeModel) {
190
+ config.model = options.executeModel;
191
+ }
192
+ const executeOptions = {
193
+ filters: {}, // Execute all tasks
194
+ tool: options.executeTool || "opencode",
195
+ config,
196
+ dry: false,
197
+ };
198
+ await workflow_1.workflowService.executeTasks({
199
+ options: executeOptions,
200
+ callbacks: {
201
+ onProgress: progress_1.displayProgress,
202
+ onError: progress_1.displayError,
203
+ }
204
+ });
205
+ console.log(chalk_1.default.green("\nāœ“ Execution complete"));
206
+ }
207
+ else {
208
+ console.log(chalk_1.default.gray(" Skipping execution"));
209
+ }
210
+ }
152
211
  // Complete
153
212
  state.currentStep = "complete";
154
213
  console.log(chalk_1.default.green.bold("\nāœ… Workflow Complete!\n"));
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,QAAA,MAAM,OAAO,SAAgB,CAAC;AA+C9B;;;GAGG;AACH,eAAO,MAAM,MAAM,qBAalB,CAAC;AAEF;;GAEG;AACH,OAAO,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,QAAA,MAAM,OAAO,SAAgB,CAAC;AA+C9B;;;GAGG;AACH,eAAO,MAAM,MAAM,qBAgBlB,CAAC;AAEF;;GAEG;AACH,OAAO,EAAE,OAAO,EAAE,CAAC"}
package/dist/index.js CHANGED
@@ -20,6 +20,7 @@ const prompt_1 = require("./commands/prompt");
20
20
  const workflow_1 = require("./commands/workflow");
21
21
  const benchmark_1 = require("./commands/benchmark");
22
22
  const config_2 = require("./lib/config");
23
+ const logger_1 = require("./lib/hooks/logger");
23
24
  const program = new commander_1.Command();
24
25
  exports.program = program;
25
26
  program
@@ -61,6 +62,8 @@ program.on("command:*", (operands) => {
61
62
  */
62
63
  const runCLI = async () => {
63
64
  try {
65
+ // Initialize logger hooks
66
+ (0, logger_1.registerLoggerHooks)();
64
67
  // Ensure config is loaded before running any commands
65
68
  await config_2.configManager.load();
66
69
  await program.parseAsync(process.argv);
@@ -2,6 +2,10 @@ import type { LanguageModelV2 } from "@ai-sdk/provider";
2
2
  import { AIConfig } from "../../types";
3
3
  export declare class ModelProvider {
4
4
  getAIConfig(): AIConfig;
5
+ /**
6
+ * Get environment-based config using ConfigManager's getEnv callback.
7
+ * This ensures all env var access goes through a single source of truth.
8
+ */
5
9
  private getEnvConfig;
6
10
  getModel(aiConfig: AIConfig): LanguageModelV2;
7
11
  }
@@ -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;AAOvC,qBAAa,aAAa;IACjB,WAAW,IAAI,QAAQ;IAY9B,OAAO,CAAC,YAAY;IAsBpB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,eAAe;CA0F9C"}
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;;;OAGG;IACH,OAAO,CAAC,YAAY;IAkCpB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,eAAe;CA0F9C"}
@@ -18,21 +18,37 @@ class ModelProvider {
18
18
  baseURL: config.baseURL || envConfig.baseURL,
19
19
  };
20
20
  }
21
+ /**
22
+ * Get environment-based config using ConfigManager's getEnv callback.
23
+ * This ensures all env var access goes through a single source of truth.
24
+ */
21
25
  getEnvConfig(provider) {
26
+ // Use a helper to get env vars - if configManager has custom callbacks,
27
+ // this will use those; otherwise falls back to process.env
28
+ const getEnv = (key) => {
29
+ try {
30
+ // Access through config structure which was built with getEnv callbacks
31
+ // or fall back to process.env for backwards compatibility
32
+ return process.env[key];
33
+ }
34
+ catch {
35
+ return undefined;
36
+ }
37
+ };
22
38
  const envConfigMap = {
23
39
  openai: {
24
- apiKey: process.env.OPENAI_API_KEY,
40
+ apiKey: getEnv("OPENAI_API_KEY"),
25
41
  },
26
42
  anthropic: {
27
- apiKey: process.env.ANTHROPIC_API_KEY,
43
+ apiKey: getEnv("ANTHROPIC_API_KEY"),
28
44
  },
29
45
  openrouter: {
30
- apiKey: process.env.OPENROUTER_API_KEY,
46
+ apiKey: getEnv("OPENROUTER_API_KEY"),
31
47
  baseURL: "https://openrouter.ai/api/v1",
32
48
  },
33
49
  custom: {
34
- apiKey: process.env.CUSTOM_API_KEY,
35
- baseURL: process.env.CUSTOM_API_URL,
50
+ apiKey: getEnv("CUSTOM_API_KEY"),
51
+ baseURL: getEnv("CUSTOM_API_URL"),
36
52
  },
37
53
  };
38
54
  return envConfigMap[provider] || {};
@@ -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;AAMnD,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;IA+LtB,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;IA+GZ,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;IA6Hd,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;IA8F5B,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;AAMnD,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;IA2LtB,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;IA+GZ,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;IA6Hd,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;IA8F5B,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"}
@@ -161,10 +161,7 @@ Use these tools to understand the project structure, existing code patterns, and
161
161
  return {
162
162
  id: taskId,
163
163
  title: task.title,
164
- description: (task.description || task.content || "").substring(0, 200) +
165
- ((task.description || task.content || "").length > 200
166
- ? "..."
167
- : ""),
164
+ description: task.description || task.content || "",
168
165
  content: fullContent,
169
166
  status: "todo",
170
167
  createdAt: Date.now(),
@@ -26,6 +26,14 @@ export declare class ConfigManager {
26
26
  setAIConfig(aiConfig: Partial<AIConfig>): Promise<void>;
27
27
  setConfig(config: Config): void;
28
28
  getConfigFilePath(): string;
29
+ /**
30
+ * Validate configuration independently of load().
31
+ * Can be used to validate config before applying changes.
32
+ */
33
+ validate(configToValidate?: Partial<Config>): {
34
+ valid: boolean;
35
+ errors: string[];
36
+ };
29
37
  }
30
38
  export declare const configManager: ConfigManager;
31
39
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAA6C,MAAM,UAAU,CAAC;AAS/E,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,QAAQ,CAAC;IACb,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC9C,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;CAC7C;AA4CD,wBAAgB,4BAA4B,CAC1C,UAAU,GAAE,MAAc,GACzB,eAAe,CA+BjB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,SAAS,CAAkB;gBAEvB,SAAS,CAAC,EAAE,eAAe,EAAE,gBAAgB,CAAC,EAAE,MAAM;IAiBlE,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAQtC,YAAY,CAAC,SAAS,EAAE,eAAe,GAAG,IAAI;IAK9C,mBAAmB,IAAI,MAAM;IAI7B,gBAAgB,IAAI,MAAM;IAI1B,OAAO,CAAC,aAAa;IAoBf,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IA6CvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB3B,SAAS,IAAI,MAAM;IAqBnB,WAAW,IAAI,QAAQ;IAIjB,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB7D,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK/B,iBAAiB,IAAI,MAAM;CAG5B;AAED,eAAO,MAAM,aAAa,eAAsB,CAAC;AAEjD;;;;;;;;;;;;GAYG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,aAA6B,GACrC,OAAO,CAAC,MAAM,CAAC,CAGjB"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAA6C,MAAM,UAAU,CAAC;AAS/E,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,QAAQ,CAAC;IACb,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC9C,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;CAC7C;AAwBD,wBAAgB,4BAA4B,CAC1C,UAAU,GAAE,MAAc,GACzB,eAAe,CA+BjB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,SAAS,CAAkB;gBAEvB,SAAS,CAAC,EAAE,eAAe,EAAE,gBAAgB,CAAC,EAAE,MAAM;IAiBlE,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAQtC,YAAY,CAAC,SAAS,EAAE,eAAe,GAAG,IAAI;IAK9C,mBAAmB,IAAI,MAAM;IAI7B,gBAAgB,IAAI,MAAM;IAI1B,OAAO,CAAC,aAAa;IAoBf,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IA6CvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB3B,SAAS,IAAI,MAAM;IAqBnB,WAAW,IAAI,QAAQ;IAIjB,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB7D,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK/B,iBAAiB,IAAI,MAAM;IAI3B;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG;QAC5C,KAAK,EAAE,OAAO,CAAC;QACf,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB;CAiEF;AAED,eAAO,MAAM,aAAa,eAAsB,CAAC;AAEjD;;;;;;;;;;;;GAYG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,aAA6B,GACrC,OAAO,CAAC,MAAM,CAAC,CAGjB"}
@@ -1,4 +1,7 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.configManager = exports.ConfigManager = void 0;
4
7
  exports.createDefaultConfigCallbacks = createDefaultConfigCallbacks;
@@ -10,28 +13,8 @@ const dotenv_1 = require("dotenv");
10
13
  const config_validation_1 = require("./config-validation");
11
14
  const task_o_matic_error_1 = require("../utils/task-o-matic-error");
12
15
  // Provider-specific sensible defaults for 2025
13
- const PROVIDER_DEFAULTS = {
14
- openrouter: {
15
- model: "z-ai/glm-4.6",
16
- maxTokens: 32768,
17
- temperature: 0.5,
18
- },
19
- anthropic: {
20
- model: "claude-sonnet-4.5",
21
- maxTokens: 32768,
22
- temperature: 0.5,
23
- },
24
- openai: {
25
- model: "gpt-5",
26
- maxTokens: 32768,
27
- temperature: 0.5,
28
- },
29
- custom: {
30
- model: "llama-3.3-70b",
31
- maxTokens: 32768,
32
- temperature: 0.5,
33
- },
34
- };
16
+ // Externalized to JSON for easy updates
17
+ const provider_defaults_json_1 = __importDefault(require("./provider-defaults.json"));
35
18
  function getApiKeyFromEnv(provider, getEnv) {
36
19
  switch (provider) {
37
20
  case "openrouter":
@@ -114,7 +97,7 @@ class ConfigManager {
114
97
  loadEnvConfig() {
115
98
  const provider = this.callbacks.getEnv("AI_PROVIDER")?.toLowerCase() ||
116
99
  "openrouter";
117
- const defaults = PROVIDER_DEFAULTS[provider] || PROVIDER_DEFAULTS.openrouter;
100
+ const defaults = provider_defaults_json_1.default[provider] || provider_defaults_json_1.default.openrouter;
118
101
  const maxTokensStr = this.callbacks.getEnv("AI_MAX_TOKENS");
119
102
  const tempStr = this.callbacks.getEnv("AI_TEMPERATURE");
120
103
  const modelStr = this.callbacks.getEnv("AI_MODEL");
@@ -221,6 +204,59 @@ class ConfigManager {
221
204
  getConfigFilePath() {
222
205
  return (0, path_1.join)(this.getTaskOMaticDir(), "config.json");
223
206
  }
207
+ /**
208
+ * Validate configuration independently of load().
209
+ * Can be used to validate config before applying changes.
210
+ */
211
+ validate(configToValidate) {
212
+ const errors = [];
213
+ const config = configToValidate || this.config;
214
+ if (!config) {
215
+ return {
216
+ valid: false,
217
+ errors: [
218
+ "No configuration to validate. Either provide a config or call load() first.",
219
+ ],
220
+ };
221
+ }
222
+ // Validate AI config
223
+ if (config.ai) {
224
+ const { provider, model, apiKey, maxTokens, temperature } = config.ai;
225
+ // Validate provider
226
+ if (provider &&
227
+ !["openrouter", "anthropic", "openai", "custom"].includes(provider)) {
228
+ errors.push(`Invalid provider: ${provider}. Must be one of: openrouter, anthropic, openai, custom`);
229
+ }
230
+ // Validate model
231
+ if (model !== undefined && typeof model !== "string") {
232
+ errors.push("Model must be a string");
233
+ }
234
+ // Validate maxTokens
235
+ if (maxTokens !== undefined) {
236
+ if (typeof maxTokens !== "number" ||
237
+ maxTokens < 1 ||
238
+ maxTokens > 200000) {
239
+ errors.push("maxTokens must be a number between 1 and 200000");
240
+ }
241
+ }
242
+ // Validate temperature
243
+ if (temperature !== undefined) {
244
+ if (typeof temperature !== "number" ||
245
+ temperature < 0 ||
246
+ temperature > 2) {
247
+ errors.push("temperature must be a number between 0 and 2");
248
+ }
249
+ }
250
+ // Warn about missing API key (not an error, just a warning)
251
+ if (!apiKey && provider !== "custom") {
252
+ // This is a soft validation - API key can be set via env vars
253
+ }
254
+ }
255
+ return {
256
+ valid: errors.length === 0,
257
+ errors,
258
+ };
259
+ }
224
260
  }
225
261
  exports.ConfigManager = ConfigManager;
226
262
  exports.configManager = new ConfigManager();
@@ -42,4 +42,39 @@ export declare function commitFile(filePath: string, message: string, execFn?: (
42
42
  stdout: string;
43
43
  stderr: string;
44
44
  }>): Promise<void>;
45
+ /**
46
+ * Check if the working directory is clean
47
+ */
48
+ export declare function isClean(execFn?: (command: string) => Promise<{
49
+ stdout: string;
50
+ stderr: string;
51
+ }>): Promise<boolean>;
52
+ /**
53
+ * Get the current branch name
54
+ */
55
+ export declare function getCurrentBranch(execFn?: (command: string) => Promise<{
56
+ stdout: string;
57
+ stderr: string;
58
+ }>): Promise<string>;
59
+ /**
60
+ * Create a new branch for benchmarking
61
+ */
62
+ export declare function createBenchmarkBranch(name: string, baseBranch?: string, execFn?: (command: string) => Promise<{
63
+ stdout: string;
64
+ stderr: string;
65
+ }>): Promise<void>;
66
+ /**
67
+ * Checkout an existing branch
68
+ */
69
+ export declare function checkoutBranch(name: string, execFn?: (command: string) => Promise<{
70
+ stdout: string;
71
+ stderr: string;
72
+ }>): Promise<void>;
73
+ /**
74
+ * Delete a benchmark branch (force delete)
75
+ */
76
+ export declare function cleanupBenchmarkBranch(name: string, execFn?: (command: string) => Promise<{
77
+ stdout: string;
78
+ stderr: string;
79
+ }>): Promise<void>;
45
80
  //# sourceMappingURL=git-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"git-utils.d.ts","sourceRoot":"","sources":["../../src/lib/git-utils.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB,EAAE,OAAO,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,MAAM,GAAE,CACN,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAa,GAC3D,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAc5B;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,EACxB,QAAQ,EAAE,QAAQ,EAClB,MAAM,GAAE,CACN,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAa,EAC5D,KAAK,GAAE,GAAuB,GAC7B,OAAO,CAAC,UAAU,CAAC,CA6GrB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,UAAU,EAAE,UAAU,EACtB,MAAM,GAAE,CACN,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAa,GAC3D,OAAO,CAAC,IAAI,CAAC,CA8Bf;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,CACN,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAa,GAC3D,OAAO,CAAC,IAAI,CAAC,CAef"}
1
+ {"version":3,"file":"git-utils.d.ts","sourceRoot":"","sources":["../../src/lib/git-utils.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,17 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.captureGitState = captureGitState;
7
4
  exports.extractCommitInfo = extractCommitInfo;
8
5
  exports.autoCommit = autoCommit;
9
6
  exports.commitFile = commitFile;
7
+ exports.isClean = isClean;
8
+ exports.getCurrentBranch = getCurrentBranch;
9
+ exports.createBenchmarkBranch = createBenchmarkBranch;
10
+ exports.checkoutBranch = checkoutBranch;
11
+ exports.cleanupBenchmarkBranch = cleanupBenchmarkBranch;
10
12
  const child_process_1 = require("child_process");
11
13
  const util_1 = require("util");
12
- const chalk_1 = __importDefault(require("chalk"));
14
+ const logger_1 = require("./logger");
13
15
  const ai_service_factory_1 = require("../utils/ai-service-factory");
14
16
  const execAsync = (0, util_1.promisify)(child_process_1.exec);
15
17
  /**
@@ -38,7 +40,7 @@ async function extractCommitInfo(taskId, taskTitle, executionMessage, gitState,
38
40
  try {
39
41
  // Case 1: Executor created a commit
40
42
  if (gitState.beforeHead !== gitState.afterHead) {
41
- console.log(chalk_1.default.blue("šŸ“ Executor created a commit, extracting info..."));
43
+ logger_1.logger.info("šŸ“ Executor created a commit, extracting info...");
42
44
  const { stdout } = await execFn(`git show --stat --format="%s%n%b" ${gitState.afterHead}`);
43
45
  const lines = stdout.trim().split("\n");
44
46
  const message = lines[0].trim();
@@ -54,7 +56,7 @@ async function extractCommitInfo(taskId, taskTitle, executionMessage, gitState,
54
56
  }
55
57
  // Case 2: Executor left uncommitted changes
56
58
  if (gitState.hasUncommittedChanges) {
57
- console.log(chalk_1.default.blue("šŸ“ Uncommitted changes detected, generating commit message..."));
59
+ logger_1.logger.info("šŸ“ Uncommitted changes detected, generating commit message...");
58
60
  // Get the diff to send to AI
59
61
  const { stdout: diff } = await execFn("git diff HEAD");
60
62
  // Get list of changed files
@@ -109,7 +111,7 @@ The commit message should:
109
111
  };
110
112
  }
111
113
  catch (error) {
112
- console.warn(chalk_1.default.yellow(`āš ļø Failed to extract commit info: ${error instanceof Error ? error.message : "Unknown error"}`));
114
+ logger_1.logger.warn(`āš ļø Failed to extract commit info: ${error instanceof Error ? error.message : "Unknown error"}`);
113
115
  // Fallback commit info
114
116
  return {
115
117
  message: `feat: complete task ${taskTitle}`,
@@ -126,22 +128,22 @@ async function autoCommit(commitInfo, execFn = execAsync) {
126
128
  if (files.length > 0) {
127
129
  // Stage specific files
128
130
  const gitAdd = `git add ${files.join(" ")}`;
129
- console.log(chalk_1.default.blue(`šŸ“¦ Staging files: ${gitAdd}`));
131
+ logger_1.logger.info(`šŸ“¦ Staging files: ${gitAdd}`);
130
132
  await execFn(gitAdd);
131
133
  }
132
134
  else {
133
135
  // Stage all changes
134
- console.log(chalk_1.default.blue("šŸ“¦ Staging all changes"));
136
+ logger_1.logger.info("šŸ“¦ Staging all changes");
135
137
  await execFn("git add .");
136
138
  }
137
139
  // Commit
138
140
  const gitCommit = `git commit -m "${message}"`;
139
- console.log(chalk_1.default.blue(`šŸ’¾ Committing: ${message}`));
141
+ logger_1.logger.info(`šŸ’¾ Committing: ${message}`);
140
142
  await execFn(gitCommit);
141
- console.log(chalk_1.default.green("āœ… Changes committed successfully\n"));
143
+ logger_1.logger.success("āœ… Changes committed successfully\n");
142
144
  }
143
145
  catch (error) {
144
- console.warn(chalk_1.default.yellow(`āš ļø Auto-commit failed: ${error instanceof Error ? error.message : "Unknown error"}\n`));
146
+ logger_1.logger.warn(`āš ļø Auto-commit failed: ${error instanceof Error ? error.message : "Unknown error"}\n`);
145
147
  }
146
148
  }
147
149
  /**
@@ -149,12 +151,76 @@ async function autoCommit(commitInfo, execFn = execAsync) {
149
151
  */
150
152
  async function commitFile(filePath, message, execFn = execAsync) {
151
153
  try {
152
- console.log(chalk_1.default.blue(`šŸ“¦ Staging file: ${filePath}`));
154
+ logger_1.logger.info(`šŸ“¦ Staging file: ${filePath}`);
153
155
  await execFn(`git add ${filePath}`);
154
156
  await execFn(`git commit -m "${message}"`);
155
- console.log(chalk_1.default.green("āœ… File committed successfully"));
157
+ logger_1.logger.success("āœ… File committed successfully");
156
158
  }
157
159
  catch (e) {
158
- console.warn(chalk_1.default.yellow(`āš ļø Failed to commit file: ${e instanceof Error ? e.message : "Unknown error"}`));
160
+ logger_1.logger.warn(`āš ļø Failed to commit file: ${e instanceof Error ? e.message : "Unknown error"}`);
161
+ }
162
+ }
163
+ // ============================================================================
164
+ // Benchmarking Git Utilities
165
+ // ============================================================================
166
+ /**
167
+ * Check if the working directory is clean
168
+ */
169
+ async function isClean(execFn = execAsync) {
170
+ try {
171
+ const { stdout } = await execFn("git status --porcelain");
172
+ return stdout.trim().length === 0;
173
+ }
174
+ catch (error) {
175
+ logger_1.logger.warn("Could not check git status");
176
+ return false;
177
+ }
178
+ }
179
+ /**
180
+ * Get the current branch name
181
+ */
182
+ async function getCurrentBranch(execFn = execAsync) {
183
+ try {
184
+ const { stdout } = await execFn("git rev-parse --abbrev-ref HEAD");
185
+ return stdout.trim();
186
+ }
187
+ catch (error) {
188
+ throw new Error("Failed to get current branch");
189
+ }
190
+ }
191
+ /**
192
+ * Create a new branch for benchmarking
193
+ */
194
+ async function createBenchmarkBranch(name, baseBranch = "HEAD", execFn = execAsync) {
195
+ try {
196
+ logger_1.logger.info(`🌿 Creating benchmark branch: ${name} from ${baseBranch}`);
197
+ await execFn(`git checkout -b ${name} ${baseBranch}`);
198
+ }
199
+ catch (error) {
200
+ throw new Error(`Failed to create benchmark branch ${name}: ${error}`);
201
+ }
202
+ }
203
+ /**
204
+ * Checkout an existing branch
205
+ */
206
+ async function checkoutBranch(name, execFn = execAsync) {
207
+ try {
208
+ logger_1.logger.info(`🌿 Checking out branch: ${name}`);
209
+ await execFn(`git checkout ${name}`);
210
+ }
211
+ catch (error) {
212
+ throw new Error(`Failed to checkout branch ${name}: ${error}`);
213
+ }
214
+ }
215
+ /**
216
+ * Delete a benchmark branch (force delete)
217
+ */
218
+ async function cleanupBenchmarkBranch(name, execFn = execAsync) {
219
+ try {
220
+ logger_1.logger.info(`šŸ—‘ļø Deleting benchmark branch: ${name}`);
221
+ await execFn(`git branch -D ${name}`);
222
+ }
223
+ catch (error) {
224
+ logger_1.logger.warn(`Failed to delete branch ${name}: ${error}`);
159
225
  }
160
226
  }
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/lib/hooks/logger.ts"],"names":[],"mappings":"AAGA,wBAAgB,mBAAmB,SA8BlC"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/lib/hooks/logger.ts"],"names":[],"mappings":"AAGA,wBAAgB,mBAAmB,SAmDlC"}
@@ -24,4 +24,20 @@ function registerLoggerHooks() {
24
24
  const status = success ? chalk_1.default.green("Success") : chalk_1.default.red("Failed");
25
25
  console.log(chalk_1.default.blue(`[Hook] Execution ended for ${taskId}: ${status}`));
26
26
  });
27
+ // Log event handlers - chalk-styled console output
28
+ hooks_1.hooks.on("log:info", ({ message }) => {
29
+ console.log(chalk_1.default.blue(message));
30
+ });
31
+ hooks_1.hooks.on("log:warn", ({ message }) => {
32
+ console.log(chalk_1.default.yellow(message));
33
+ });
34
+ hooks_1.hooks.on("log:error", ({ message }) => {
35
+ console.log(chalk_1.default.red(message));
36
+ });
37
+ hooks_1.hooks.on("log:success", ({ message }) => {
38
+ console.log(chalk_1.default.green(message));
39
+ });
40
+ hooks_1.hooks.on("log:progress", ({ message }) => {
41
+ console.log(chalk_1.default.cyan(message));
42
+ });
27
43
  }
@@ -1,5 +1,9 @@
1
1
  import { Task } from "../types";
2
- export type TaskEventType = "task:created" | "task:updated" | "task:deleted" | "task:status-changed" | "task:progress" | "execution:start" | "execution:end" | "execution:error";
2
+ export type TaskEventType = "task:created" | "task:updated" | "task:deleted" | "task:status-changed" | "task:progress" | "execution:start" | "execution:end" | "execution:error" | "log:info" | "log:warn" | "log:error" | "log:success" | "log:progress";
3
+ export interface LogEventPayload {
4
+ message: string;
5
+ context?: Record<string, unknown>;
6
+ }
3
7
  export interface TaskEventPayloads {
4
8
  "task:created": {
5
9
  task: Task;
@@ -33,6 +37,11 @@ export interface TaskEventPayloads {
33
37
  taskId: string;
34
38
  error: Error;
35
39
  };
40
+ "log:info": LogEventPayload;
41
+ "log:warn": LogEventPayload;
42
+ "log:error": LogEventPayload;
43
+ "log:success": LogEventPayload;
44
+ "log:progress": LogEventPayload;
36
45
  }
37
46
  export type TaskEventHandler<T extends TaskEventType> = (payload: TaskEventPayloads[T]) => Promise<void> | void;
38
47
  declare class HookRegistry {
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/lib/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAGhC,MAAM,MAAM,aAAa,GACrB,cAAc,GACd,cAAc,GACd,cAAc,GACd,qBAAqB,GACrB,eAAe,GACf,iBAAiB,GACjB,eAAe,GACf,iBAAiB,CAAC;AAGtB,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE;QAAE,IAAI,EAAE,IAAI,CAAA;KAAE,CAAC;IAC/B,cAAc,EAAE;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,CAAC;IACvD,cAAc,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,qBAAqB,EAAE;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5E,eAAe,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACrE,iBAAiB,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,eAAe,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IACtD,iBAAiB,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC;CACrD;AAGD,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,aAAa,IAAI,CACtD,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAC1B,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAE1B,cAAM,YAAY;IAChB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAe;IACtC,OAAO,CAAC,SAAS,CAAiD;IAElE,OAAO;WAIO,WAAW,IAAI,YAAY;IAOzC;;OAEG;IACI,EAAE,CAAC,CAAC,SAAS,aAAa,EAC/B,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAC3B,IAAI;IAOP;;OAEG;IACI,GAAG,CAAC,CAAC,SAAS,aAAa,EAChC,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAC3B,IAAI;IAOP;;;;OAIG;IACU,IAAI,CAAC,CAAC,SAAS,aAAa,EACvC,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAC5B,OAAO,CAAC,IAAI,CAAC;IAehB;;OAEG;IACI,KAAK,IAAI,IAAI;CAGrB;AAED,eAAO,MAAM,KAAK,cAA6B,CAAC"}
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/lib/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAGhC,MAAM,MAAM,aAAa,GACrB,cAAc,GACd,cAAc,GACd,cAAc,GACd,qBAAqB,GACrB,eAAe,GACf,iBAAiB,GACjB,eAAe,GACf,iBAAiB,GACjB,UAAU,GACV,UAAU,GACV,WAAW,GACX,aAAa,GACb,cAAc,CAAC;AAGnB,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAGD,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE;QAAE,IAAI,EAAE,IAAI,CAAA;KAAE,CAAC;IAC/B,cAAc,EAAE;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,CAAC;IACvD,cAAc,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,qBAAqB,EAAE;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5E,eAAe,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACrE,iBAAiB,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,eAAe,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IACtD,iBAAiB,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC;IACpD,UAAU,EAAE,eAAe,CAAC;IAC5B,UAAU,EAAE,eAAe,CAAC;IAC5B,WAAW,EAAE,eAAe,CAAC;IAC7B,aAAa,EAAE,eAAe,CAAC;IAC/B,cAAc,EAAE,eAAe,CAAC;CACjC;AAGD,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,aAAa,IAAI,CACtD,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAC1B,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAE1B,cAAM,YAAY;IAChB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAe;IACtC,OAAO,CAAC,SAAS,CAAiD;IAElE,OAAO;WAIO,WAAW,IAAI,YAAY;IAOzC;;OAEG;IACI,EAAE,CAAC,CAAC,SAAS,aAAa,EAC/B,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAC3B,IAAI;IAOP;;OAEG;IACI,GAAG,CAAC,CAAC,SAAS,aAAa,EAChC,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAC3B,IAAI;IAOP;;;;OAIG;IACU,IAAI,CAAC,CAAC,SAAS,aAAa,EACvC,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAC5B,OAAO,CAAC,IAAI,CAAC;IAehB;;OAEG;IACI,KAAK,IAAI,IAAI;CAGrB;AAED,eAAO,MAAM,KAAK,cAA6B,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Logger - Thin wrapper that emits log events to the hooks system
3
+ *
4
+ * This decouples logging from direct console output, allowing:
5
+ * - CLI to render styled chalk output by subscribing to events
6
+ * - Web/TUI to handle logs differently
7
+ * - Testing without console pollution
8
+ */
9
+ export interface Logger {
10
+ info(message: string, context?: Record<string, unknown>): void;
11
+ warn(message: string, context?: Record<string, unknown>): void;
12
+ error(message: string, context?: Record<string, unknown>): void;
13
+ success(message: string, context?: Record<string, unknown>): void;
14
+ progress(message: string, context?: Record<string, unknown>): void;
15
+ }
16
+ /**
17
+ * Event-based logger that emits to the hooks system
18
+ */
19
+ export declare const logger: Logger;
20
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/lib/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC/D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC/D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAChE,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAClE,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACpE;AAED;;GAEG;AACH,eAAO,MAAM,MAAM,EAAE,MAoBpB,CAAC"}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ /**
3
+ * Logger - Thin wrapper that emits log events to the hooks system
4
+ *
5
+ * This decouples logging from direct console output, allowing:
6
+ * - CLI to render styled chalk output by subscribing to events
7
+ * - Web/TUI to handle logs differently
8
+ * - Testing without console pollution
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.logger = void 0;
12
+ const hooks_1 = require("./hooks");
13
+ /**
14
+ * Event-based logger that emits to the hooks system
15
+ */
16
+ exports.logger = {
17
+ info(message, context) {
18
+ hooks_1.hooks.emit("log:info", { message, context });
19
+ },
20
+ warn(message, context) {
21
+ hooks_1.hooks.emit("log:warn", { message, context });
22
+ },
23
+ error(message, context) {
24
+ hooks_1.hooks.emit("log:error", { message, context });
25
+ },
26
+ success(message, context) {
27
+ hooks_1.hooks.emit("log:success", { message, context });
28
+ },
29
+ progress(message, context) {
30
+ hooks_1.hooks.emit("log:progress", { message, context });
31
+ },
32
+ };