Tighten plugin authoring completion regressions

This commit is contained in:
Amy 2026-05-29 18:43:08 +08:00
parent f7beb42950
commit 91691f3e66
2 changed files with 74 additions and 0 deletions

View file

@ -394,6 +394,76 @@ child.on('exit', (code, signal) => {
}
});
it('allows plugin authoring to succeed when the requested generated-plugin artifacts exist before close', async () => {
const projectId = `proj-plugin-authoring-success-${randomUUID()}`;
const createProjectResponse = await fetch(`${baseUrl}/api/projects`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
id: projectId,
name: 'Plugin authoring artifact success fixture',
skillId: null,
designSystemId: null,
}),
});
expect(createProjectResponse.status).toBe(200);
const conversationsResponse = await fetch(`${baseUrl}/api/projects/${projectId}/conversations`);
expect(conversationsResponse.status).toBe(200);
const conversationsBody = await conversationsResponse.json() as {
conversations: Array<{ id: string }>;
};
const conversationId = conversationsBody.conversations[0]?.id;
expect(conversationId).toBeTruthy();
await withFakeAgent(
'opencode',
`
const fs = require('node:fs');
const path = require('node:path');
process.stdin.resume();
process.stdin.on('end', () => {
const pluginDir = path.join(process.cwd(), 'generated-plugin');
fs.mkdirSync(pluginDir, { recursive: true });
fs.writeFileSync(path.join(pluginDir, 'open-design.json'), JSON.stringify({ name: 'generated-plugin' }, null, 2));
fs.writeFileSync(path.join(pluginDir, 'SKILL.md'), '# Generated plugin\\n');
console.log(JSON.stringify({ type: 'step_start' }));
console.log(JSON.stringify({ type: 'text', part: { text: '我来帮你创建一个通用的 Open Design 插件脚手架。先读取文档规范,再生成插件文件。' } }));
console.log(JSON.stringify({ type: 'step_finish', part: { tokens: { input: 1, output: 1 } } }));
process.exit(0);
});
`,
async () => {
const createResponse = await fetch(`${baseUrl}/api/runs`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
agentId: 'opencode',
projectId,
conversationId,
pluginId: 'od-plugin-authoring',
message: '请创建一个可刷新、可审计、由 API 驱动的 Open Design 插件脚手架。',
}),
});
expect(createResponse.status).toBe(202);
const { runId } = await createResponse.json() as { runId: string };
const eventsResponse = await fetch(`${baseUrl}/api/runs/${runId}/events`);
const eventsBody = await readSseUntil(eventsResponse, 'event: final');
const statusBody = await waitForRunStatus(baseUrl, runId);
expect(eventsBody).toContain('先读取文档规范,再生成插件文件');
expect(statusBody.status).toBe('succeeded');
const filesResponse = await fetch(`${baseUrl}/api/projects/${projectId}/files`);
expect(filesResponse.status).toBe(200);
const filesBody = await filesResponse.json() as { files: Array<{ name: string }> };
expect(filesBody.files.some((file) => file.name === 'generated-plugin/open-design.json')).toBe(true);
expect(filesBody.files.some((file) => file.name === 'generated-plugin/SKILL.md')).toBe(true);
},
);
});
it('does not report plugin authoring as succeeded when the agent only emits planning text without artifacts', async () => {
const projectId = `proj-plugin-authoring-${randomUUID()}`;

View file

@ -392,6 +392,10 @@ pnpm exec playwright test -c playwright.config.ts ui/design-systems-manager.test
- `generated-plugin/SKILL.md`
- daemon 会把本轮转成 `failed`,而不是错误地保留 `succeeded`
2. `allows plugin authoring to succeed when the requested generated-plugin artifacts exist before close`
- 覆盖同一条 guard 的对称路径:只要关键插件产物已经落地,就不会被误伤成失败
- 锁住 daemon 的判断是“缺少目标产物才失败”,而不是“只要文本看起来像计划句就失败”
### 6. Grok Build prompt inline argv 契约