chore: establish YCode replication baseline and TODO

This commit is contained in:
xiaohan.yuan committed 2026-10-17 02:43:49 +08:00
commit 6dc59f89ba
1118 files changed
+196002

No files matched your search

+139
View File
@@ -0,0 +1,139 @@
// Recover pure panel geometry and source motion CSS from fixed REA artifacts only.
import { readFile, writeFile } from 'node:fs/promises'
import { createHash } from 'node:crypto'
import { resolve } from 'node:path'
import { parse } from '@babel/parser'
import postcss from 'postcss'
const runtimeEvidenceId = 'ev_717fa5e846e64d67ac19c8925d121bff632c0d3aefb3603b10858559cabb2dcb'
const cssEvidenceId = 'ev_377c8790468b3c67dad8577aabb327f98d3140659f0fffdbabfcff5a40cc9e94'
const runtimeFile = 'contexts-BMeWSUHk.js'
const runtimeSha256 = '5f35b7489b107e21ef452c8ee88a95265756f6fc444841eef869228bbc44768b'
const motionFile = 'desktop-sdk-setup-Bh0rg_xP.css'
const motionSha256 = 'b2ee58c0caf560eeddc4eb8c91d86cabddbec634b8d37ed5d6b85d0644c0e142'
const tokenFile = 'tokens-Df-i-zsO.css'
const tokenSha256 = '13f2bf82c96e5167a7d7098e36950c6c22c475b3337dbb8bb29ad2fe79cde696'
const hash = text => createHash('sha256').update(text).digest('hex')
const runtime = JSON.parse(await readFile(resolve('.tmp/rea-runtime-scripts.json'), 'utf8'))
if (runtime.evidence_id !== runtimeEvidenceId) throw new Error('Fixed runtime Evidence changed')
const matches = runtime.items.filter(item => item.file_path?.replaceAll('\\', '/').endsWith(`/renderer/assets/${runtimeFile}`))
if (matches.length !== 1) throw new Error('Expected exactly one panel layout runtime source')
const artifact = matches[0].source?.artifact
if (!matches[0].source.included || !artifact?.text || hash(artifact.text) !== runtimeSha256 || artifact.sha256 !== runtimeSha256) throw new Error('Fixed panel runtime SHA-256 mismatch')
const source = artifact.text
const ast = parse(source, { sourceType: 'module' })
const constantNames = ['Rw', 'zw', 'Bw', 'Vw', 'JQe', 'f$e', 'p$e']
const definitions = {
normalizeInset: { parameters: 'e: number', result: 'number' },
clampSidebarWidth: { parameters: 'e: number', result: 'number' },
resolveSidebarDragAction: { parameters: 'e: number, t: boolean', result: "'expand' | 'keep-collapsed' | 'collapse' | 'resize'" },
resolveChatAreaAvailableWidth: { parameters: 'e: PanelAvailableWidthInput', result: 'number' },
resolveDetailDrawerWidth: { parameters: 'e: DetailDrawerWidthInput', result: 'number' },
resolveLeadingInsetRebalanceWidth: { parameters: 'e: LeadingInsetRebalanceInput', result: 'number | undefined' },
resolveDetailPanelLayoutWidths: { parameters: 'e: DetailPanelLayoutInput', result: 'DetailPanelLayoutWidths | undefined' },
resolveRememberedDetailWidth: { parameters: 'e: readonly (number | null | undefined)[], t: number', implementationParameters: 'e: readonly any[], t: number', result: 'number' },
resolveChatAreaWidth: { parameters: 'e: number, t: number', result: 'number' },
getNarrowState: { parameters: 'e: number, t: number = 0', result: 'NarrowLayoutState' },
stickyNarrow: { parameters: 'e: boolean, t: number, n: number', result: 'boolean' },
resolveNarrowState: { parameters: 'e: NarrowLayoutState | null | undefined, t: number, n: number = 0', result: 'NarrowLayoutState' }
}
const functions = new Map(), constants = new Map()
function walk(node) {
if (!node || typeof node !== 'object') return
if (node.type === 'FunctionDeclaration' && definitions[node.id?.name]) {
if (functions.has(node.id.name)) throw new Error(`Duplicate source function ${node.id.name}`)
functions.set(node.id.name, node)
}
if (node.type === 'AssignmentExpression' && node.left.type === 'Identifier' && constantNames.includes(node.left.name)
&& (node.right.type === 'ObjectExpression' || (['f$e', 'p$e'].includes(node.left.name) && node.right.type === 'BinaryExpression'))) {
if (constants.has(node.left.name)) throw new Error(`Duplicate panel constant ${node.left.name}`)
constants.set(node.left.name, node.right)
}
for (const [key, value] of Object.entries(node)) {
if (key === 'loc' || key === 'extra') continue
if (Array.isArray(value)) value.forEach(walk)
else if (value && typeof value === 'object') walk(value)
}
}
walk(ast)
for (const name of Object.keys(definitions)) if (!functions.has(name)) throw new Error(`Missing source function ${name}`)
for (const name of constantNames) if (!constants.has(name)) throw new Error(`Missing source constant ${name}`)
const cssDirectory = resolve('.tmp/rea-css-recovered')
const manifest = JSON.parse(await readFile(resolve(cssDirectory, 'manifest.json'), 'utf8'))
if (manifest.sourceEvidenceId !== cssEvidenceId) throw new Error('Fixed CSS Evidence changed')
async function stylesheet(file, expected) {
const content = await readFile(resolve(cssDirectory, file), 'utf8')
if (manifest.files.find(item => item.file === file)?.sha256 !== expected || hash(content) !== expected) throw new Error(`Fixed ${file} SHA-256 mismatch`)
return postcss.parse(content, { from: file })
}
const motion = await stylesheet(motionFile, motionSha256)
const tokens = await stylesheet(tokenFile, tokenSha256)
const tokenNames = ['--wb-motion-duration-medium', '--wb-motion-duration-fast', '--wb-motion-easing-decelerate', '--wb-motion-easing-accelerate']
const tokenValues = new Map()
tokens.walkDecls(decl => { if (tokenNames.includes(decl.prop) && decl.parent.selectors?.includes(':root')) tokenValues.set(decl.prop, decl.value) })
for (const name of tokenNames) if (!tokenValues.has(name)) throw new Error(`Missing motion token ${name}`)
const outputCss = postcss.root()
outputCss.append(postcss.rule({ selector: '.source-detail-layout', nodes: tokenNames.map(name => postcss.decl({ prop: name, value: tokenValues.get(name) })) }))
let rules = 0
const selected = selector => /\.detail-panel-motion-[\w-]+|\.detail-panel-container(?:[\s.:#[]|$)/.test(selector)
function scope(selector) {
if (selector.startsWith('.detail-panel-motion-')) return `.source-detail-layout${selector}`
return `.source-detail-layout ${selector}`
}
function project(node) {
if (node.type === 'rule') {
const selectors = node.selectors.filter(selected)
if (!selectors.length) return null
rules++
return node.clone({ selector: selectors.map(scope).join(',') })
}
if (node.type === 'atrule' && node.nodes && !/keyframes$/.test(node.name)) {
const children = node.nodes.map(project).filter(Boolean)
return children.length ? node.clone({ nodes: children }) : null
}
return null
}
for (const node of motion.nodes) { const projected = project(node); if (projected) outputCss.append(projected) }
const bodies = Object.fromEntries([...functions].map(([name, fn]) => [name, { offset: fn.start, bodySha256: hash(source.slice(fn.body.start, fn.body.end)) }]))
const identities = {
version: '5.8.2', runtimeEvidenceId, runtimeFile, runtimeSha256, cssEvidenceId, motionFile, motionSha256, tokenFile, tokenSha256,
functions: bodies, constants: Object.fromEntries([...constants].map(([name, node]) => [name, hash(source.slice(node.start, node.end))]))
}
const interfaces = `export interface PanelAvailableWidthInput { containerWidth: number; sidebarWidth: number; leadingInset?: number }
export interface DetailDrawerWidthInput extends PanelAvailableWidthInput { isMobile?: boolean; preferredWidth?: number }
export interface DetailPanelLayoutInput extends PanelAvailableWidthInput { requestedDetailWidth: number }
export interface DetailPanelLayoutWidths { mainWidth: number; detailWidth: number }
export interface LeadingInsetRebalanceInput { previousInset: number; nextInset: number; isNarrowForDetail: boolean; isPanelVisible: boolean; rememberedDetailWidth: number | null; chatAreaWidth: number }
export interface NarrowLayoutState { isMobile: boolean; isNarrowForDetail: boolean; isNarrowForSidebar: boolean; screenWidth: number }
`
const constantText = constantNames.map(name => `export const ${name} = ${source.slice(constants.get(name).start, constants.get(name).end)}${constants.get(name).type === 'ObjectExpression' ? ' as const' : ''}`).join('\n')
const functionText = Object.entries(definitions).map(([name, spec]) => {
const fn = functions.get(name)
const overload = spec.implementationParameters ? `/** Preserve source JavaScript null-to-number comparisons behind the typed public overload. */\nexport function ${name}(${spec.parameters}): ${spec.result}\n` : ''
return `${overload}export function ${name}(${spec.implementationParameters ?? spec.parameters}): ${spec.result} ${source.slice(fn.body.start, fn.body.end)}`
}).join('\n\n')
const toMilliseconds = value => value.endsWith('ms') ? Number.parseFloat(value) : Number.parseFloat(value) * 1000
const motionConfig = { openMs: toMilliseconds(tokenValues.get('--wb-motion-duration-medium')), closeMs: toMilliseconds(tokenValues.get('--wb-motion-duration-fast')),
openEasing: tokenValues.get('--wb-motion-easing-decelerate'), closeEasing: tokenValues.get('--wb-motion-easing-accelerate') }
const typescript = `/* Generated by scripts/rea/recover-panel-layout.mjs from fixed REA Evidence.
* Source function bodies and constant object expressions are unchanged; only exports/types are added.
* The source runtime leading-inset store is replaced by the explicit zero-default adapter below.
* Callers with a registered leading inset must pass leadingInset. Inputs otherwise retain source behavior.
*/\n${interfaces}\nexport const SOURCE_PANEL_LAYOUT_EVIDENCE = ${JSON.stringify(identities, null, 2)} as const\n\n${constantText}\n\nexport const SIDEBAR_LAYOUT = Rw\nexport const CHAT_LAYOUT = zw\nexport const DETAIL_BREAKPOINT = Bw\nexport const DETAIL_PANEL_LAYOUT = Vw\nexport const DETAIL_NARROW_WIDTH = f$e\nexport const SIDEBAR_NARROW_WIDTH = p$e\nexport const DETAIL_PANEL_MOTION = ${JSON.stringify(motionConfig, null, 2)} as const\n\n/** Host adapter: the source getter returns the currently registered inset; local default is zero. */\nfunction getMainContentLeadingInset(): number { return 0 }\n\n${functionText}\n`
const css = `/* Generated by scripts/rea/recover-panel-layout.mjs; WorkBuddy 5.8.2.
* REA CSS ${cssEvidenceId}; ${motionFile} sha256=${motionSha256}.
* Motion tokens ${tokenFile} sha256=${tokenSha256}.
* ${rules} selected rules, original bodies/order and all enclosing media conditions preserved.
* .source-detail-layout carries motion phase classes on the same element.
*/\n${outputCss.toString()}\n`
postcss.parse(css)
const targetDirectory = resolve('src/renderer/src/workbuddy/workbench')
for (const [file, contents] of [['source-panel-layout.ts', typescript], ['panel-motion-source.css', css]]) {
const target = resolve(targetDirectory, file)
if (process.argv.includes('--check')) {
if (await readFile(target, 'utf8') !== contents) throw new Error(`${file} differs from the fixed source recovery`)
} else await writeFile(target, contents)
}
console.log(JSON.stringify({ runtimeEvidenceId, cssEvidenceId, functions: functions.size, constants: constants.size, rules, motion: motionConfig, check: process.argv.includes('--check') }))