(filePath, toolResult, cwd)
| 976 | // tdd_begin_cycle explicitly. |
| 977 | |
| 978 | async function _tddPostWrite(filePath, toolResult, cwd) { |
| 979 | try { |
| 980 | const { getTDDState, _isTestFile } = require('../src/session/tdd_state'); |
| 981 | const tdd = getTDDState({ workdir: cwd }); |
| 982 | if (!tdd.loopActive) return toolResult; |
| 983 | |
| 984 | const { runTests, formatResult } = require('../src/tools/run_tests'); |
| 985 | const { getTDDGovernor } = require('../src/governor/tdd_governor'); |
| 986 | |
| 987 | const isTestFile = _isTestFile(filePath || ''); |
| 988 | const isRefactor = tdd.isRefactor(); |
| 989 | const allDone = tdd.allRequirementsDone(); |
| 990 | |
| 991 | // Choose filter: target test while in cycle, full suite for refactor/done |
| 992 | const filter = (!isRefactor && !allDone && tdd.targetTest) ? tdd.targetTest : null; |
| 993 | const testResult = runTests({ workdir: cwd, test_filter: filter || undefined }); |
| 994 | |
| 995 | // Auto-begin cycle: idle + test file written + failures detected |
| 996 | if (tdd.isIdle() && isTestFile && (testResult.failed > 0 || testResult.errors > 0)) { |
| 997 | const inferredName = (testResult.failures[0] && testResult.failures[0].name) || 'new test'; |
| 998 | tdd.beginCycle(inferredName); |
| 999 | // Re-run processTestResult so confirmRed fires on this same result |
| 1000 | } |
| 1001 | |
| 1002 | const gov = getTDDGovernor({ workdir: cwd }); |
| 1003 | const tddMsg = gov.processTestResult(testResult); |
| 1004 | |
| 1005 | const testSummary = `\n\n[harness] run_tests: ${testResult.summary}${tddMsg ? '\n[TDD] ' + tddMsg : ''}`; |
| 1006 | return { ...toolResult, result: (toolResult.result || '') + testSummary }; |
| 1007 | } catch { |
| 1008 | return toolResult; // never fail the write because of TDD auto-check |
| 1009 | } |
| 1010 | } |
| 1011 | |
| 1012 | // Wrap executeTool so the TDD post-write hook fires automatically. |
| 1013 | // This keeps the hook out of every individual tool case. |
no test coverage detected