// YCode-only live DOM/screenshot inspection. Original WorkBuddy must use REA instead. import fs from 'node:fs/promises' const targets = await (await fetch('http://127.0.0.1:9237/json/list')).json() const setting = process.argv.includes('--settings') const target = targets.find(item => item.type === 'page' && item.url.includes('window=settings') === setting) if (!target) throw new Error('Requested YCode window not found') const socket = new WebSocket(target.webSocketDebuggerUrl) await new Promise(resolve => { socket.onopen = resolve }) let sequence = 0 const pending = new Map() socket.onmessage = event => { const message = JSON.parse(event.data); const task = pending.get(message.id); if (task) { pending.delete(message.id); message.error ? task.reject(message.error) : task.resolve(message.result) } } const send = (method, params = {}) => new Promise((resolve, reject) => { const id = ++sequence; pending.set(id, { resolve, reject }); socket.send(JSON.stringify({ id, method, params })) }) const evaluate = async expression => { const response = await send('Runtime.evaluate', { expression, returnByValue: true, awaitPromise: true }); if (response.exceptionDetails) throw new Error(response.exceptionDetails.text); return response.result.value } const out = '.tmp/ycode-live-' + (setting ? 'settings' : 'main') try { await fs.mkdir(out, { recursive: true }) const viewportArgument = process.argv.find(value => value.startsWith('--viewport=')) if (viewportArgument) { const match = /^--viewport=(\d+)x(\d+)$/.exec(viewportArgument) if (!match || Number(match[1]) < 160 || Number(match[2]) < 160) throw new Error('Invalid viewport') await send('Emulation.setDeviceMetricsOverride', { width: Number(match[1]), height: Number(match[2]), deviceScaleFactor: 1, mobile: false }) } if (process.argv.includes('--home')) await evaluate(`Array.from(document.querySelectorAll('.sidebar__tab')).find(button=>button.textContent.includes('新建任务'))?.click()`) await evaluate('document.fonts.ready.then(()=>true)') await evaluate('new Promise(resolve=>setTimeout(resolve,1200))') const layout = await evaluate(`(()=>{const selectors=['.sidebar','.chat-pane','.source-home','.wb-home-page','.wb-home-page__main-content','.wb-home-header','.wb-scene-tabs','.wb-home-composer','.wb-home-composer__chips','.wb-home-composer__input-slot','.wb-home-composer__below-input','.wb-composer','.cr-input-container','.wb-composer__workspace-footer','.cr-input-toolbar','.cr-permission-setting','.settings-modal','.settings-modal__nav','.settings-modal__content','.models-settings-panel','.models-settings-panel__editor','.sidebar-next'];return{viewport:{width:innerWidth,height:innerHeight},nodes:selectors.flatMap(selector=>Array.from(document.querySelectorAll(selector)).map(node=>{const box=node.getBoundingClientRect(),style=getComputedStyle(node);return{selector,bounds:[box.x,box.y,box.width,box.height],font:style.fontFamily,fontSize:style.fontSize,lineHeight:style.lineHeight,padding:style.padding,margin:style.margin,gap:style.gap,background:style.backgroundColor,display:style.display}}))}})()`) await fs.writeFile(out + '/layout.json', JSON.stringify(layout, null, 2)) const screenshot = await send('Page.captureScreenshot', { format: 'png', fromSurface: true }) await fs.writeFile(out + '/screen.png', Buffer.from(screenshot.data, 'base64')) console.log(JSON.stringify({ targetId: target.id, output: out, viewport: layout.viewport })) } finally { socket.close() }