import fs from 'node:fs';import path from 'node:path';import crypto from 'node:crypto';import {spawnSync} from 'node:child_process'; const state=JSON.parse(fs.readFileSync('C:/laragon/data/sgf-tempo/run/modular-regression-current.json','utf8'));if(state.port!==55439)throw Error('Owned QA artifact root required'); const tag=crypto.randomBytes(6).toString('hex'),root=path.join(state.root,'private/finance-bundle-'+tag),sha=p=>crypto.createHash('sha256').update(fs.readFileSync(p)).digest('hex');fs.mkdirSync(root);const files=[]; const copy=(source,file)=>{const destination=path.join(root,file);fs.mkdirSync(path.dirname(destination),{recursive:true});fs.copyFileSync(source,destination);files.push({file,sha256:sha(destination)});}; copy('packages/finance-bundle/Bundle.php','Bundle.php'); for(const name of ['payables','general-ledger']){for(const file of ['bootstrap.php','README.md'])if(fs.existsSync('packages/'+name+'/'+file))copy('packages/'+name+'/'+file,name+'/'+file);for(const dir of ['src','ui'])for(const file of fs.readdirSync('packages/'+name+'/'+dir).sort()){if(!/^[A-Za-z0-9_-]+\.php$/.test(file))throw Error('Unexpected runtime source');copy('packages/'+name+'/'+dir+'/'+file,name+'/'+dir+'/'+file);}} files.sort((a,b)=>a.file.localeCompare(b.file));const manifest=path.join(root,'manifest.json');fs.writeFileSync(manifest,JSON.stringify({contract:'COMMON-FINANCE-BUNDLE-v1',synthetic_only:true,files},null,2)+'\n');const hash=sha(manifest); const code='require $argv[1]."/Bundle.php"; echo json_encode(Tempo\\Finance\\Composition\\Bundle::verify($argv[1],$argv[2]));'; const test=spawnSync('C:/laragon/tools/sgf-tempo/php-8.4.27/php.exe',['-r',code,root,hash],{encoding:'utf8',windowsHide:true});if(test.status!==0)throw Error('Fresh artifact verification failed'); const record={tag,root,manifest_sha256:hash,files:files.length,tests_or_credentials_included:false,installed_or_activated:false};fs.writeFileSync(path.join(state.root,'finance-bundle-latest.json'),JSON.stringify(record,null,2)+'\n');console.log(JSON.stringify(record));