/** Focused production-module regression using only explicitly test-owned expert packages. */ import fs from 'node:fs/promises' import path from 'node:path' import assert from 'node:assert/strict' import {createHash} from 'node:crypto' import {pathToFileURL} from 'node:url' import {build} from 'esbuild' const output=await fs.mkdtemp(path.resolve('.tmp/imported-expert-qa-preloading-')),userData=path.join(output,'YCode') await fs.mkdir(userData) await fs.writeFile(path.join(userData,'mcp-servers.json'),JSON.stringify({version:1,servers:[]})) const source='src/main/capabilities/experts.ts',sha=value=>createHash('sha256').update(value).digest('hex'),sourceSha256=sha(await fs.readFile(source)) await build({stdin:{contents:`export * from './src/main/capabilities/experts';`,resolveDir:process.cwd(),loader:'ts'},outfile:path.join(output,'experts.mjs'),bundle:true,platform:'node',format:'esm',packages:'external',logLevel:'warning',plugins:[{name:'own-profile',setup(builder){builder.onResolve({filter:/^electron$/},()=>({path:'electron',namespace:'qa'}));builder.onLoad({filter:/.*/,namespace:'qa'},()=>({contents:`export const app={getPath:()=>${JSON.stringify(userData)}};export const safeStorage={isEncryptionAvailable:()=>false};`}))}}]}) const api=await import(pathToFileURL(path.join(output,'experts.mjs')).href),checks=[] function check(label,actual,expected=true){assert.deepEqual(actual,expected,label);checks.push({label,pass:true})} async function rejected(label,run,pattern){await assert.rejects(run,pattern,label);checks.push({label,pass:true})} const skill=(name,body)=>`---\nname: ${name}\ndescription: Controlled test skill ${name}\n---\n${body}\n` async function install(id,preload,options={}){ const plugin={name:id,version:'1.0.0',description:'Explicit test-owned local role fixture',expertType:'agent',agentName:id,agents:[`./agents/${id}.md`],skills:['./skills/directory-alias','./skills/second-directory'],displayName:{zh:'测试角色',en:'Test Role'},profession:{zh:'测试角色',en:'Test Role'},displayDescription:{zh:'测试角色',en:'Test Role'},defaultInitPrompt:{zh:'测试输入',en:'Test input'},tags:[1,2,3].map(n=>({zh:'标签'+n,en:'Tag '+n})),quickPrompts:[{zh:'测试输入',en:'Test input'},...[2,3].map(n=>({zh:'测试'+n,en:'Test '+n}))]} const first=skill(options.unsafeName??'real-skill','FIRST_BODY_SENTINEL'),second=skill(options.duplicateName?'real-skill':'other-skill','SECOND_BODY_SENTINEL') const agent=`---\nname: ${id}\ndescription: Explicit test-owned role\n${preload===undefined?'':'skills: '+JSON.stringify(preload)+'\n'}---\nTEST_ROLE_SENTINEL\n` const files={'.codebuddy-plugin/plugin.json':JSON.stringify(plugin),[`agents/${id}.md`]:agent,'skills/directory-alias/SKILL.md':first,'skills/second-directory/SKILL.md':second,'skills/unregistered/SKILL.md':skill('not-registered','UNREGISTERED_BODY_SENTINEL')} await api.expertPackageOperation('test-'+id,{id,action:'write',files});const result=await api.expertPackageOperation('test-'+id,{id,action:'register'});assert.equal(result.success,true) return{files,first,second} } try{ const absent=await install('absent-skills',undefined),absentTurn=await api.expertTurnContext('absent-skills') check('missing Agent skills injects no registered skill full body',absentTurn.context.includes(absent.first)||absentTurn.context.includes(absent.second),false) check('missing Agent skills still exposes both registered skill names',absentTurn.context.includes('"name":"real-skill"')&&absentTurn.context.includes('"name":"other-skill"')) check('all original resources remain available including nonregistered text',Object.keys(absentTurn.resources).sort(),Object.keys(absent.files).sort().concat('.created-by-session').sort()) const named=await install('named-skills',['real-skill']),namedTurn=await api.expertTurnContext('named-skills') check('selection resolves SKILL frontmatter name rather than directory alias',namedTurn.context.includes(named.first)) check('unselected registered skill is not silently preloaded',namedTurn.context.includes(named.second),false) check('directory explicitly marks selected and unselected state',namedTurn.context.includes('"path":"skills/directory-alias/SKILL.md","description":"Controlled test skill real-skill","preloaded":true')&&namedTurn.context.includes('"path":"skills/second-directory/SKILL.md","description":"Controlled test skill other-skill","preloaded":false')) const duplicate=await install('duplicate-selection',['real-skill','real-skill']),duplicateTurn=await api.expertTurnContext('duplicate-selection') check('duplicate YAML skill names preload one full body',duplicateTurn.context.split(duplicate.first).length-1,1) await install('unknown-selection',['not-registered']);await rejected('existing but unregistered skill cannot be preloaded',()=>api.expertTurnContext('unknown-selection'),/未在 plugin.skills 注册/) await install('inherited-selection',['constructor']);await rejected('inherited property cannot resolve as a registered skill',()=>api.expertTurnContext('inherited-selection'),/未在 plugin.skills 注册/) await install('traversal-selection',['../real-skill']);await rejected('Agent skill path is not accepted as a legal name',()=>api.expertTurnContext('traversal-selection'),/合法技能名称/) await install('scalar-selection','real-skill');await rejected('scalar Agent skills is rejected rather than all-loaded',()=>api.expertTurnContext('scalar-selection'),/合法技能名称/) await install('ambiguous-selection',['real-skill'],{duplicateName:true});await rejected('ambiguous registered skill name cannot choose arbitrary directory',()=>api.expertTurnContext('ambiguous-selection'),/名称不唯一/) await install('empty-selection',[]);check('explicit empty Agent skills has no preloads',(await api.expertTurnContext('empty-selection')).context.includes('api.expertTurnContext('invalid-skill-name'),/技能名称无效/) check('production source stays unchanged during focused test',sha(await fs.readFile(source)),sourceSha256) await fs.writeFile(path.join(output,'report.json'),JSON.stringify({result:'PASS',checks,source,sourceSha256,limitations:'Only host preload semantics; no model request or expert business script executed.'},null,2)) console.log(JSON.stringify({result:'PASS',checks:checks.length,output})) }catch(error){await fs.writeFile(path.join(output,'report.json'),JSON.stringify({result:'FAIL',checks,error:error.stack,source,sourceSha256},null,2));console.error(JSON.stringify({result:'FAIL',error:error.message,output}));process.exitCode=1}