11import { readFileSync , realpathSync } from 'node:fs' ;
22import { isAbsolute , join , relative , resolve } from 'node:path' ;
33
4+ import type { SkillHostDocument , SkillIr , SkillSidecarRef } from '../skills/ir.ts' ;
5+ import type { Diagnostic } from './diagnostics.ts' ;
46import { digest } from './digest.ts' ;
57import { deepFreeze } from './freeze.ts' ;
68import { isInsideOrEqual } from './paths.ts' ;
@@ -209,6 +211,46 @@ const canonicalProvenance = (root: string, provenance: SourceProvenance): Source
209211 sourcePath : canonicalCompilerPath ( root , provenance . sourcePath , 'Model provenance path' ) ,
210212} ) ;
211213
214+ const canonicalDiagnostic = ( root : string , diagnostic : Diagnostic ) : Diagnostic => ( {
215+ ...diagnostic ,
216+ ...( diagnostic . generatedPath === undefined
217+ ? { }
218+ : { generatedPath : canonicalCompilerPath ( root , diagnostic . generatedPath , 'Diagnostic generated path' ) } ) ,
219+ ...( diagnostic . sourcePath === undefined
220+ ? { }
221+ : { sourcePath : canonicalCompilerPath ( root , diagnostic . sourcePath , 'Diagnostic source path' ) } ) ,
222+ } ) ;
223+
224+ const canonicalSkillSidecar = ( root : string , sidecar : SkillSidecarRef ) : SkillSidecarRef => ( {
225+ ...sidecar ,
226+ ...( sidecar . source === undefined
227+ ? { }
228+ : { source : canonicalCompilerPath ( root , sidecar . source , 'Skill sidecar source path' ) } ) ,
229+ } ) ;
230+
231+ const canonicalSkillIr = ( root : string , skillIr : SkillIr ) : SkillIr => ( {
232+ ...skillIr ,
233+ diagnostics : skillIr . diagnostics . map ( ( diagnostic ) => canonicalDiagnostic ( root , diagnostic ) ) ,
234+ resources : skillIr . resources . map ( ( resource ) => ( {
235+ ...resource ,
236+ source : canonicalCompilerPath ( root , resource . source , 'Skill IR resource path' ) ,
237+ } ) ) ,
238+ sidecars : skillIr . sidecars . map ( ( sidecar ) => canonicalSkillSidecar ( root , sidecar ) ) ,
239+ source : canonicalCompilerPath ( root , skillIr . source , 'Skill IR source path' ) ,
240+ } ) ;
241+
242+ const canonicalHostDocuments = (
243+ root : string ,
244+ hostDocuments : Readonly < Record < string , SkillHostDocument > > ,
245+ ) : Readonly < Record < string , SkillHostDocument > > =>
246+ Object . fromEntries ( Object . entries ( hostDocuments )
247+ . sort ( ( [ left ] , [ right ] ) => left . localeCompare ( right ) )
248+ . map ( ( [ host , document ] ) => [ host , {
249+ ...document ,
250+ diagnostics : document . diagnostics . map ( ( diagnostic ) => canonicalDiagnostic ( root , diagnostic ) ) ,
251+ sidecars : document . sidecars . map ( ( sidecar ) => canonicalSkillSidecar ( root , sidecar ) ) ,
252+ } ] ) ) ;
253+
212254const modelPathReferences = ( model : NormalizedPlugin ) : readonly string [ ] => [
213255 model . metadata . provenance . sourcePath ,
214256 ...( model . assets ?? [ ] ) . flatMap ( ( asset ) => [ asset . provenance . sourcePath , asset . source ] ) ,
@@ -226,6 +268,22 @@ const modelPathReferences = (model: NormalizedPlugin): readonly string[] => [
226268 skill . provenance . sourcePath ,
227269 skill . source ,
228270 ...skill . resources . map ( ( resource ) => resource . source ) ,
271+ ...( skill . skillIr === undefined
272+ ? [ ]
273+ : [
274+ skill . skillIr . source ,
275+ ...skill . skillIr . resources . map ( ( resource ) => resource . source ) ,
276+ ...skill . skillIr . sidecars . flatMap ( ( sidecar ) => sidecar . source === undefined ? [ ] : [ sidecar . source ] ) ,
277+ ...skill . skillIr . diagnostics . flatMap ( ( diagnostic ) =>
278+ diagnostic . sourcePath === undefined ? [ ] : [ diagnostic . sourcePath ] ) ,
279+ ] ) ,
280+ ...( skill . hostDocuments === undefined
281+ ? [ ]
282+ : Object . values ( skill . hostDocuments ) . flatMap ( ( document ) => [
283+ ...document . diagnostics . flatMap ( ( diagnostic ) =>
284+ diagnostic . sourcePath === undefined ? [ ] : [ diagnostic . sourcePath ] ) ,
285+ ...document . sidecars . flatMap ( ( sidecar ) => sidecar . source === undefined ? [ ] : [ sidecar . source ] ) ,
286+ ] ) ) ,
229287 ] ) ,
230288 ...model . scripts . flatMap ( ( script ) => [ script . provenance . sourcePath , script . source ] ) ,
231289 ...model . mcpServers . flatMap ( ( server ) => [
@@ -367,11 +425,15 @@ export const canonicalizeNormalizedModel = (
367425 skills : detached . skills . map ( ( skill ) => ( {
368426 ...skill ,
369427 dir : canonicalCompilerPath ( root , skill . dir , 'Skill directory path' ) ,
428+ ...( skill . hostDocuments === undefined
429+ ? { }
430+ : { hostDocuments : canonicalHostDocuments ( root , skill . hostDocuments ) } ) ,
370431 provenance : canonicalProvenance ( root , skill . provenance ) ,
371432 resources : skill . resources . map ( ( resource ) => ( {
372433 ...resource ,
373434 source : canonicalCompilerPath ( root , resource . source , 'Skill resource path' ) ,
374435 } ) ) ,
436+ ...( skill . skillIr === undefined ? { } : { skillIr : canonicalSkillIr ( root , skill . skillIr ) } ) ,
375437 source : canonicalCompilerPath ( root , skill . source , 'Skill source path' ) ,
376438 } ) ) ,
377439 targets : detached . targets . map ( ( target ) => ( {
0 commit comments