( jsonPath: string, options: DiffScopeOptions, )
| 67 | } |
| 68 | |
| 69 | async function buildChaptersFile( |
| 70 | jsonPath: string, |
| 71 | options: DiffScopeOptions, |
| 72 | ): Promise<BuiltChaptersFile> { |
| 73 | const absolute = path.resolve(jsonPath); |
| 74 | const raw = readFileSync(absolute, "utf8"); |
| 75 | const parsed = JSON.parse(raw) as unknown; |
| 76 | |
| 77 | // A fully-formed chapters file carries its own scope, so the diff isn't |
| 78 | // recomputed from the working tree or PR. `--pr` still records which PR the |
| 79 | // run targets (so the UI resolves the right one) — only the number is needed |
| 80 | // here, not a fetch, since the scope already comes from the file. |
| 81 | const fullResult = ChaptersFileSchema.safeParse(parsed); |
| 82 | if (fullResult.success) { |
| 83 | const prNumber = options.pr === undefined ? null : pullRequestNumberFromRef(options.pr); |
| 84 | return { chaptersFile: fullResult.data, prNumber }; |
| 85 | } |
| 86 | |
| 87 | const agentResult = AgentOutputSchema.safeParse(parsed); |
| 88 | if (agentResult.success) { |
| 89 | const { scope, rawDiff, prNumber } = await resolveDiffScope(options); |
| 90 | return { chaptersFile: assembleChaptersFile(agentResult.data, scope, rawDiff), prNumber }; |
| 91 | } |
| 92 | |
| 93 | throw fullResult.error; |
| 94 | } |
| 95 | |
| 96 | function assembleChaptersFile( |
| 97 | agentOutput: AgentOutput, |
no test coverage detected