11import fs from 'node:fs'
22import path from 'node:path'
3- import { fetchDocsFromRepo } from './fetchDocs.js'
3+ import { ensureRepoCheckout , fetchDocsFromRepo } from './fetchDocs.js'
44import { indexDocsSnapshot } from './indexDocs.js'
55import { buildTopicsIndex } from './buildTopics.js'
66import { renderSkillMd } from './renderSkill.js'
77import { renderLibraryAgent } from './renderLibraryAgent.js'
88import { renderTanstackAgent } from './renderTanstackAgent.js'
9- import { computeTemplatesHash , writeProvenance } from './provenance.js'
9+ import {
10+ computeSignature ,
11+ computeTemplatesHash ,
12+ writeProvenance ,
13+ } from './provenance.js'
1014import { readCatalog } from './catalog.js'
1115import { git } from './git.js'
16+ import { extractRecentChanges } from './changelog.js'
1217
1318type CatalogRepo = {
1419 repo : string
@@ -103,10 +108,18 @@ function writeProvenanceFromExisting(args: {
103108 commitSha : string
104109 templatesHash : string
105110 compilerVersion : string
111+ changelogHash : string
106112} ) {
107113 const provenancePath = path . join ( args . outDir , 'provenance.json' )
108114 const prev = readJsonIfExists < any > ( provenancePath ) ?? { }
109115
116+ const signature = computeSignature ( {
117+ docsHash : prev . docs_hash ?? 'sha256:0' ,
118+ templatesHash : args . templatesHash ,
119+ changelogHash : args . changelogHash ,
120+ compilerVersion : args . compilerVersion ,
121+ } )
122+
110123 const provenance = {
111124 schema : 1 ,
112125 lib : prev . lib ,
@@ -116,8 +129,9 @@ function writeProvenanceFromExisting(args: {
116129 commitSha : args . commitSha ,
117130 docs_hash : prev . docs_hash ,
118131 templates_hash : args . templatesHash ,
132+ changelog_hash : args . changelogHash ,
119133 compiler_version : args . compilerVersion ,
120- signature : prev . signature ,
134+ signature,
121135 generated_at : new Date ( ) . toISOString ( ) ,
122136 }
123137
@@ -221,21 +235,33 @@ export async function buildLib(args: {
221235 throw err
222236 }
223237
238+ const { worktree } = ensureRepoCheckout ( { repoUrl, ref } )
239+ const { lines : recentChanges , hash : changelogHash } =
240+ extractRecentChanges ( {
241+ worktree,
242+ version : args . version ,
243+ tagPattern : pattern ,
244+ } )
245+
224246 const existingBuild = readJsonIfExists < any > (
225247 path . join ( outAbs , 'build.json' ) ,
226248 )
227249 const existingProv = readJsonIfExists < any > (
228250 path . join ( outAbs , 'provenance.json' ) ,
229251 )
230252
231- if (
253+ const matchesExistingCore =
232254 existingBuild &&
233255 existingProv &&
234256 existingBuild . repo === repoUrl &&
235257 existingBuild . ref === ref &&
236258 existingBuild . commitSha === commitSha &&
237259 existingProv . templates_hash === templatesHash &&
238260 existingProv . compiler_version === compilerVersion
261+
262+ if (
263+ matchesExistingCore &&
264+ existingProv . changelog_hash === changelogHash
239265 ) {
240266 console . log ( `Skill build result: skipped (${ args . lib } @${ args . version } )` )
241267 console . log (
@@ -244,9 +270,53 @@ export async function buildLib(args: {
244270 return
245271 }
246272
273+ if ( matchesExistingCore ) {
274+ console . log (
275+ `Skill build result: updated-changelog (${ args . lib } @${ args . version } )` ,
276+ )
277+ console . log (
278+ `Updating changelog for ${ args . lib } @${ args . version } from ${ repoUrl } @${ ref } (${ commitSha } ).` ,
279+ )
280+
281+ renderSkillMd ( {
282+ library : args . lib ,
283+ version : args . version ,
284+ outDir : outAbs ,
285+ recentChanges,
286+ } )
287+
288+ writeProvenanceFromExisting ( {
289+ outDir : outAbs ,
290+ version : args . version ,
291+ repoUrl,
292+ ref,
293+ commitSha,
294+ templatesHash,
295+ compilerVersion,
296+ changelogHash,
297+ } )
298+
299+ const buildJson = {
300+ lib : args . lib ,
301+ version : args . version ,
302+ repo : repoUrl ,
303+ ref,
304+ commitSha,
305+ generatedAt : new Date ( ) . toISOString ( ) ,
306+ }
307+
308+ fs . writeFileSync (
309+ path . join ( outAbs , 'build.json' ) ,
310+ JSON . stringify ( buildJson , null , 2 ) + '\n' ,
311+ )
312+
313+ return
314+ }
315+
247316 const latest = findLatestBuild ( { repoRoot : args . repoRoot , lib : args . lib } )
248317 const canReuseLatest =
249318 latest &&
319+ latest . dir !== outAbs &&
250320 latest . build ?. repo === repoUrl &&
251321 latest . build ?. commitSha === commitSha &&
252322 latest . provenance ?. templates_hash === templatesHash &&
@@ -263,6 +333,12 @@ export async function buildLib(args: {
263333 cloneDirWithHardlinks ( latest . dir , outAbs )
264334
265335 updateSkillVersion ( outAbs , args . version )
336+ renderSkillMd ( {
337+ library : args . lib ,
338+ version : args . version ,
339+ outDir : outAbs ,
340+ recentChanges,
341+ } )
266342 writeProvenanceFromExisting ( {
267343 outDir : outAbs ,
268344 version : args . version ,
@@ -271,6 +347,7 @@ export async function buildLib(args: {
271347 commitSha,
272348 templatesHash,
273349 compilerVersion,
350+ changelogHash,
274351 } )
275352
276353 const buildJson = {
@@ -319,7 +396,12 @@ export async function buildLib(args: {
319396 version : args . version ,
320397 outDir,
321398 } )
322- renderSkillMd ( { library : args . lib , version : args . version , outDir } )
399+ renderSkillMd ( {
400+ library : args . lib ,
401+ version : args . version ,
402+ outDir,
403+ recentChanges,
404+ } )
323405
324406 writeProvenance ( {
325407 lib : args . lib ,
@@ -329,6 +411,7 @@ export async function buildLib(args: {
329411 indexRoot,
330412 compiler : { name : '@tanstack/skillc' , version : compilerVersion } ,
331413 templatesRoot,
414+ changelogHash,
332415 } )
333416
334417 const revisionPath = path . join ( sourceRoot , 'REVISION.json' )
0 commit comments