@krr2020/taskflow-core 0.1.0-beta.3 → 0.1.0-beta.5

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 (62) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/index.js +42 -4
  3. package/dist/commands/base.d.ts +41 -0
  4. package/dist/commands/base.js +141 -0
  5. package/dist/commands/configure.d.ts +29 -0
  6. package/dist/commands/configure.js +187 -0
  7. package/dist/commands/init.js +21 -7
  8. package/dist/commands/prd/create.d.ts +1 -1
  9. package/dist/commands/prd/create.js +29 -11
  10. package/dist/commands/prd/generate-arch.d.ts +1 -1
  11. package/dist/commands/prd/generate-arch.js +6 -5
  12. package/dist/commands/retro/list.js +6 -5
  13. package/dist/commands/tasks/generate.d.ts +1 -1
  14. package/dist/commands/tasks/generate.js +83 -56
  15. package/dist/commands/upgrade.js +49 -16
  16. package/dist/commands/workflow/check.d.ts +17 -0
  17. package/dist/commands/workflow/check.js +482 -35
  18. package/dist/commands/workflow/commit.js +117 -60
  19. package/dist/commands/workflow/do.d.ts +1 -0
  20. package/dist/commands/workflow/do.js +206 -13
  21. package/dist/commands/workflow/next.js +4 -4
  22. package/dist/commands/workflow/resume.js +9 -6
  23. package/dist/commands/workflow/start.js +11 -11
  24. package/dist/index.d.ts +4 -0
  25. package/dist/index.js +6 -0
  26. package/dist/lib/config-paths.d.ts +15 -15
  27. package/dist/lib/config-paths.js +20 -15
  28. package/dist/lib/file-validator.d.ts +119 -0
  29. package/dist/lib/file-validator.js +291 -0
  30. package/dist/lib/git.js +4 -2
  31. package/dist/lib/log-parser.d.ts +91 -0
  32. package/dist/lib/log-parser.js +178 -0
  33. package/dist/lib/retrospective.d.ts +27 -0
  34. package/dist/lib/retrospective.js +111 -1
  35. package/dist/lib/types.d.ts +19 -6
  36. package/dist/lib/types.js +20 -1
  37. package/dist/lib/validation.d.ts +0 -3
  38. package/dist/lib/validation.js +1 -15
  39. package/dist/llm/base.d.ts +52 -0
  40. package/dist/llm/base.js +35 -0
  41. package/dist/llm/factory.d.ts +39 -0
  42. package/dist/llm/factory.js +102 -0
  43. package/dist/llm/index.d.ts +7 -0
  44. package/dist/llm/index.js +7 -0
  45. package/dist/llm/model-selector.d.ts +71 -0
  46. package/dist/llm/model-selector.js +139 -0
  47. package/dist/llm/providers/anthropic.d.ts +31 -0
  48. package/dist/llm/providers/anthropic.js +116 -0
  49. package/dist/llm/providers/index.d.ts +6 -0
  50. package/dist/llm/providers/index.js +6 -0
  51. package/dist/llm/providers/ollama.d.ts +28 -0
  52. package/dist/llm/providers/ollama.js +91 -0
  53. package/dist/llm/providers/openai-compatible.d.ts +30 -0
  54. package/dist/llm/providers/openai-compatible.js +93 -0
  55. package/dist/schemas/config.d.ts +82 -0
  56. package/dist/schemas/config.js +35 -0
  57. package/dist/schemas/task.d.ts +2 -2
  58. package/dist/state-machine.d.ts +12 -0
  59. package/dist/state-machine.js +2 -2
  60. package/package.json +1 -1
  61. package/dist/lib/package-manager.d.ts +0 -17
  62. package/dist/lib/package-manager.js +0 -53
@@ -1,12 +1,19 @@
1
1
  /**
2
2
  * Check command - Validate and advance task state
3
3
  */
4
+ import { execSync } from "node:child_process";
5
+ import { readdir } from "node:fs/promises";
6
+ import path from "node:path";
4
7
  import { ConfigLoader } from "../../lib/config-loader.js";
5
8
  import { getRefFilePath, REF_FILES } from "../../lib/config-paths.js";
6
9
  import { findActiveTask, loadTasksProgress, updateTaskStatus, } from "../../lib/data-access.js";
7
10
  import { NoActiveSessionError } from "../../lib/errors.js";
8
- import { processValidationOutput } from "../../lib/retrospective.js";
11
+ import { FileValidator, } from "../../lib/file-validator.js";
12
+ import { LogParser } from "../../lib/log-parser.js";
13
+ import { extractNewPatterns, formatNewPatternForDisplay, processValidationOutput, } from "../../lib/retrospective.js";
9
14
  import { runValidations } from "../../lib/validation.js";
15
+ import { Phase } from "../../llm/base.js";
16
+ import { ProviderFactory } from "../../llm/factory.js";
10
17
  import { BaseCommand } from "../base.js";
11
18
  export class CheckCommand extends BaseCommand {
12
19
  async execute() {
@@ -25,6 +32,8 @@ export class CheckCommand extends BaseCommand {
25
32
  // Handle each status transition
26
33
  switch (currentStatus) {
27
34
  case "setup":
35
+ return this.advanceToPlanning(paths.tasksDir, tasksProgress, taskId, content);
36
+ case "planning":
28
37
  return this.advanceToImplementing(paths.tasksDir, tasksProgress, taskId, content);
29
38
  case "implementing":
30
39
  return this.advanceToVerifying(paths.tasksDir, tasksProgress, taskId, content);
@@ -44,14 +53,98 @@ export class CheckCommand extends BaseCommand {
44
53
  return this.failure(`Unknown status: ${currentStatus}`, [`Task ${taskId} has an invalid status`], "Check the task file and fix the status manually.");
45
54
  }
46
55
  }
56
+ advanceToPlanning(tasksDir, tasksProgress, taskId, content) {
57
+ // Advance to planning
58
+ updateTaskStatus(tasksDir, tasksProgress, taskId, "planning");
59
+ return this.success([
60
+ `✓ Status advanced: setup → planning`,
61
+ `✓ Task ${taskId}: ${content.title}`,
62
+ "",
63
+ "Now create your execution plan before writing code.",
64
+ ].join("\n"), [
65
+ "1. Create execution plan:",
66
+ " - Review all context files (RETROSPECTIVE, AI PROTOCOL, etc.)",
67
+ " - Identify files to modify",
68
+ " - Determine implementation approach",
69
+ " - Plan subtask execution order",
70
+ "",
71
+ "2. Check planning checklist:",
72
+ " - [ ] Reviewed RETROSPECTIVE for known issues",
73
+ " - [ ] Understood task requirements",
74
+ " - [ ] Identified affected files and patterns",
75
+ " - [ ] Planned implementation approach",
76
+ " - [ ] Considered edge cases",
77
+ "",
78
+ "3. When plan is ready, run:",
79
+ " taskflow check",
80
+ " This will advance you to IMPLEMENTING status",
81
+ ].join("\n"), {
82
+ aiGuidance: [
83
+ "Current Status: PLANNING",
84
+ "Your Goal: Create a clear execution plan",
85
+ "",
86
+ "PLANNING CHECKLIST:",
87
+ "─────────────────────",
88
+ "1. CONTEXT REVIEW:",
89
+ " - Read RETROSPECTIVE - know what NOT to do",
90
+ " - Read AI PROTOCOL - understand workflow rules",
91
+ " - Review TASK DETAILS - understand requirements",
92
+ " - Check SKILL guidelines - domain-specific rules",
93
+ " - Review ARCHITECTURE/CODING STANDARDS",
94
+ "",
95
+ "2. ANALYSIS:",
96
+ " - Search for similar implementations in codebase",
97
+ " - Identify patterns to follow",
98
+ " - List files to modify",
99
+ " - Identify dependencies",
100
+ " - Check for library conflicts (verify no similar library exists, check compatibility)",
101
+ "",
102
+ "3. PLAN CREATION:",
103
+ " - Define implementation approach",
104
+ " - Order subtasks logically",
105
+ " - Consider error handling needs",
106
+ " - Note integration points",
107
+ " - Use EARS syntax for acceptance criteria: WHEN [event] THEN [system] SHALL [response]",
108
+ " - Present alternatives with pros/cons when multiple approaches exist",
109
+ "",
110
+ "4. RISK ASSESSMENT:",
111
+ " - Check RETROSPECTIVE for known issues",
112
+ " - Identify potential edge cases",
113
+ " - Plan for backward compatibility",
114
+ " - Ask for explicit approval (yes/approved/LGTM?) before proceeding",
115
+ "",
116
+ "OUTPUT DOCUMENT:",
117
+ "─────────────────",
118
+ "Create a brief plan covering:",
119
+ "- Files to modify",
120
+ "- Implementation approach",
121
+ "- Patterns to follow",
122
+ "- Subtask execution order",
123
+ "- Acceptance criteria (EARS syntax)",
124
+ "",
125
+ "ASK ONE QUESTION AT A TIME:",
126
+ "───────────────────────────",
127
+ "Build understanding iteratively - ask ONE clarifying question, wait for answer, then ask the next. Do NOT batch questions.",
128
+ "",
129
+ "WHEN READY:",
130
+ "────────────",
131
+ "Run 'taskflow check' to advance to IMPLEMENTING",
132
+ ].join("\n"),
133
+ warnings: [
134
+ "Do NOT skip planning - it prevents costly mistakes",
135
+ "Do NOT start coding until plan is complete",
136
+ "Review RETROSPECTIVE carefully - avoid known errors",
137
+ ],
138
+ });
139
+ }
47
140
  advanceToImplementing(tasksDir, tasksProgress, taskId, content) {
48
141
  // Advance to implementing
49
142
  updateTaskStatus(tasksDir, tasksProgress, taskId, "implementing");
50
143
  return this.success([
51
- `✓ Status advanced: setup → implementing`,
144
+ `✓ Status advanced: planning → implementing`,
52
145
  `✓ Task ${taskId}: ${content.title}`,
53
146
  "",
54
- "You may now write code to implement this task.",
147
+ "You may now write code to implement this task based on your plan.",
55
148
  ].join("\n"), [
56
149
  "1. Write the code to implement the task",
57
150
  " - Follow the patterns in the codebase",
@@ -77,6 +170,8 @@ export class CheckCommand extends BaseCommand {
77
170
  "3. MATCH PATTERNS - Code should be indistinguishable from existing",
78
171
  "4. HANDLE ERRORS - Every external call needs error handling",
79
172
  "5. NO GUESSING - Verify everything before declaring done",
173
+ "6. CHECK LIBRARY COMPATIBILITY - Before suggesting new libraries, verify no similar library exists, check compatibility, consider security/maintenance",
174
+ "7. SECURITY & PERFORMANCE - Consider security implications, performance impact, backward compatibility",
80
175
  "",
81
176
  "Operating Mode Selection:",
82
177
  "- REACTIVE: Simple, clear, single file",
@@ -91,6 +186,23 @@ export class CheckCommand extends BaseCommand {
91
186
  "- Create new patterns when existing ones work",
92
187
  "- Declare done without verifying",
93
188
  "",
189
+ "3-RETRY LIMIT FOR TESTS:",
190
+ "────────────────────────",
191
+ "Automated tests: Implement test, run full suite, fix failures. Max 3 retry attempts. If still failing, STOP and analyze root cause.",
192
+ "Manual tests: STOP and ask user to verify. Do NOT auto-proceed.",
193
+ "",
194
+ "LEARNINGS TRACKING:",
195
+ "────────────────────",
196
+ "Track learnings for future tasks: capture only general, project-wide insights (not implementation details, not what you did but what you learned, prevent repeated mistakes).",
197
+ "",
198
+ "TECH DEBT REPORTING:",
199
+ "────────────────────────",
200
+ "Report after implementation: tech debt introduced, unfinished work, most impactful next step (focus on high-impact items only).",
201
+ "",
202
+ "DEFINITION OF DONE:",
203
+ "────────────────────",
204
+ "Before declaring complete: functional requirements implemented, tests passing (3-retry limit for automated), lint/type-check pass, documentation updated (if applicable), code reviewed (mandatory), no tech debt or explicitly reported.",
205
+ "",
94
206
  "WHEN DONE:",
95
207
  "───────────",
96
208
  "Run 'taskflow check' to advance to VERIFYING",
@@ -120,7 +232,7 @@ export class CheckCommand extends BaseCommand {
120
232
  "2. Verify all acceptance criteria are met:",
121
233
  ...(content.subtasks || []).map((st) => ` [${st.status === "completed" ? "x" : " "}] ${st.id}. ${st.description}`),
122
234
  "",
123
- "3. Check against .taskflow/ref/RETROSPECTIVE.md:",
235
+ "3. Check against .taskflow/ref/retrospective.md:",
124
236
  " Ensure you haven't repeated known mistakes",
125
237
  "",
126
238
  "4. When self-review is complete, run:",
@@ -141,9 +253,17 @@ export class CheckCommand extends BaseCommand {
141
253
  "□ All subtasks completed",
142
254
  "□ Acceptance criteria met",
143
255
  "",
256
+ "LEARNINGS TRACKING:",
257
+ "────────────────────",
258
+ "Capture only general, project-wide insights: not implementation details ('I added a function'), not what you did but what you learned, prevent repeated mistakes in future tasks.",
259
+ "",
260
+ "TECH DEBT REPORTING:",
261
+ "────────────────────────",
262
+ "Report after implementation: tech debt introduced, unfinished work, most impactful next step (focus on high-impact items only).",
263
+ "",
144
264
  "RETROSPECTIVE CHECK:",
145
265
  "────────────────────",
146
- "Read .taskflow/ref/RETROSPECTIVE.md",
266
+ "Read .taskflow/ref/retrospective.md",
147
267
  "Confirm you haven't made any known mistakes",
148
268
  "These are errors that have been made before",
149
269
  "Do NOT repeat them",
@@ -206,6 +326,12 @@ export class CheckCommand extends BaseCommand {
206
326
  "3. Lint - check code quality",
207
327
  "4. Tests - verify functionality (if configured)",
208
328
  "",
329
+ "TEST HANDLING:",
330
+ "────────────────",
331
+ "Automated tests: Implement test, run full suite, fix failures. Max 3 retry attempts. If still failing, STOP and analyze root cause.",
332
+ "Manual tests: STOP and ask user to verify. Do NOT auto-proceed.",
333
+ "Database tests: Do NOT clean up test data.",
334
+ "",
209
335
  "IF VALIDATION FAILS:",
210
336
  "────────────────────",
211
337
  "1. Read the error summary in the output",
@@ -228,51 +354,138 @@ export class CheckCommand extends BaseCommand {
228
354
  });
229
355
  }
230
356
  async advanceToCommitting(tasksDir, logsDir, refDir, tasksProgress, taskId, content, validationCommands) {
231
- // Run validations
357
+ // Check if AI validation is enabled
358
+ const configLoader = new ConfigLoader(this.context.projectRoot);
359
+ const config = configLoader.load();
360
+ // Run AI-powered validation if configured
361
+ if (config.ai?.enabled && config.ai.provider) {
362
+ const aiResult = await this.runAIValidation(logsDir, Phase.Analysis);
363
+ if (!aiResult.passed) {
364
+ return aiResult.result;
365
+ }
366
+ }
367
+ // Run traditional validations
232
368
  console.log("\n🧪 Running validations...\n");
233
369
  const summary = runValidations(logsDir, taskId, validationCommands);
234
370
  // Check for known errors in output
235
371
  const retroCheck = processValidationOutput(refDir, summary.allOutput);
236
372
  if (!summary.passed) {
373
+ // Get LLM error analysis if available
374
+ let llmGuidance = [
375
+ "Validation Failed - Fix Required",
376
+ "",
377
+ retroCheck.knownErrors.length > 0
378
+ ? "KNOWN ERRORS DETECTED:"
379
+ : "Errors found in validation.",
380
+ retroCheck.knownErrors.length > 0
381
+ ? "You have made mistakes that are already documented."
382
+ : "",
383
+ retroCheck.knownErrors.length > 0
384
+ ? "Check the output above for solutions."
385
+ : "",
386
+ retroCheck.knownErrors.length > 0
387
+ ? "STOP REPEATING THESE MISTAKES."
388
+ : "",
389
+ "",
390
+ "How to fix:",
391
+ "1. Read error messages carefully",
392
+ "2. Apply solutions from retrospective (if shown)",
393
+ "3. Fix the code",
394
+ "4. Re-run: taskflow check",
395
+ "",
396
+ "DO NOT bypass validations",
397
+ "DO NOT use 'any' types to suppress errors",
398
+ "DO fix the root cause",
399
+ ].join("\n");
400
+ // Parse logs and detect new error patterns
401
+ const logParser = new LogParser();
402
+ const logFiles = await readdir(logsDir);
403
+ const parsedErrors = [];
404
+ for (const logFile of logFiles) {
405
+ if (logFile.endsWith(".log")) {
406
+ try {
407
+ const logPath = path.join(logsDir, logFile);
408
+ const parseResult = await logParser.parseFile(logPath);
409
+ parsedErrors.push(...parseResult.errors);
410
+ }
411
+ catch {
412
+ // Ignore log parsing errors
413
+ }
414
+ }
415
+ }
416
+ // Detect NEW error patterns for retrospective
417
+ let newPatternsDetected = [];
418
+ if (parsedErrors.length > 0) {
419
+ const newPatterns = extractNewPatterns(parsedErrors, refDir);
420
+ if (newPatterns.length > 0) {
421
+ newPatternsDetected = newPatterns.map((pattern) => formatNewPatternForDisplay(pattern));
422
+ }
423
+ }
424
+ // Get AI error analysis if LLM available
425
+ if (this.isLLMAvailable() && parsedErrors.length > 0) {
426
+ try {
427
+ const errors = parsedErrors.map((error) => ({
428
+ file: error.file,
429
+ message: error.message,
430
+ line: error.line ?? undefined,
431
+ code: error.code ?? undefined,
432
+ }));
433
+ const errorAnalysis = await this.getErrorAnalysis(errors);
434
+ if (errorAnalysis) {
435
+ llmGuidance = [
436
+ "AI Error Analysis:",
437
+ "───────────────────",
438
+ errorAnalysis,
439
+ "",
440
+ "How to fix:",
441
+ "1. Review the AI analysis above",
442
+ "2. Apply suggested fixes file-by-file",
443
+ "3. Re-run: taskflow check",
444
+ "",
445
+ retroCheck.knownErrors.length > 0
446
+ ? "⚠️ Known errors also detected - see solutions above"
447
+ : "",
448
+ "",
449
+ newPatternsDetected.length > 0
450
+ ? "📝 NEW error patterns detected (see warnings below)"
451
+ : "",
452
+ ].join("\n");
453
+ }
454
+ }
455
+ catch {
456
+ // Fall back to standard guidance
457
+ }
458
+ }
459
+ // Build warnings with new patterns
460
+ const warnings = [];
461
+ if (newPatternsDetected.length > 0) {
462
+ warnings.push("📝 NEW Error Patterns Detected:");
463
+ warnings.push("");
464
+ for (const patternDisplay of newPatternsDetected) {
465
+ warnings.push(patternDisplay);
466
+ warnings.push("");
467
+ }
468
+ warnings.push("💡 Consider adding these to retrospective: taskflow retro add");
469
+ warnings.push("");
470
+ }
471
+ const failureOptions = {
472
+ aiGuidance: llmGuidance,
473
+ };
474
+ if (warnings.length > 0) {
475
+ failureOptions.warnings = warnings;
476
+ }
237
477
  return this.failure("Validation failed", summary.failedChecks.map((check) => `${check} failed`), [
238
478
  "Fix the errors shown above and re-run: taskflow check",
239
479
  "",
240
480
  retroCheck.knownErrors.length > 0
241
481
  ? "⚠️ Known errors detected - see solutions above"
242
482
  : "",
243
- retroCheck.hasNewErrors
483
+ retroCheck.hasNewErrors && newPatternsDetected.length === 0
244
484
  ? "⚠️ New error detected - consider adding to retrospective: taskflow retro add"
245
485
  : "",
246
486
  "",
247
487
  `Full logs: ${logsDir}`,
248
- ].join("\n"), {
249
- aiGuidance: [
250
- "Validation Failed - Fix Required",
251
- "",
252
- retroCheck.knownErrors.length > 0
253
- ? "KNOWN ERRORS DETECTED:"
254
- : "Errors found in validation.",
255
- retroCheck.knownErrors.length > 0
256
- ? "You have made mistakes that are already documented."
257
- : "",
258
- retroCheck.knownErrors.length > 0
259
- ? "Check the output above for solutions."
260
- : "",
261
- retroCheck.knownErrors.length > 0
262
- ? "STOP REPEATING THESE MISTAKES."
263
- : "",
264
- "",
265
- "How to fix:",
266
- "1. Read error messages carefully",
267
- "2. Apply solutions from retrospective (if shown)",
268
- "3. Fix the code",
269
- "4. Re-run: taskflow check",
270
- "",
271
- "DO NOT bypass validations",
272
- "DO NOT use 'any' types to suppress errors",
273
- "DO fix the root cause",
274
- ].join("\n"),
275
- });
488
+ ].join("\n"), failureOptions);
276
489
  }
277
490
  // All validations passed - advance to committing
278
491
  updateTaskStatus(tasksDir, tasksProgress, taskId, "committing");
@@ -316,6 +529,10 @@ export class CheckCommand extends BaseCommand {
316
529
  "- Be specific and concise",
317
530
  "- Focus on user-facing or functional changes",
318
531
  "",
532
+ "TECH DEBT REPORTING:",
533
+ "────────────────────────",
534
+ "Report after implementation: tech debt introduced, unfinished work, most impactful next step (focus on high-impact items only).",
535
+ "",
319
536
  "WHAT HAPPENS NEXT:",
320
537
  "───────────────────",
321
538
  "1. Git add all changes",
@@ -333,7 +550,237 @@ export class CheckCommand extends BaseCommand {
333
550
  "Commit will run git hooks - they must pass",
334
551
  "Push may fail if remote has changes - pull first if needed",
335
552
  "This action marks the task as completed",
553
+ "Report any tech debt introduced in commit message or retrospective",
336
554
  ],
337
555
  });
338
556
  }
557
+ /**
558
+ * Run AI-powered validation on changed files
559
+ */
560
+ async runAIValidation(logsDir, phase) {
561
+ console.log("\n🤖 Running AI-powered file validation...\n");
562
+ try {
563
+ // Get AI config to create provider with correct settings
564
+ const config = this.configLoader.load();
565
+ if (!config?.ai || !config.ai.enabled) {
566
+ throw new Error("AI configuration not enabled");
567
+ }
568
+ if (!config.ai.provider) {
569
+ throw new Error("AI provider not configured");
570
+ }
571
+ // Create provider using actual config (cast to AIConfig)
572
+ const provider = ProviderFactory.createSelector(config.ai);
573
+ const analysisProvider = provider.getProvider(phase);
574
+ // Find modified files (git status, recent changes, etc.)
575
+ const modifiedFiles = await this.findModifiedFiles();
576
+ if (modifiedFiles.length === 0) {
577
+ console.log("No modified files found for validation");
578
+ return {
579
+ passed: true,
580
+ result: this.success("No files to validate", ""),
581
+ };
582
+ }
583
+ console.log(`Validating ${modifiedFiles.length} file${modifiedFiles.length > 1 ? "s" : ""}...\n`);
584
+ // Create file validator
585
+ const validator = new FileValidator({
586
+ provider: analysisProvider,
587
+ includeContext: true,
588
+ provideFixes: true,
589
+ maxIssues: 10,
590
+ });
591
+ // Validate each file
592
+ const results = [];
593
+ for (const filePath of modifiedFiles) {
594
+ try {
595
+ const result = await validator.validate(filePath);
596
+ results.push(result);
597
+ }
598
+ catch (error) {
599
+ console.warn(`Failed to validate ${filePath}: ${error.message}`);
600
+ }
601
+ }
602
+ // Check if all files passed
603
+ const allPassed = results.every((r) => r.passed);
604
+ // Format and display results
605
+ const output = this.formatValidationResults(results);
606
+ console.log(output);
607
+ if (allPassed) {
608
+ return {
609
+ passed: true,
610
+ result: this.success("All files passed AI validation", "Ready to proceed with standard validation"),
611
+ };
612
+ }
613
+ // Parse logs for errors to provide context
614
+ const logParser = new LogParser();
615
+ const logFiles = await readdir(logsDir);
616
+ const errors = [];
617
+ for (const logFile of logFiles) {
618
+ if (logFile.endsWith(".log")) {
619
+ try {
620
+ const logPath = path.join(logsDir, logFile);
621
+ const parseResult = await logParser.parseFile(logPath);
622
+ errors.push(...parseResult.errors);
623
+ }
624
+ catch {
625
+ // Ignore log parsing errors
626
+ }
627
+ }
628
+ }
629
+ // Create AI guidance with error context
630
+ const errorSummary = this.createErrorSummary(errors);
631
+ const messages = [
632
+ "Fix issues shown above and re-run: taskflow check",
633
+ "",
634
+ errorSummary,
635
+ "",
636
+ "AI-Powered Validation Benefits:",
637
+ "- Early error detection before compilation",
638
+ "- Context-aware fix suggestions",
639
+ "- Pattern-based issue identification",
640
+ "- Code quality analysis",
641
+ ];
642
+ const guidance = [
643
+ "AI Validation Results",
644
+ "────────────────────",
645
+ `Files validated: ${results.length}`,
646
+ `Files passed: ${results.filter((r) => r.passed).length}`,
647
+ `Files failed: ${results.filter((r) => !r.passed).length}`,
648
+ "",
649
+ "Fix Instructions:",
650
+ "1. Review issues shown above for each file",
651
+ "2. Apply suggested fixes",
652
+ "3. Re-run: taskflow check",
653
+ "",
654
+ "If errors persist, check for:",
655
+ "- Incorrect imports or types",
656
+ "- Missing dependencies",
657
+ "- Logic errors or bugs",
658
+ "- Known patterns in retrospective",
659
+ ];
660
+ return {
661
+ passed: false,
662
+ result: this.failure("AI validation failed", results.flatMap((r) => r.issues.map((i) => i.message)), messages.join("\n"), {
663
+ aiGuidance: guidance.join("\n"),
664
+ }),
665
+ };
666
+ }
667
+ catch (error) {
668
+ console.warn(`AI validation failed: ${error.message}`);
669
+ console.log("Falling back to standard validation\n");
670
+ // Return passed to fall back to standard validation
671
+ return {
672
+ passed: true,
673
+ result: this.success("AI validation skipped", "Proceeding with standard validation"),
674
+ };
675
+ }
676
+ }
677
+ /**
678
+ * Find modified files for validation
679
+ */
680
+ async findModifiedFiles() {
681
+ try {
682
+ // Get modified, added, and untracked files from git
683
+ const output = execSync("git status --porcelain --untracked-files=all", {
684
+ cwd: this.context.projectRoot,
685
+ encoding: "utf-8",
686
+ }).trim();
687
+ if (!output) {
688
+ return [];
689
+ }
690
+ const files = [];
691
+ const lines = output.split("\n");
692
+ for (const line of lines) {
693
+ // Parse git status output format:
694
+ // XY FILENAME
695
+ // X = status in index, Y = status in working tree
696
+ // Status codes: M (modified), A (added), D (deleted), ?? (untracked), etc.
697
+ const match = line.match(/^(.{2})\s+(.+)$/);
698
+ if (!match)
699
+ continue;
700
+ const [, status, filePath] = match;
701
+ if (!status || !filePath)
702
+ continue;
703
+ // Skip deleted files
704
+ if (status.includes("D"))
705
+ continue;
706
+ // Only validate source files (ts, tsx, js, jsx) but not test files
707
+ const isSourceFile = /\.(ts|tsx|js|jsx|mjs|cjs)$/.test(filePath);
708
+ const isTestFile = /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(filePath);
709
+ if (isSourceFile && !isTestFile) {
710
+ // Convert to absolute path
711
+ const absolutePath = path.join(this.context.projectRoot, filePath);
712
+ files.push(absolutePath);
713
+ }
714
+ }
715
+ return files;
716
+ }
717
+ catch (error) {
718
+ console.warn(`Failed to get modified files: ${error.message}`);
719
+ return [];
720
+ }
721
+ }
722
+ /**
723
+ * Create error summary from logs and validation results
724
+ */
725
+ createErrorSummary(errors) {
726
+ if (errors.length === 0) {
727
+ return "No errors found in logs.";
728
+ }
729
+ const grouped = new Map();
730
+ for (const error of errors) {
731
+ if (error.file) {
732
+ const existing = grouped.get(error.file) || [];
733
+ existing.push(error);
734
+ grouped.set(error.file, existing);
735
+ }
736
+ }
737
+ const lines = ["Error Summary:", ""];
738
+ for (const [file, fileErrors] of grouped) {
739
+ lines.push(`${file}: ${fileErrors.length} error${fileErrors.length > 1 ? "s" : ""}`);
740
+ }
741
+ return lines.join("\n");
742
+ }
743
+ /**
744
+ * Format validation results
745
+ */
746
+ formatValidationResults(results) {
747
+ const lines = [];
748
+ lines.push("=".repeat(80));
749
+ lines.push("AI-Powered Validation Results");
750
+ lines.push("=".repeat(80));
751
+ for (const result of results) {
752
+ lines.push("");
753
+ lines.push(`File: ${result.file}`);
754
+ lines.push(`Status: ${result.passed ? "✓ PASSED" : "✗ FAILED"}`);
755
+ lines.push(`Summary: ${result.summary}`);
756
+ if (result.issues.length > 0) {
757
+ lines.push("");
758
+ lines.push("Issues:");
759
+ for (const issue of result.issues) {
760
+ const icon = issue.severity === "error"
761
+ ? "✗"
762
+ : issue.severity === "warning"
763
+ ? "⚠"
764
+ : "ℹ";
765
+ lines.push(` ${icon} ${issue.message}`);
766
+ if (issue.line) {
767
+ lines.push(` Line: ${issue.line}`);
768
+ }
769
+ if (issue.suggestedFix) {
770
+ lines.push(` Suggested: ${issue.suggestedFix}`);
771
+ }
772
+ }
773
+ }
774
+ if (result.suggestions.length > 0) {
775
+ lines.push("");
776
+ lines.push("Suggestions:");
777
+ for (const suggestion of result.suggestions) {
778
+ lines.push(` • ${suggestion}`);
779
+ }
780
+ }
781
+ }
782
+ lines.push("");
783
+ lines.push("=".repeat(80));
784
+ return lines.join("\n");
785
+ }
339
786
  }