feat: remove legacy OpenCode runtime
Cut product flows over to Coding/Pi and retain only the migration-owned v1 boundary. Promote supported native optional packages because electron-builder omitted pnpm transitive optional closure from the packaged ASAR.
This commit is contained in:
@@ -60,6 +60,7 @@ async function installCodingFirstChatHost(
|
||||
const { ipcMain } = process.mainModule!.require('electron') as typeof import('electron');
|
||||
type MainState = {
|
||||
captured: CapturedRequest[];
|
||||
conversationCreated: boolean;
|
||||
releaseSnapshot: (() => void) | null;
|
||||
snapshotPending: boolean;
|
||||
};
|
||||
@@ -68,6 +69,7 @@ async function installCodingFirstChatHost(
|
||||
};
|
||||
const state: MainState = {
|
||||
captured: [],
|
||||
conversationCreated: false,
|
||||
releaseSnapshot: null,
|
||||
snapshotPending: false,
|
||||
};
|
||||
@@ -80,7 +82,11 @@ async function installCodingFirstChatHost(
|
||||
updatedAt: now,
|
||||
lastOpenedAt: now,
|
||||
};
|
||||
const legacyProject = { ...project, path: 'D:/e2e/pi-first-chat' };
|
||||
const configuredModel = {
|
||||
accountId: 'account-e2e',
|
||||
modelId: 'model-a',
|
||||
thinkingLevel: 'off',
|
||||
};
|
||||
const agent = {
|
||||
id: 'builder',
|
||||
avatarId: 'avatar-01',
|
||||
@@ -88,8 +94,8 @@ async function installCodingFirstChatHost(
|
||||
name: 'Builder',
|
||||
builtIn: false,
|
||||
enabled: true,
|
||||
model: null,
|
||||
modelResolution: 'required',
|
||||
model: configuredModel,
|
||||
modelResolution: 'resolved',
|
||||
skillIds: [],
|
||||
responsibility: {
|
||||
mission: 'Implement',
|
||||
@@ -114,22 +120,12 @@ async function installCodingFirstChatHost(
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
};
|
||||
const legacyConfig = {
|
||||
schemaVersion: 1,
|
||||
projectType: 'custom',
|
||||
initialized: true,
|
||||
defaultModel: null,
|
||||
agents: [{ ...agent, model: null }],
|
||||
knowledgeDirectory: 'knowledge',
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
};
|
||||
const conversation = {
|
||||
id: 'conversation-pi-first-chat',
|
||||
agentId: agent.id,
|
||||
title: '新对话',
|
||||
model: null,
|
||||
modelResolution: 'required',
|
||||
model: configuredModel,
|
||||
modelResolution: 'resolved',
|
||||
archivedAt: null,
|
||||
unread: false,
|
||||
createdAt: now,
|
||||
@@ -152,7 +148,7 @@ async function installCodingFirstChatHost(
|
||||
projectId: project.id,
|
||||
agentId: agent.id,
|
||||
title: conversation.title,
|
||||
model: { model: null, modelResolution: 'required' },
|
||||
model: { model: configuredModel, modelResolution: 'resolved' },
|
||||
},
|
||||
nodes: featureComplete ? [{
|
||||
kind: 'subagent',
|
||||
@@ -279,7 +275,7 @@ async function installCodingFirstChatHost(
|
||||
return respond({ projects: [project], activeProjectId: project.id });
|
||||
}
|
||||
if (path === '/api/provider-accounts') {
|
||||
return respond(featureComplete ? [{
|
||||
return respond([{
|
||||
id: 'account-e2e',
|
||||
vendorId: 'custom',
|
||||
label: 'E2E account',
|
||||
@@ -290,18 +286,25 @@ async function installCodingFirstChatHost(
|
||||
isDefault: true,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
}] : []);
|
||||
}]);
|
||||
}
|
||||
if (path === '/api/provider-accounts/key-info') return respond([]);
|
||||
if (path === '/api/provider-vendors') return respond(featureComplete ? [{ id: 'custom', name: 'Custom' }] : []);
|
||||
if (path === '/api/provider-accounts/default') return respond({ accountId: featureComplete ? 'account-e2e' : null });
|
||||
if (path === '/api/provider-vendors') return respond([{ id: 'custom', name: 'Custom' }]);
|
||||
if (path === '/api/provider-accounts/default') return respond({ accountId: 'account-e2e' });
|
||||
if (path === `/api/coding/projects/config?projectId=${project.id}`) {
|
||||
return respond({ snapshot: { project, config, knowledgeFiles: [] } });
|
||||
}
|
||||
if (path === `/api/coding/projects/conversations?projectId=${project.id}`) {
|
||||
return respond({ conversations: featureComplete ? [conversation, secondConversation] : [] });
|
||||
return respond({
|
||||
conversations: featureComplete
|
||||
? [conversation, secondConversation]
|
||||
: state.conversationCreated
|
||||
? [conversation]
|
||||
: [],
|
||||
});
|
||||
}
|
||||
if (path === '/api/coding/projects/conversations' && method === 'POST') {
|
||||
state.conversationCreated = true;
|
||||
return respond({ conversation }, 201);
|
||||
}
|
||||
if (path === `/api/coding/conversations/${conversation.id}/snapshot`) {
|
||||
@@ -353,23 +356,6 @@ async function installCodingFirstChatHost(
|
||||
if (path.startsWith('/api/coding/skills')) return respond({ skills: [{ id: 'research', name: 'Research', description: 'Inspect sources', selected: true }] });
|
||||
if (/^\/api\/coding\/conversations\/[^/]+\/commands$/.test(path)) return respond({ commands: [{ name: 'review', title: 'Review', description: 'Review changes', source: 'makelore' }] });
|
||||
if (path === '/api/coding/runtime/diagnostics') return respond({ runtime: { revision: { provider: 1, resources: 1 }, workers: [{ conversationId: conversation.id, generation: 1, state: 'running', stage: 'running' }] } });
|
||||
if (path.startsWith('/api/opencode/status')) {
|
||||
return respond({ state: 'stopped', port: null, url: null });
|
||||
}
|
||||
if (path === '/api/opencode/projects' || path.startsWith('/api/opencode/projects?')) {
|
||||
return respond({ projects: [legacyProject], activeProject: legacyProject });
|
||||
}
|
||||
if (path === '/api/opencode/projects/active') {
|
||||
return respond({ projects: [legacyProject], activeProject: legacyProject });
|
||||
}
|
||||
if (path.startsWith('/api/opencode/projects/config?')) {
|
||||
return respond({ status: 'valid', config: legacyConfig, knowledgeFiles: [] });
|
||||
}
|
||||
if (path.startsWith('/api/opencode/projects/conversations?')) {
|
||||
return respond({
|
||||
state: { schemaVersion: 1, sessions: [], updatedAt: now },
|
||||
});
|
||||
}
|
||||
return respond({ success: false, error: `Unhandled E2E route: ${method} ${path}` }, 404);
|
||||
});
|
||||
}, { connection: hostConnection, featureComplete });
|
||||
@@ -422,7 +408,7 @@ test('first PI Conversation is editable under 500 ms and submits before runtime
|
||||
await expect(page.getByTestId('main-layout')).toBeVisible();
|
||||
await page.evaluate(() => {
|
||||
performance.mark('pi-first-chat-start');
|
||||
window.location.hash = '/opencode-chat';
|
||||
window.location.hash = '/chat';
|
||||
});
|
||||
const composer = page.getByRole('textbox');
|
||||
await expect(composer).toBeEnabled();
|
||||
@@ -503,7 +489,7 @@ test('PI feature UI isolates Conversations and exposes queue, interaction, model
|
||||
page = await getStableWindow(electronApp);
|
||||
await page.getByTestId('ai-module-option-programming').click();
|
||||
await expect(page.getByTestId('main-layout')).toBeVisible();
|
||||
await page.evaluate(() => { window.location.hash = '/opencode-chat'; });
|
||||
await page.evaluate(() => { window.location.hash = '/chat'; });
|
||||
|
||||
await expect(page.getByTestId('coding-conversation-header')).toContainText('生成中');
|
||||
await expect(page.getByTestId('coding-conversation-header')).toContainText('队列 1');
|
||||
|
||||
Reference in New Issue
Block a user