@@ -34,6 +34,58 @@ const { resolveDataSchema } = require("./data_schema_normalizer.cjs");
3434const { clearValidationMarker, formatJSONFiles, runCustomMemoryValidation, writeValidationMarker } = require ( "./memory_custom_validation.cjs" ) ;
3535const { compileFileGlobPatterns, isMemoryFileEligible } = require ( "./memory_file_eligibility.cjs" ) ;
3636
37+ function createEligibleMemoryValidationView ( memoryDir , isEligibleFile ) {
38+ let validationDir ;
39+ try {
40+ validationDir = fs . mkdtempSync ( path . join ( os . tmpdir ( ) , "gh-aw-repo-memory-validation-" ) ) ;
41+ } catch ( error ) {
42+ throw new Error ( `${ ERR_SYSTEM } : Failed to create repo-memory validation directory: ${ getErrorMessage ( error ) } ` , { cause : error } ) ;
43+ }
44+
45+ /**
46+ * @param {string } targetPath
47+ */
48+ function removeValidationDirectory ( targetPath ) {
49+ try {
50+ fs . rmSync ( targetPath , { recursive : true , force : true } ) ;
51+ } catch ( error ) {
52+ throw new Error ( `${ ERR_SYSTEM } : Failed to remove repo-memory validation directory: ${ getErrorMessage ( error ) } ` , { cause : error } ) ;
53+ }
54+ }
55+
56+ try {
57+ /**
58+ * @param {string } sourceDir
59+ * @param {string } relativePath
60+ */
61+ function copyEligibleFiles ( sourceDir , relativePath ) {
62+ for ( const entry of fs . readdirSync ( sourceDir , { withFileTypes : true } ) ) {
63+ const sourcePath = path . join ( sourceDir , entry . name ) ;
64+ const relativeFilePath = relativePath ? path . join ( relativePath , entry . name ) : entry . name ;
65+ if ( entry . isDirectory ( ) ) {
66+ if ( entry . name !== ".git" ) {
67+ copyEligibleFiles ( sourcePath , relativeFilePath ) ;
68+ }
69+ } else if ( entry . isFile ( ) && isEligibleFile ( relativeFilePath ) ) {
70+ const targetPath = path . join ( validationDir , relativeFilePath ) ;
71+ fs . mkdirSync ( path . dirname ( targetPath ) , { recursive : true } ) ;
72+ fs . copyFileSync ( sourcePath , targetPath ) ;
73+ }
74+ }
75+ }
76+
77+ copyEligibleFiles ( memoryDir , "" ) ;
78+ return validationDir ;
79+ } catch ( error ) {
80+ try {
81+ removeValidationDirectory ( validationDir ) ;
82+ } catch ( cleanupError ) {
83+ throw new Error ( `${ ERR_SYSTEM } : Failed to create repo-memory validation view: ${ getErrorMessage ( error ) } ; cleanup also failed: ${ getErrorMessage ( cleanupError ) } ` , { cause : error } ) ;
84+ }
85+ throw error ;
86+ }
87+ }
88+
3789/** PR event names used for target:triggering context validation across all safe-output handlers. */
3890const PR_EVENT_NAMES = new Set ( [ "pull_request" , "pull_request_target" , "pull_request_review" , "pull_request_review_comment" ] ) ;
3991
@@ -1849,7 +1901,7 @@ function createHandlers(server, appendSafeOutput, config = {}) {
18491901
18501902 if ( memoryConf . format_json === true ) {
18511903 try {
1852- const formattedFiles = formatJSONFiles ( memoryDir , maxFileSize ) ;
1904+ const formattedFiles = formatJSONFiles ( memoryDir , maxFileSize , isEligibleFile ) ;
18531905 if ( formattedFiles . length > 0 ) {
18541906 core . info ( `Formatted ${ formattedFiles . length } repo-memory JSON file(s) before validation: ${ formattedFiles . join ( ", " ) } ` ) ;
18551907 }
@@ -1971,12 +2023,14 @@ function createHandlers(server, appendSafeOutput, config = {}) {
19712023 let patchSizeBytes ;
19722024 try {
19732025 ensureSafeDirectoryTrust ( memoryDir , server ) ;
2026+ const stagedFiles = execGitSync ( [ "diff" , "--cached" , "--no-renames" , "--name-only" , "-z" ] , { cwd : memoryDir , stdio : "pipe" } ) . split ( "\0" ) . filter ( Boolean ) . filter ( isEligibleFile ) ;
19742027 const trackedFiles = execGitSync ( [ "ls-files" , "-z" ] , { cwd : memoryDir , stdio : "pipe" } ) . split ( "\0" ) . filter ( Boolean ) . filter ( isEligibleFile ) ;
19752028 const filesToStage = [ ...new Set ( [ ...files . map ( file => file . relativePath ) , ...trackedFiles ] ) ] ;
19762029 if ( filesToStage . length > 0 ) {
19772030 execGitSync ( [ "add" , "--sparse" , "--all" , "--" , ...filesToStage . map ( file => `:(literal)${ file } ` ) ] , { cwd : memoryDir , stdio : "pipe" } ) ;
19782031 }
1979- patchSizeBytes = getStagedPatchDiffSizeBytes ( { execGitSyncFn : execGitSync , cwd : memoryDir } ) ;
2032+ const filesToMeasure = [ ...new Set ( [ ...stagedFiles , ...filesToStage ] ) ] . map ( file => `:(literal)${ file } ` ) ;
2033+ patchSizeBytes = getStagedPatchDiffSizeBytes ( { execGitSyncFn : execGitSync , cwd : memoryDir , pathspecs : filesToMeasure } ) ;
19802034 } catch ( /** @type {any } */ error ) {
19812035 return {
19822036 content : [
@@ -2017,13 +2071,22 @@ function createHandlers(server, appendSafeOutput, config = {}) {
20172071 /** @type {ReturnType<typeof runCustomMemoryValidation> | null } */
20182072 let customValidation = null ;
20192073 if ( validationConfig ) {
2020- customValidation = runCustomMemoryValidation ( {
2021- script : validationScript ,
2022- memoryDir,
2023- memoryId,
2024- kind : "repo" ,
2025- timeoutSeconds : validationTimeoutSeconds ,
2026- } ) ;
2074+ const validationDir = createEligibleMemoryValidationView ( memoryDir , isEligibleFile ) ;
2075+ try {
2076+ customValidation = runCustomMemoryValidation ( {
2077+ script : validationScript ,
2078+ memoryDir : validationDir ,
2079+ memoryId,
2080+ kind : "repo" ,
2081+ timeoutSeconds : validationTimeoutSeconds ,
2082+ } ) ;
2083+ } finally {
2084+ try {
2085+ fs . rmSync ( validationDir , { recursive : true , force : true } ) ;
2086+ } catch ( error ) {
2087+ throw new Error ( `${ ERR_SYSTEM } : Failed to clean up repo-memory validation directory: ${ getErrorMessage ( error ) } ` , { cause : error } ) ;
2088+ }
2089+ }
20272090 if ( ! customValidation . ok ) {
20282091 const reason = customValidation . timedOut ? `timed out after ${ validationTimeoutSeconds || 30 } second(s)` : `exited with code ${ customValidation . exitCode } ` ;
20292092 return {
0 commit comments