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:
2026-08-24 12:17:43 +08:00
parent 61fede2b4d
commit 5a275b93a7
199 changed files with 1330 additions and 64725 deletions

View File

@@ -16,8 +16,8 @@ import {
import { TitleBar } from '@/components/layout/TitleBar';
import { Button } from '@/components/ui/button';
import { Progress } from '@/components/ui/progress';
import { hostApiFetch } from '@/lib/host-api';
import { cn } from '@/lib/utils';
import { useOpencodeStore } from '@/stores/opencode';
import { useSettingsStore } from '@/stores/settings';
import { useTranslation } from 'react-i18next';
import type { TFunction } from 'i18next';
@@ -71,7 +71,7 @@ interface DefaultSkill {
}
const getDefaultSkills = (t: TFunction): DefaultSkill[] => [
{ id: 'opencode', name: t('defaultSkills.opencode.name'), description: t('defaultSkills.opencode.description') },
{ id: 'coding-runtime', name: t('defaultSkills.codingRuntime.name'), description: t('defaultSkills.codingRuntime.description') },
{ id: 'python-env', name: t('defaultSkills.python-env.name'), description: t('defaultSkills.python-env.description') },
{ id: 'code-assist', name: t('defaultSkills.code-assist.name'), description: t('defaultSkills.code-assist.description') },
{ id: 'file-tools', name: t('defaultSkills.file-tools.name'), description: t('defaultSkills.file-tools.description') },
@@ -107,10 +107,6 @@ function useRotatingSetupMessage(messages: string[], active = true) {
return messages[index % Math.max(messages.length, 1)] ?? messages[0] ?? '';
}
function isRuntimeReady(state: string) {
return state === 'running' || state === 'stopped';
}
export function Setup() {
const { t } = useTranslation('setup');
const navigate = useNavigate();
@@ -339,8 +335,6 @@ interface RuntimeContentProps {
function RuntimeContent({ onStatusChange }: RuntimeContentProps) {
const { t } = useTranslation('setup');
const opencodeStatus = useOpencodeStore((state) => state.status);
const refreshOpencodeStatus = useOpencodeStore((state) => state.refreshStatus);
const stuckTimeoutRef = useRef<number | null>(null);
const [runtimeStatus, setRuntimeStatus] = useState<RuntimeProgressStatus>('checking');
@@ -394,21 +388,16 @@ function RuntimeContent({ onStatusChange }: RuntimeContentProps) {
try {
setRuntimeProgress(48);
await refreshOpencodeStatus();
const current = useOpencodeStore.getState().status;
if (isRuntimeReady(current.state)) {
const current = await hostApiFetch<{ runtime?: string }>('/api/app/runtime-info');
if (current.runtime === 'pi') {
markSuccess();
return;
}
if (current.state === 'error') {
markFailure();
return;
}
setRuntimeProgress(72);
markFailure();
} catch {
markFailure();
}
}, [markFailure, markSuccess, onStatusChange, refreshOpencodeStatus, startStuckTimeout]);
}, [markFailure, markSuccess, onStatusChange, startStuckTimeout]);
useEffect(() => {
const timer = window.setTimeout(() => {
@@ -420,18 +409,6 @@ function RuntimeContent({ onStatusChange }: RuntimeContentProps) {
};
}, [clearStuckTimeout, runChecks]);
useEffect(() => {
let timer: number | null = null;
if (opencodeStatus.state === 'running') {
timer = window.setTimeout(markSuccess, 0);
} else if (opencodeStatus.state === 'error') {
timer = window.setTimeout(markFailure, 0);
}
return () => {
if (timer !== null) window.clearTimeout(timer);
};
}, [markFailure, markSuccess, opencodeStatus.state]);
const statusMessage = runtimeStatus === 'success'
? t('runtime.progress.done')
: runtimeStatus === 'error'
@@ -585,7 +562,6 @@ interface CompleteContentProps {
function CompleteContent({ installedSkills }: CompleteContentProps) {
const { t } = useTranslation(['setup', 'settings']);
const opencodeStatus = useOpencodeStore((state) => state.status);
const installedSkillNames = getDefaultSkills(t)
.filter((s: DefaultSkill) => installedSkills.includes(s.id))
@@ -609,9 +585,7 @@ function CompleteContent({ installedSkills }: CompleteContentProps) {
</div>
<div className="flex items-center justify-between p-3 rounded-lg bg-muted/50">
<span>{t('complete.runtime')}</span>
<span className={opencodeStatus.state === 'running' ? 'text-green-400' : 'text-yellow-400'}>
{opencodeStatus.state === 'running' ? t('complete.running') : opencodeStatus.state}
</span>
<span className="text-green-400">{t('complete.running')}</span>
</div>
</div>