feat: ship skill and MCP workflows with signed updater for v0.0.7

This commit is contained in:
xiaohan.yuan committed 2026-10-21 00:04:17 +08:00
1 parent 1b52df0603
commit a01085c656
136 files changed
+18646 -217

No files matched your search

+3 -3
View File
@@ -39,7 +39,7 @@ if (!electron) {
fs.writeFileSync(path.join(output,'preload.cjs'), `const{contextBridge,ipcRenderer}=require('electron');contextBridge.exposeInMainWorld('ycode',{skills:Object.fromEntries(['list','read','setEnabled','remove','export','importPath'].map(method=>[method,(...args)=>ipcRenderer.invoke('skills-qa',method,args)]))});`)
const location = file=>JSON.stringify(path.join(repository,file).replaceAll('\\','/'))
fs.writeFileSync(path.join(output,'fixture.tsx'), `import React from 'react';import{createRoot}from'react-dom/client';import Center from ${location('src/renderer/src/capabilities/CapabilityCenter')};import ${location('src/renderer/src/styles/tokens.css')};import ${location('src/renderer/src/styles/app.css')};window.__skillsQa={uses:[],created:0,find:0};createRoot(document.getElementById('root')).render(<div className="chat-pane cr-theme" style={{height:'100vh'}}><Center cwd={${JSON.stringify(workspace)}} onBackToChat={()=>{}} onUseSkill={skill=>window.__skillsQa.uses.push(skill)} onCreateSkill={()=>window.__skillsQa.created++} onFindSkill={()=>window.__skillsQa.find++}/></div>);`)
await require('esbuild').build({entryPoints:[path.join(output,'fixture.tsx')],bundle:true,platform:'browser',format:'esm',jsx:'automatic',outfile:path.join(output,'fixture.js'),loader:{'.svg':'file','.png':'file','.woff':'file','.woff2':'file','.ttf':'file'},logLevel:'warning'})
await require('esbuild').build({entryPoints:[path.join(output,'fixture.tsx')],bundle:true,platform:'browser',format:'esm',jsx:'automatic',outfile:path.join(output,'fixture.js'),loader:{'.svg':'file','.png':'file','.jpg':'file','.woff':'file','.woff2':'file','.ttf':'file'},logLevel:'warning'})
fs.writeFileSync(path.join(output,'index.html'),'<html data-theme="light"><head><meta charset="utf-8"><link rel="stylesheet" href="fixture.css"><style>html,body,#root{width:100%;height:100%;margin:0}</style></head><body><div id="root"></div><script type="module" src="fixture.js"></script></body></html>')
const win=new BrowserWindow({width:1052,height:901,useContentSize:true,frame:false,show:false,webPreferences:{preload:path.join(output,'preload.cjs'),contextIsolation:true,nodeIntegration:false,backgroundThrottling:false}})
win.webContents.on('console-message',(_event,level,message)=>{if(level===3)errors.push(message)})
@@ -67,9 +67,9 @@ if (!electron) {
check('success notice does not affect normal flow',await read('getComputedStyle(document.querySelector(".yc-skill-notice")).position'),'absolute');await wait('!document.querySelector(".yc-skill-notice")');check('success notice disappears automatically',await read('!!document.querySelector(".yc-skill-notice")'),false)
await clickText('.sm-installed-batch-manage','批量管理');await click('.sm-card');await clickText('.sm-batch-toolbar button','禁用');check('batch disable persists real state',(await api.listSkills(workspace))[0].enabled,false);await clickText('.sm-batch-toolbar button','启用');check('batch enable persists real state',(await api.listSkills(workspace))[0].enabled,true);await clickText('.sm-installed-batch-manage','完成')
await click('.wb-switch__input');check('native toggle persists actual disabled state',(await api.listSkills(workspace))[0].enabled,false)
await click('.wb-switch__input');await click('.sm-card-name');await wait('document.querySelector(".sm-skill-detail-overview-body")?.textContent.includes("NATIVE_SKILL_PROOF")');check('detail renders real SKILL.md markdown',await read('document.querySelector(".sm-skill-detail-overview-body").textContent.includes("Actual skill instructions")'),true);await capture('detail')
await click('.wb-switch__input');await click('.sm-card-name');await wait('document.querySelector(".yc-skill-description-body")?.textContent.includes("NATIVE_SKILL_PROOF")');check('detail renders real SKILL.md markdown',await read('document.querySelector(".yc-skill-description-body").textContent.includes("Actual skill instructions")'),true);await capture('detail')
await click('[aria-label="使用技能"]');check('use callback receives actual enabled identity',await read('window.__skillsQa.uses[0].id'),(await api.listSkills(workspace))[0].id)
await clickText('.sm-skill-detail-action-row button','导出');check('export writes real ZIP',fs.existsSync(path.join(output,'export.zip')),true)
await click('.sm-card-name');await wait('!!document.querySelector(".sm-skill-detail-card")');await clickText('.sm-skill-detail-action-row button','导出');check('export writes real ZIP',fs.existsSync(path.join(output,'export.zip')),true)
await click('[aria-label="卸载技能"]');await key('Escape');await settle();check('nested Escape closes only top uninstall dialog',await read('!!document.querySelector(".sm-skill-detail-card")&&!document.querySelector("[aria-label=确认卸载]")'),true)
await click('[aria-label="关闭技能详情"]');await click('[aria-label="搜索技能"]');await cdp('Input.insertText',{text:'NO_MATCH'});await settle();check('real search filters installed list',await read('document.querySelectorAll(".sm-card").length'),0);await click('[aria-label="清空技能搜索"]');await wait('document.querySelectorAll(".sm-card").length===1')
await click('.sm-card-pin');check('pin updates shared slash menu memory',await read(`JSON.parse(localStorage.getItem(${JSON.stringify('ycode.skills.menu.v1:'+workspace.replaceAll('\\','/').toLowerCase())})).pinned.length`),1)