const fs = require('node:fs/promises') const path = require('node:path') const { pathToFileURL } = require('node:url') if (!process.versions.electron) { ;(async () => { const dir = await fs.mkdtemp(path.resolve('.tmp/alignment-window-')) const data = path.join(dir, 'data'), home = path.join(dir, 'home'), cwd = path.join(dir, 'workspace') for (const folder of [data, home, cwd]) await fs.mkdir(folder) const now = Date.now() const model = { id:'audit-model', name:'Audit Model', providerId:'custom', model:'fixture', baseUrl:'http://127.0.0.1:1', authMode:'none', protocol:'anthropic', supportsToolCall:true } await fs.writeFile(path.join(data,'models.json'), JSON.stringify({version:1, models:[model], selectedModelId:model.id})) await fs.writeFile(path.join(data,'workspaces.json'),JSON.stringify({selectedWorkspaceId:'audit-space',workspaces:[{id:'audit-space',name:'Audit Workspace',root:cwd,createdAt:now}]})) const question = { id:'q1', question:'Which target should be inspected?', answers:['Local fixture'] } const messages = [ {id:'u1',role:'user',content:'Inspect the local fixture.',createdAt:now-10000,status:'done'}, {id:'a1',role:'assistant',content:'The local fixture is ready.',createdAt:now-9000,status:'done',turnStartedAt:now-10000,turnFinishedAt:now,turnDurationMs:10000, tools:[{id:'q-tool',name:'AskUserQuestion',args:{questions:[question]},argsRaw:'{}',status:'ok',output:'ANSWER_RAW_SENTINEL',metadata:{questionAnswer:{questions:[question]}}}], parts:[{type:'reasoning',id:'r1',text:'I need the target.',finished:true},{type:'tool',toolId:'q-tool'},{type:'reasoning',id:'r2',text:'The target is selected.',finished:true},{type:'text',text:'The local fixture is ready.'}]} ] const session = (id,agentMode,ms) => ({id,title:`Audit ${agentMode}`,cwd,workspaceId:'audit-space',modelId:model.id,agentMode,permissionMode:'full-access',createdAt:ms,updatedAt:ms,messages}) await fs.writeFile(path.join(data,'sessions.json'),JSON.stringify({sessions:[session('audit-plan','plan',now+1),session('audit-ask','ask',now)]})) const env={...process.env,YCODE_USER_DATA_DIR:data,YCODE_QA_DIRECTORY:dir,YCODE_QA_OFFSCREEN:'1',YCODE_DISABLE_GPU:'1',YCODE_DISABLE_SYSTEM_INTEGRATION:'1',AUDIT_WINDOW_DIR:dir} delete env.ELECTRON_RUN_AS_NODE; delete env.ELECTRON_RENDERER_URL const child=require('node:child_process').spawn(require('electron'),['--no-sandbox','--disable-gpu-sandbox',__filename],{env,windowsHide:true,stdio:['ignore','pipe','pipe']}) let log='';child.stdout.on('data',x=>{log+=x});child.stderr.on('data',x=>{log+=x}) const timeout=setTimeout(()=>child.kill(),90000) child.on('exit',async code=>{clearTimeout(timeout);await fs.writeFile(path.join(dir,'process.log'),log);console.log(JSON.stringify({directory:dir,exitCode:code}));if(code)console.error(log.slice(-7000));process.exitCode=code??1}) })().catch(e=>{console.error(e);process.exitCode=1}) } else { const {app,BrowserWindow,ipcMain}=require('electron') const dir=process.env.AUDIT_WINDOW_DIR app.disableHardwareAcceleration();app.setPath('home',path.join(dir,'home')) const originalHandle=ipcMain.handle.bind(ipcMain) ipcMain.handle=(channel,listener)=>originalHandle(channel,async(...args)=>{if(channel==='session:messages')await new Promise(r=>setTimeout(r,1200));return listener(...args)}) let win const pause=ms=>new Promise(r=>setTimeout(r,ms)) const read=code=>win.webContents.executeJavaScript(code) async function wait(code){for(let i=0;i<250;i++){const x=await read(code);if(x)return x;await pause(40)}throw new Error('Timeout '+code)} async function shot(name){await read('document.fonts.ready');await pause(80);await fs.writeFile(path.join(dir,name+'.png'),(await win.webContents.capturePage()).toPNG())} const styleProbe=`(selector)=>{const e=document.querySelector(selector);if(!e)return null;const c=getComputedStyle(e),r=e.getBoundingClientRect();return {selector,text:e.textContent,width:r.width,height:r.height,fontSize:c.fontSize,fontWeight:c.fontWeight,lineHeight:c.lineHeight,padding:c.padding,borderRadius:c.borderRadius,background:c.backgroundColor,color:c.color,display:c.display,opacity:c.opacity}}` const styles=selectors=>read(`(()=>{const p=${styleProbe};return ${JSON.stringify(selectors)}.map(p)})()`) ;(async()=>{ await import(pathToFileURL(path.resolve('out/main/index.mjs')).href);await app.whenReady();win=BrowserWindow.getAllWindows()[0];win.setSize(1336,902);win.showInactive() const errors=[];win.webContents.on('console-message',(_e,level,message)=>{if(level>=3)errors.push(message)}) await wait('!!document.querySelector(".yc-session-skeleton")') const skeleton=await styles(['.yc-session-skeleton','.yc-session-skeleton__avatar','.yc-session-skeleton__name','.yc-session-skeleton__user','.yc-session-skeleton__line','.yc-session-skeleton__line--short']) await shot('loading') await wait('!!document.querySelector(".yc-mode-chip") && !!document.querySelector(".msg--assistant")') await pause(350) const mode=await styles(['.yc-mode-chip','.yc-mode-chip > svg','.yc-mode-chip__clear']) await shot('plan') await read('document.querySelector(".yc-mode-chip").focus()') const focusedMode=await styles(['.yc-mode-chip','.yc-mode-chip > svg','.yc-mode-chip__clear']) await shot('plan-focus') await read('document.querySelector(".cr-collapse--completed > header").click()') await wait('!!document.querySelector(".ask-user-question--completed")') await read('document.querySelector(".ask-user-question__header .cr-tool-head__main").click()') await wait('!!document.querySelector(".question-answer-transcript__question")') const question=await styles(['.ask-user-question--completed','.ask-user-question__header','.ask-user-question__content','.question-answer-transcript__question','.question-answer-transcript__answer']) await shot('answered-expanded') await read('document.querySelector("[data-session-id=\\"audit-ask\\"]").click()') await wait('!!document.querySelector(".yc-session-skeleton")') const switching=await read('({hasHome:!!document.querySelector(".wb-home-route"),hasSkeleton:!!document.querySelector(".yc-session-skeleton"),hasComposer:!!document.querySelector(".wb-composer"),hasHeader:!!document.querySelector(".source-chat-header"),text:document.querySelector(".yc-mode-chip")?.textContent})') await shot('switch-loading') await wait('!!document.querySelector(".msg--assistant") && !document.querySelector(".yc-session-skeleton")') const ask=await styles(['.yc-mode-chip','[data-permission-trigger]','.yc-source-permission button']) await shot('ask') await read('document.querySelector("[data-session-id=\\"audit-ask\\"] .agent-card-more-button").click()') await wait('!!document.querySelector(".cb-context-menu-item")') await read('[...document.querySelectorAll(".cb-context-menu-item")].find(e=>e.textContent.includes("归档")).click()') await wait('!!document.querySelector(".task-popconfirm") && Number(getComputedStyle(document.querySelector(".task-popconfirm")).opacity)>=0.99') await pause(500) const popconfirm=await styles(['.task-popconfirm','.task-popconfirm__title','.task-popconfirm__description','.task-popconfirm__confirm','.task-popconfirm__cancel']) const popconfirmAncestors=await read('(()=>{let e=document.querySelector(".task-popconfirm"),a=[];while(e){const c=getComputedStyle(e);a.push({className:e.className,opacity:c.opacity,visibility:c.visibility});e=e.parentElement}return a})()') await shot('archive-settled') await read('document.querySelector(".task-popconfirm__cancel").click()') await read('document.querySelector(".yc-mode-chip__clear").click()') await wait('!document.querySelector(".yc-mode-chip")') const fixtureTime=Date.now(), runId='audit-approval-run' const userMessage={id:'audit-approval-user',requestId:runId,role:'user',content:'Render a local approval fixture.',createdAt:fixtureTime,status:'done'} const approval={id:'audit-approval',requestId:'audit-approval',runId,toolCallId:'audit-command',kind:'approval',title:'执行命令命中询问规则,需要确认。',status:'pending',options:[{optionId:'once',name:'允许',kind:'allow_once'},{optionId:'session',name:'本次会话内始终允许',kind:'allow_always'},{optionId:'deny',name:'拒绝',kind:'reject_once'}],details:{requestKind:'rule-intercept',toolName:'Bash',command:'echo audit',reason:'fixture rule',rule:{id:'fixture-command-rule',description:'Local fixture only'},allowScope:'session'}} const assistant={id:'audit-approval-assistant',requestId:runId,role:'assistant',content:'',createdAt:fixtureTime,status:'streaming',turnStartedAt:fixtureTime,parts:[],tools:[],interactions:[approval],runtimeProgress:{source:'agent',phase:'waiting-approval',toolName:'Bash'}} win.webContents.send('chat:run-started',{sessionId:'audit-ask',runId,assistantMessageId:assistant.id,userMessage,modelId:'audit-model',modelName:'Audit Model',sequence:0,messages:[userMessage,assistant]}) await wait('!!document.querySelector(".conversation-intercept-card")') await pause(150) const permission=await styles(['.conversation-intercept-card','.conversation-intercept-card__title','.conversation-intercept-card__rule-action','.conversation-intercept-card__description','.conversation-intercept-card__option','.conversation-intercept-card__option-num']) await shot('approval') await read('document.querySelector(".conversation-intercept-card__rule-action").click()') const permissionRule=await styles(['.conversation-intercept-card__rule']) await shot('approval-rule') await fs.writeFile(path.join(dir,'report.json'),JSON.stringify({head:'51531dcae8d8ade85db9e203bc8c0f712805b2ae',scope:'Real isolated YCode main/preload/renderer; delayed local IPC and injected approval snapshot; fixture model only; no model calls or original app access.',skeleton,mode,focusedMode,question,switching,ask,popconfirm,popconfirmAncestors,permission,permissionRule,errors},null,2)) console.log('WINDOW_AUDIT_DONE');app.exit(0) })().catch(async e=>{console.error(e);if(win)await shot('failure').catch(()=>{});await fs.writeFile(path.join(dir,'failure.txt'),String(e));app.exit(1)}) }