Files
ycode/scripts/rea/ui-designer-audit.mjs
T

72 lines
5.1 KiB
JavaScript

/** Offline audit of retained REA exports. Never opens the original package. */
import fs from 'node:fs'
import path from 'node:path'
import assert from 'node:assert/strict'
import crypto from 'node:crypto'
import { parse } from 'yaml'
const root = path.resolve('.tmp/rea-ui-designer-recovered-20261016')
const manifest = JSON.parse(fs.readFileSync(path.join(root, 'evidence-manifest.json'), 'utf8'))
const pin = 'c9c83df190f0f0f871706d52b7e372f20b7ad63fde739f59cf9181ace1d08afa'
const inventory = JSON.parse(fs.readFileSync(manifest.retainedInventory, 'utf8'))
const sha = bytes => crypto.createHash('sha256').update(bytes).digest('hex')
assert.equal(manifest.rootSha256, pin)
assert.equal(inventory.normalized_result.root_sha256, pin)
assert.equal(inventory.evidence_id, manifest.inventoryEvidenceId)
assert.equal(inventory.normalized_result.coverage.status, 'complete')
assert.equal(manifest.remaining.length, 0)
assert.equal(manifest.files.length, 143)
assert.deepEqual(manifest.excluded.map(item => item.path), ['.downloaded_at'])
const expected = inventory.normalized_result.members.filter(item => item.kind === 'file' && item.path !== '.downloaded_at')
assert.deepEqual(manifest.files.map(item => item.path).sort(), expected.map(item => item.path).sort())
const evidence = new Map(), checks = []
for (const file of manifest.files) {
const destination = path.resolve(root, file.path), relative = path.relative(root, destination)
assert(!path.isAbsolute(relative) && relative !== '..' && !relative.startsWith('..' + path.sep))
const bytes = fs.readFileSync(destination), source = expected.find(item => item.path === file.path)
assert.equal(bytes.length, source.size_bytes, file.path)
assert.equal(sha(bytes), source.sha256, file.path)
assert.equal(file.bytes, bytes.length, file.path)
assert.equal(file.sha256, source.sha256, file.path)
if (!evidence.has(file.retainedExport)) evidence.set(file.retainedExport, JSON.parse(fs.readFileSync(file.retainedExport, 'utf8')))
const exported = evidence.get(file.retainedExport)
assert.equal(exported.evidence_id, file.evidenceId)
assert.equal(exported.normalized_result.root_sha256, pin)
const selected = exported.normalized_result.files.find(item => item.path === file.path)
assert(selected, file.path)
const selectedBytes = file.encoding === 'base64' ? Buffer.from(selected.data_base64, 'base64') : Buffer.from(selected.text, 'utf8')
assert.equal(selected.sha256, source.sha256, file.path)
assert.equal(selected.size_bytes, bytes.length, file.path)
assert(bytes.equals(selectedBytes), file.path)
checks.push({ path: file.path, bytes: bytes.length, sha256: sha(bytes), evidenceId: exported.evidence_id, retainedExport: file.retainedExport, pass: true })
}
const read = file => fs.readFileSync(path.join(root, file), 'utf8')
const frontmatter = file => parse(read(file).match(/^---\r?\n([\s\S]*?)\r?\n---/)?.[1] ?? '')
const plugin = JSON.parse(read('.codebuddy-plugin/plugin.json'))
assert.equal(plugin.name, 'ui-designer')
assert.deepEqual(plugin.skills, ['./skills/impeccable', './skills/frontend-dev', './skills/browser-use'])
const skills = plugin.skills.map(file => ({ path: file, metadata: frontmatter(file + '/SKILL.md') }))
for (const file of plugin.agents) assert(manifest.files.some(item => './' + item.path === file))
for (const skill of plugin.skills) assert(manifest.files.some(item => './' + item.path === skill + '/SKILL.md'))
assert(!manifest.files.some(item => item.path.endsWith('.mcp.json')))
const miniMaxScripts = manifest.files.filter(item => /frontend-dev\/scripts\/.*\.py$/.test(item.path)).map(item => {
const source = read(item.path)
assert(source.includes('import requests'))
for (const key of ['MINIMAX_API_KEY', 'MINIMAX_API_BASE']) assert(source.includes(`os.getenv("${key}")`))
return { path: item.path, requires: ['Python', 'requests', 'MINIMAX_API_KEY', 'MINIMAX_API_BASE'] }
})
assert.equal(miniMaxScripts.length, 4)
const html = read('skills/frontend-dev/templates/viewer.html')
const templateRemoteUrls = [...new Set(html.match(/https:\/\/[^"'<>\s]+/g))]
const groups = Object.fromEntries(['.ttf', '.png', '.LICENSE', '.html', '.py'].map(extension => {
const files = manifest.files.filter(item => item.path.endsWith(extension))
return [extension, { files: files.length, bytes: files.reduce((sum, item) => sum + item.bytes, 0) }]
}))
const report = { rootSha256: pin, inventoryEvidenceId: inventory.evidence_id, packageVersion: plugin.version,
functionalFiles: checks.length, functionalBytes: checks.reduce((sum, item) => sum + item.bytes, 0),
excluded: manifest.excluded, remaining: 0, evidenceExports: evidence.size, groups, plugin, skills, miniMaxScripts,
templateRemoteUrls, checks, scope: 'REA byte recovery and offline dependency analysis; no execution, installation, remote request, or original runtime behavior verification' }
const reportPath = path.resolve('.tmp/rea-ui-designer-audit-20261016.json')
fs.writeFileSync(reportPath, JSON.stringify(report, null, 2) + '\n')
console.log(JSON.stringify({ report: reportPath, rootSha256: pin, verified: checks.length, bytes: report.functionalBytes, remaining: 0, exports: evidence.size, groups, templateRemoteUrls }, null, 2))