import { createHash } from 'node:crypto' import fs from 'node:fs/promises' import path from 'node:path' import { parse } from '@babel/parser' import traverseModule from '@babel/traverse' import postcss from 'postcss' const EXPECTED_ROOT_SHA256 = '035254bc76310ea46317433e4840602094543ef323d2d5c5aff7c131729de918' const MAIN_EVIDENCE_PATH = '.tmp/rea-selected-editor-evidence.json' const DEPENDENCY_EVIDENCE_PATH = '.tmp/rea-selected-pierre-dependencies.json' const LEAF_EVIDENCE_PATH = '.tmp/rea-selected-pierre-leaf-dependencies.json' const LANGUAGE_EVIDENCE_PATH = '.tmp/rea-selected-pierre-ui-languages.json' const OUTPUT_DIRECTORY = path.resolve('src/renderer/src/workbuddy/artifacts/recovered-pierre') const VITE_PRELOAD_HELPER = '__vite__mapDeps' const RECOVERED_PRELOAD_HELPER = '__ycodePierreMapDeps' const traverse = traverseModule.default const SOURCE_FILES = { 'renderer/assets/codeEditor-D3P9alks.js': 'main', 'renderer/assets/codeEditor-Bxmo_AI3.css': 'css', 'package.json': 'package', 'renderer/assets/rolldown-runtime-BJCASTsb.js': 'asset', 'renderer/assets/preload-helper-D30X3e06.js': 'asset', 'renderer/assets/dist-BAqWIeie.js': 'asset', 'renderer/assets/dist-BUGqZtx5.js': 'asset', 'renderer/assets/worker-portable-D1lwTqsk.js': 'asset', 'renderer/assets/zwitch-B8a51bts.js': 'asset', 'renderer/assets/stringify-entities-i2atvqYU.js': 'asset', 'renderer/assets/hast-util-whitespace-DbScqzu3.js': 'asset', 'renderer/assets/pierre-dark-Daa2n9wr.js': 'asset', 'renderer/assets/pierre-light-D_hZXvUj.js': 'asset', 'renderer/assets/javascript-AfZCJ9Uc.js': 'asset', 'renderer/assets/typescript-4sRsPriL.js': 'asset', 'renderer/assets/diff-lAxbRYdS.js': 'asset', 'renderer/assets/css-NFwnoVns.js': 'asset', 'renderer/assets/html-Dq1ixqYb.js': 'asset', 'renderer/assets/json-CKKhFIOr.js': 'asset', 'renderer/assets/markdown-BSrOIEaF.js': 'asset', } const COPYING_ASSETS = Object.keys(SOURCE_FILES).filter((sourcePath) => SOURCE_FILES[sourcePath] === 'asset') const REACT_IMPORTS = new Map([ ['./react-z__Ncn__.js', 's'], ['./react-dom-mnR6psRT.js', 'c'], ['./jsx-runtime-DM1VED__.js', 'f'], ]) const sha256 = (value) => createHash('sha256').update(value).digest('hex') const fail = (message) => { throw new Error(message) } async function loadEvidence(filePath) { const evidence = JSON.parse(await fs.readFile(filePath, 'utf8')) if (evidence.authority !== 'shipped-artifact') fail(`Evidence is not shipped-artifact authority: ${filePath}`) if (evidence.normalized_result?.root_sha256 !== EXPECTED_ROOT_SHA256) { fail(`Evidence root SHA-256 does not match the selected WorkBuddy archive: ${filePath}`) } const files = new Map() for (const file of evidence.normalized_result.files) { const actualBytes = Buffer.byteLength(file.text, 'utf8') const actualSha256 = sha256(file.text) if (actualBytes !== file.size_bytes || actualSha256 !== file.sha256) { fail(`Evidence text failed size/SHA validation: ${file.path}`) } files.set(file.path, file) } return { evidence, files } } function collectPatternNames(node, names = []) { if (!node) return names if (node.type === 'Identifier') names.push(node.name) else if (node.type === 'RestElement') collectPatternNames(node.argument, names) else if (node.type === 'AssignmentPattern') collectPatternNames(node.left, names) else if (node.type === 'ArrayPattern') node.elements.forEach((entry) => collectPatternNames(entry, names)) else if (node.type === 'ObjectPattern') { for (const property of node.properties) { if (property.type === 'RestElement') collectPatternNames(property.argument, names) else collectPatternNames(property.value, names) } } return names } function collectDynamicImportPaths(source) { const ast = parse(source, { sourceType: 'module' }) const paths = new Set() traverse(ast, { ImportExpression(pathRef) { const sourceNode = pathRef.node.source if (sourceNode.type === 'StringLiteral') paths.add(sourceNode.value) else if (sourceNode.type === 'TemplateLiteral' && sourceNode.expressions.length === 0) { paths.add(sourceNode.quasis[0].value.cooked) } }, }) return paths } function renameTopLevelBinding(source, fromName, toName, sourcePath) { if (!source.includes(fromName)) return { source, renameCount: 0 } if (source.includes(toName)) fail(`Reserved recovery identifier already exists in ${sourcePath}`) const ast = parse(source, { sourceType: 'module' }) let foundBinding = false traverse(ast, { Program(pathRef) { pathRef.scope.crawl() if (pathRef.scope.getBinding(fromName)) { pathRef.scope.rename(fromName, toName) foundBinding = true } pathRef.stop() }, }) if (!foundBinding) return { source, renameCount: 0 } const edits = [] traverse(ast, { Identifier(pathRef) { const { start, end, name } = pathRef.node if (name === toName && source.slice(start, end) === fromName) edits.push({ start, end }) }, }) if (edits.length < 2) fail(`Babel scope rename did not capture the binding and its references in ${sourcePath}`) let renamedSource = source for (const { start, end } of edits.sort((left, right) => right.start - left.start)) { renamedSource = `${renamedSource.slice(0, start)}${toName}${renamedSource.slice(end)}` } return { source: renamedSource, renameCount: edits.length } } function closeBindings(source) { const ast = parse(source, { sourceType: 'module' }) let programPath traverse(ast, { Program(pathRef) { programPath = pathRef pathRef.scope.crawl() pathRef.stop() }, }) const included = new Map() const queue = [] const imported = new Map() const enqueue = (binding) => { if (!binding || binding.scope !== programPath.scope || included.has(binding.identifier.name)) return included.set(binding.identifier.name, binding) queue.push(binding) } const visitReferences = (pathRef) => { pathRef.traverse({ Identifier(reference) { if (!reference.isReferencedIdentifier() && !reference.isBindingIdentifier()) return enqueue(reference.scope.getBinding(reference.node.name)) }, }) } enqueue(programPath.scope.getBinding('Po')) while (queue.length > 0) { const binding = queue.shift() if (binding.kind === 'module') { const declaration = binding.path.findParent((candidate) => candidate.isImportDeclaration()) if (declaration) { const locals = imported.get(declaration.node.source.value) ?? new Set() locals.add(binding.identifier.name) imported.set(declaration.node.source.value, locals) } continue } if (binding.path.isFunctionDeclaration() || binding.path.isClassDeclaration()) { visitReferences(binding.path) continue } if (!binding.path.isVariableDeclarator()) continue if (binding.path.node.init) visitReferences(binding.path.get('init')) else { for (const violation of binding.constantViolations) { visitReferences(violation) const owner = violation.findParent((candidate) => candidate.isVariableDeclarator()) if (owner && owner !== binding.path && owner.node.id.type === 'Identifier') { enqueue(programPath.scope.getBinding(owner.node.id.name)) } } } } const declarationChunks = [] for (const statement of ast.program.body) { if (statement.type === 'ImportDeclaration') { if (REACT_IMPORTS.has(statement.source.value)) continue const names = imported.get(statement.source.value) if (!names || names.size === 0) continue const specifiers = statement.specifiers.filter((specifier) => names.has(specifier.local.name)) if (specifiers.length === 0) continue const defaultImport = specifiers.find((specifier) => specifier.type === 'ImportDefaultSpecifier') const namespaceImport = specifiers.find((specifier) => specifier.type === 'ImportNamespaceSpecifier') const namedImports = specifiers.filter((specifier) => specifier.type === 'ImportSpecifier') const parts = [] if (defaultImport) parts.push(defaultImport.local.name) if (namespaceImport) parts.push(`* as ${namespaceImport.local.name}`) if (namedImports.length > 0) { parts.push(`{ ${namedImports.map((specifier) => { const importedName = specifier.imported.name ?? specifier.imported.value return importedName === specifier.local.name ? importedName : `${importedName} as ${specifier.local.name}` }).join(', ')} }`) } declarationChunks.push(`import ${parts.join(', ')} from ${JSON.stringify(statement.source.value)};`) continue } if (statement.type === 'VariableDeclaration') { for (const declaration of statement.declarations) { const names = collectPatternNames(declaration.id) if (!names.some((name) => included.has(name))) continue declarationChunks.push(`${statement.kind} ${source.slice(declaration.start, declaration.end)};`) } continue } if ((statement.type === 'FunctionDeclaration' || statement.type === 'ClassDeclaration') && included.has(statement.id?.name)) { declarationChunks.push(source.slice(statement.start, statement.end)) } } const reactImports = [ `import * as __ycodeReact from 'react';`, `import * as __ycodeReactDOM from 'react-dom';`, `import * as __ycodeJsxRuntime from 'react/jsx-runtime';`, `const s = () => __ycodeReact;`, `const c = () => __ycodeReactDOM;`, `const f = () => __ycodeJsxRuntime;`, ] const prefix = [ `// Generated from REA shipped-artifact Evidence; edits belong in recover-pierre-diff.mjs.`, `// Source: renderer/assets/codeEditor-D3P9alks.js; sha256: 5e9a16dca97c102afc3c73cd7dd32ba63daf5e7ddff12707ee1ea63e7a427b19.`, ...reactImports, ].join('\n') const body = declarationChunks.join('\n') const suffix = [ `Po();`, `export { No as PierreDiffEditor, buildFileDiff, processFile, parseDiffFromFile, getFiletypeFromFileName };`, ].join('\n') return { code: `${prefix}\n${body}\n${suffix}\n`, bindingCount: included.size, imports: new Set(imported.keys()) } } async function writeIfAbsentOrSame(filePath, text) { try { const previous = await fs.readFile(filePath, 'utf8') if (previous === text) return const generatedEngine = path.basename(filePath) === 'engine.mjs' && previous.startsWith('// Generated from REA shipped-artifact Evidence; edits belong in recover-pierre-diff.mjs.') let generatedManifest = false if (path.basename(filePath) === 'manifest.json') { try { generatedManifest = JSON.parse(previous).kind === 'rea-selected-pierre-diff-recovery' } catch { generatedManifest = false } } if (!generatedEngine && !generatedManifest) fail(`Refusing to overwrite changed recovered artifact: ${filePath}`) await fs.writeFile(filePath, text, 'utf8') } catch (error) { if (error.code !== 'ENOENT') throw error await fs.writeFile(filePath, text, 'utf8') } } const [mainSource, dependencies, leafDependencies, uiLanguages] = await Promise.all([ loadEvidence(MAIN_EVIDENCE_PATH), loadEvidence(DEPENDENCY_EVIDENCE_PATH), loadEvidence(LEAF_EVIDENCE_PATH), loadEvidence(LANGUAGE_EVIDENCE_PATH), ]) const dynamicEvidencePaths = (await fs.readdir('.tmp')) .filter((fileName) => /^rea-selected-pierre-chunks-\d{3}\.json$/u.test(fileName)) .map((fileName) => path.join('.tmp', fileName)) .sort() if (dynamicEvidencePaths.length === 0) fail('No REA-selected Pierre dynamic chunk Evidence was found') const dynamicEvidence = await Promise.all(dynamicEvidencePaths.map(loadEvidence)) const evidenceSet = [mainSource, dependencies, leafDependencies, uiLanguages, ...dynamicEvidence] const sources = new Map() for (const evidence of evidenceSet) { for (const [sourcePath, file] of evidence.files) { const existing = sources.get(sourcePath) if (existing && (existing.sha256 !== file.sha256 || existing.size_bytes !== file.size_bytes)) { fail(`Conflicting REA Evidence for selected file ${sourcePath}`) } sources.set(sourcePath, file) } } for (const [sourcePath, expectedKind] of Object.entries(SOURCE_FILES)) { if (!sources.has(sourcePath)) fail(`Required selected REA source is missing (${expectedKind}): ${sourcePath}`) } const appPackage = JSON.parse(sources.get('package.json').text) if (appPackage.version !== '5.8.2') fail(`Unexpected WorkBuddy app version: ${appPackage.version}`) const mainText = sources.get('renderer/assets/codeEditor-D3P9alks.js').text const dynamicImportPaths = collectDynamicImportPaths(mainText) const dynamicAssetPaths = [...dynamicImportPaths].map((importPath) => { if (!importPath.startsWith('./') || !importPath.endsWith('.js')) { fail(`Unexpected non-local dynamic chunk path in CodeView: ${importPath}`) } return `renderer/assets/${importPath.slice(2)}` }) for (const sourcePath of dynamicAssetPaths) { if (!sources.has(sourcePath)) fail(`REA dynamic chunk evidence is missing ${sourcePath}`) } const extracted = closeBindings(mainText) if (extracted.bindingCount < 700) fail(`Pierre closure is unexpectedly incomplete: ${extracted.bindingCount} bindings`) if (extracted.imports.has('./src-0FGg1seX.js') || extracted.imports.has('./monaco-init-CE4MbM4x.js')) { fail('Pierre closure unexpectedly depends on app shared code or Monaco initialization') } const renamedEngine = renameTopLevelBinding( extracted.code, VITE_PRELOAD_HELPER, RECOVERED_PRELOAD_HELPER, 'recovered engine.mjs', ) const cssSource = sources.get('renderer/assets/codeEditor-Bxmo_AI3.css').text const cssAst = postcss.parse(cssSource) const cssRules = [] cssAst.walkRules((rule) => { if (rule.selectors?.some((selector) => selector.includes('_pierre-diff-editor'))) { cssRules.push(cssSource.slice(rule.source.start.offset, rule.source.end.offset)) } }) if (cssRules.length !== 8) fail(`Expected eight exact Pierre CSS module rules, found ${cssRules.length}`) await fs.mkdir(OUTPUT_DIRECTORY, { recursive: true }) await writeIfAbsentOrSame(path.join(OUTPUT_DIRECTORY, 'engine.mjs'), renamedEngine.source) await writeIfAbsentOrSame(path.join(OUTPUT_DIRECTORY, 'engine.css'), `${cssRules.join('\n')}\n`) const assetRecords = [] const copyingAssetPaths = [...new Set([...COPYING_ASSETS, ...dynamicAssetPaths])] for (const sourcePath of copyingAssetPaths) { const source = sources.get(sourcePath) if (!source) fail(`Required selected REA asset is missing: ${sourcePath}`) const fileName = path.posix.basename(sourcePath) const renamedAsset = renameTopLevelBinding( source.text, VITE_PRELOAD_HELPER, RECOVERED_PRELOAD_HELPER, sourcePath, ) await writeIfAbsentOrSame(path.join(OUTPUT_DIRECTORY, fileName), renamedAsset.source) assetRecords.push({ path: fileName, bytes: source.size_bytes, sha256: source.sha256, renamed_top_level_preload_helper_references: renamedAsset.renameCount, }) } const outputs = ['engine.mjs', 'engine.css', ...assetRecords.map((asset) => asset.path)] const outputRecords = [] for (const fileName of outputs) { const content = await fs.readFile(path.join(OUTPUT_DIRECTORY, fileName)) outputRecords.push({ path: fileName, bytes: content.length, sha256: sha256(content) }) } const manifest = { kind: 'rea-selected-pierre-diff-recovery', target: { name: appPackage.name, version: appPackage.version, root_sha256: EXPECTED_ROOT_SHA256 }, evidence: { renderer: mainSource.evidence.evidence_id, dependencies: dependencies.evidence.evidence_id, leaf_dependencies: leafDependencies.evidence.evidence_id, ui_languages: uiLanguages.evidence.evidence_id, dynamic_chunks: dynamicEvidence.map(({ evidence }) => evidence.evidence_id), }, renderer_source: { path: 'renderer/assets/codeEditor-D3P9alks.js', sha256: '5e9a16dca97c102afc3c73cd7dd32ba63daf5e7ddff12707ee1ea63e7a427b19', closure_program_bindings: extracted.bindingCount, imports: [...extracted.imports].sort(), dynamic_import_count: dynamicImportPaths.size, dynamic_import_files: dynamicAssetPaths, renamed_top_level_preload_helper: { from: VITE_PRELOAD_HELPER, to: RECOVERED_PRELOAD_HELPER, references: renamedEngine.renameCount, }, }, css_source: { path: 'renderer/assets/codeEditor-Bxmo_AI3.css', sha256: '1c8f2210c731a25f9051088df0db78b9de5b087c802b3a9e36828c1b6b54c353', exact_pierre_rules: cssRules.length, }, dynamic_chunk_assets: dynamicAssetPaths.length, vite_preload_helper_rename: { from: VITE_PRELOAD_HELPER, to: RECOVERED_PRELOAD_HELPER, affected_assets: assetRecords.filter((asset) => asset.renamed_top_level_preload_helper_references > 0) .map((asset) => ({ path: asset.path, references: asset.renamed_top_level_preload_helper_references })), }, limitations: [ 'The original package manifest contains no Pierre or Shiki package version; this is a source-locked bundle recovery, not an npm package pin.', 'The optional shiki-wasm branch references renderer/assets/wasm-B9ZqxnKj.js, which the REA selector reports absent; the recovered component config uses the shiki-js engine.', 'Every static dynamic import in codeEditor-D3P9alks.js was selected through REA and copied; unselected app-shared and Monaco bundles are excluded from this component closure.', ], assets: assetRecords, outputs: outputRecords, } await writeIfAbsentOrSame(path.join(OUTPUT_DIRECTORY, 'manifest.json'), `${JSON.stringify(manifest, null, 2)}\n`) console.log(JSON.stringify({ outputDirectory: OUTPUT_DIRECTORY, closureProgramBindings: extracted.bindingCount, closureBytes: Buffer.byteLength(extracted.code, 'utf8'), renamedPreloadHelperReferences: renamedEngine.renameCount, importedModules: [...extracted.imports].sort(), dynamicChunks: dynamicImportPaths.size, cssRules: cssRules.length, assets: assetRecords.length, manifest: path.join(OUTPUT_DIRECTORY, 'manifest.json'), }, null, 2))