( agentOutput: AgentOutput, scope: Scope, rawDiff: string, )
| 94 | } |
| 95 | |
| 96 | function assembleChaptersFile( |
| 97 | agentOutput: AgentOutput, |
| 98 | scope: Scope, |
| 99 | rawDiff: string, |
| 100 | ): ChaptersFile { |
| 101 | const allFiles = parseGitDiff(rawDiff); |
| 102 | const stageIgnore = loadStageIgnore(readRepoRoot()); |
| 103 | const { files: filteredFiles, excludedByPath } = filterFilesForLlm(allFiles, stageIgnore); |
| 104 | |
| 105 | validateHunkCoverage(filteredFiles, agentOutput.chapters); |
| 106 | const sanitized = sanitizeLineRefs(agentOutput.chapters, filteredFiles); |
| 107 | |
| 108 | const chapters = [...sanitized]; |
| 109 | const otherChanges = buildOtherChangesChapter(allFiles, excludedByPath); |
| 110 | if (otherChanges) { |
| 111 | chapters.push({ ...otherChanges, order: chapters.length + 1 }); |
| 112 | } |
| 113 | |
| 114 | return { |
| 115 | scope, |
| 116 | chapters, |
| 117 | prologue: agentOutput.prologue, |
| 118 | generatedAt: new Date().toISOString(), |
| 119 | }; |
| 120 | } |
| 121 | |
| 122 | function validateHunkCoverage( |
| 123 | filteredFiles: { path: string; hunks: { oldStart: number }[] }[], |
no test coverage detected