feat: align controlled AI sessions and MVP controls
This commit is contained in:
@@ -24,6 +24,7 @@ const requiredFiles = [
|
||||
'src/api/mappers.tsx',
|
||||
'src/api/search.ts',
|
||||
'src/api/inbox.ts',
|
||||
'src/api/ai.ts',
|
||||
'scripts/api-client.test.mjs',
|
||||
]
|
||||
|
||||
@@ -59,7 +60,7 @@ if (existsSync('src/app/App.tsx')) {
|
||||
}
|
||||
|
||||
const apiFiles = existsSync('src/api')
|
||||
? ['client.ts', 'projects.ts', 'mappers.tsx', 'search.ts', 'inbox.ts']
|
||||
? ['client.ts', 'projects.ts', 'mappers.tsx', 'search.ts', 'inbox.ts', 'ai.ts']
|
||||
.map((name) => `src/api/${name}`)
|
||||
.filter((file) => existsSync(file))
|
||||
: []
|
||||
@@ -112,6 +113,48 @@ if (!inboxSource.includes('body: { suggestionIds }')) failures.push('inbox confi
|
||||
const inboxPageSource = existsSync('src/pages/projects/project-inbox.tsx') ? readFileSync('src/pages/projects/project-inbox.tsx', 'utf8') : ''
|
||||
if (inboxPageSource && !inboxPageSource.includes('确认创建')) failures.push('project inbox must expose the single confirmation action')
|
||||
|
||||
const aiApiSource = existsSync('src/api/ai.ts') ? readFileSync('src/api/ai.ts', 'utf8') : ''
|
||||
for (const required of ['/api/v1/projects/', '/ai-sessions', 'listAISessions', 'createAISession']) {
|
||||
if (!aiApiSource.includes(required)) failures.push(`AI API must include ${required}`)
|
||||
}
|
||||
if (/\b(?:task|note|source)Id\b/.test(aiApiSource)) failures.push('AI session responses must not expose automatic formal object IDs')
|
||||
|
||||
const aiPageSource = existsSync('src/pages/projects/project-ai.tsx') ? readFileSync('src/pages/projects/project-ai.tsx', 'utf8') : ''
|
||||
for (const required of ['AI 助手', '创建会话', 'loading', 'error']) {
|
||||
if (!aiPageSource.includes(required)) failures.push(`project AI page must include ${required}`)
|
||||
}
|
||||
for (const forbidden of ['DeepSeek V4.0 Flash', '给 DeepSeek 发送消息', 'IconAttachment', 'agent-send-button']) {
|
||||
if (aiPageSource.includes(forbidden)) failures.push(`project AI page contains unsupported chat control ${forbidden}`)
|
||||
}
|
||||
|
||||
const unsupportedControls = [
|
||||
{
|
||||
file: 'src/pages/workspace-explore.tsx',
|
||||
required: '暂未开放',
|
||||
forbidden: ['同步数据源', '添加数据源', 'IconRefresh', 'IconEdit', 'IconDelete'],
|
||||
},
|
||||
{
|
||||
file: 'src/pages/projects/project-new-channel.tsx',
|
||||
required: '暂未开放',
|
||||
forbidden: ['保存频道', '<Input', '<Select', '<TextArea'],
|
||||
},
|
||||
{
|
||||
file: 'src/pages/projects/project-statusbar.tsx',
|
||||
forbidden: ['升级', '支付', 'billing-plan', '152GB', 'AI 空闲'],
|
||||
},
|
||||
{
|
||||
file: 'src/pages/projects/project-topbar.tsx',
|
||||
forbidden: ['停靠左边', '停靠右边', 'DockIcon', 'isDesktopRuntime'],
|
||||
},
|
||||
]
|
||||
for (const check of unsupportedControls) {
|
||||
const source = existsSync(check.file) ? readFileSync(check.file, 'utf8') : ''
|
||||
if (check.required && !source.includes(check.required)) failures.push(`${check.file} must show ${check.required}`)
|
||||
for (const forbidden of check.forbidden) {
|
||||
if (source.includes(forbidden)) failures.push(`${check.file} contains unsupported control ${forbidden}`)
|
||||
}
|
||||
}
|
||||
|
||||
const html = readFileSync('index.html', 'utf8')
|
||||
if (!html.includes('<html lang="zh-CN">')) failures.push('index language must be zh-CN')
|
||||
if (!html.includes('<title>森林AI</title>')) failures.push('document title must be 森林AI')
|
||||
|
||||
Reference in New Issue
Block a user