import { mkdtemp, readFile, rm } from 'node:fs/promises'; import { join } from 'node:path'; import { tmpdir } from 'node:os'; import { describe, expect, it } from 'vitest'; import { createRuntimeSubagent, updateRuntimeSubagent } from '@electron/opencode/agent-writer'; describe('agent writer', () => { it('creates a built-in game-dev runtime subagent from the bundled markdown template', async () => { const projectPath = await mkdtemp(join(tmpdir(), 'niancode-agent-writer-')); try { const subagent = await createRuntimeSubagent({ projectPath, displayName: '小游戏开发伙伴', templateRoleId: 'game-dev', }); const markdown = await readFile(subagent.filePath, 'utf8'); expect(subagent.id).toMatch(/^nitu-game-dev-/); expect(subagent.templateRoleId).toBe('game-dev'); expect(subagent.skillIds).toEqual([ 'youth-plain-language', 'dev-build-test', 'ui-ux-course-quality', ]); expect(markdown).toContain('GDD.md'); expect(markdown).toContain('聊天总结不能代替项目文件'); expect(markdown).not.toContain('selectionStatus'); expect(markdown).toContain('Phaser'); expect(markdown).not.toContain('把起步模板小游戏直接当成目标作品'); } finally { await rm(projectPath, { recursive: true, force: true }); } }); it('creates a built-in game-showcase runtime subagent from the bundled markdown template', async () => { const projectPath = await mkdtemp(join(tmpdir(), 'niancode-agent-writer-')); try { const subagent = await createRuntimeSubagent({ projectPath, displayName: '宣传展示伙伴', templateRoleId: 'game-showcase', }); const markdown = await readFile(subagent.filePath, 'utf8'); expect(subagent.id).toMatch(/^nitu-game-showcase-/); expect(subagent.templateRoleId).toBe('game-showcase'); expect(subagent.skillIds).toEqual([ 'youth-plain-language', 'marketing-launch-story', 'ui-ux-course-quality', ]); expect(markdown).toContain('SHOWCASE_PACKAGE.md'); expect(markdown).toContain('宣传展示'); } finally { await rm(projectPath, { recursive: true, force: true }); } }); it('keeps template-required skills when creating and updating a runtime subagent', async () => { const projectPath = await mkdtemp(join(tmpdir(), 'niancode-agent-writer-required-')); try { const created = await createRuntimeSubagent({ projectPath, displayName: '结对开发伙伴', templateRoleId: 'game-dev', requiredSkillIds: ['nianxxgame-skill'], }); expect(created.skillIds).toEqual([ 'youth-plain-language', 'dev-build-test', 'ui-ux-course-quality', 'nianxxgame-skill', ]); const updated = await updateRuntimeSubagent({ projectPath, agentId: created.id, displayName: created.displayName, templateRoleId: 'game-dev', skillIds: ['dev-build-test'], requiredSkillIds: ['nianxxgame-skill'], }); const markdown = await readFile(updated.filePath, 'utf8'); expect(updated.skillIds).toEqual(['dev-build-test', 'nianxxgame-skill', 'youth-plain-language']); expect(markdown).toContain('nianxxgame-skill: allow'); expect(markdown).toContain('youth-plain-language: allow'); expect(markdown).not.toContain('youth-ai-product-course: allow'); } finally { await rm(projectPath, { recursive: true, force: true }); } }); });