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

@@ -9,7 +9,7 @@ import {
} from 'node:fs/promises';
import { dirname, isAbsolute, join, relative, sep } from 'node:path';
import type { ProjectType } from '../../shared/project-config';
import { readProjectConfig } from '../opencode/project-config';
import { readCodingProjectConfigV2 } from '../coding-projects/project-config';
import { writeStoredZip } from './streaming-zip';
type PublishableProjectType = Exclude<ProjectType, 'custom'>;
@@ -45,6 +45,7 @@ const EXCLUDED_DIRECTORY_NAMES = new Set([
'.kube',
'.next',
'.niancode',
// Legacy runtime metadata is inert product data and is never publishable.
'.opencode',
'.project-docs',
'.turbo',
@@ -267,7 +268,7 @@ export async function createStaticProjectPackage(input: {
}
async function readPublishableProjectType(projectPath: string): Promise<PublishableProjectType> {
const result = await readProjectConfig(projectPath);
const result = await readCodingProjectConfigV2(projectPath);
if (result.status === 'invalid') {
throw new ProjectPackageError(
'PROJECT_CONFIG_INVALID',

View File

@@ -2,7 +2,7 @@ import { createHash } from 'node:crypto';
import { watch, type FSWatcher } from 'node:fs';
import { access, readFile } from 'node:fs/promises';
import { join } from 'node:path';
import type { OpencodeProject, OpencodeProjectStore } from '../opencode/project-store';
import type { CodingProject, CodingProjectStore } from '../coding-projects/project-store';
import { readWorksSubmissionBinding } from './works-submission-binding';
import { WORKS_SQUARE_CONFIG } from '../api/works-config';
import { proxyAwareFetch } from '../utils/proxy-fetch';
@@ -39,7 +39,7 @@ type WatchDirectory = (
onChange: (filename: string | null) => void,
) => ProjectProgressWatcher;
type ProjectProgressProjectStore = Pick<OpencodeProjectStore, 'getActiveProject' | 'subscribe'> & Partial<Pick<OpencodeProjectStore, 'listProjects'>>;
type ProjectProgressProjectStore = Pick<CodingProjectStore, 'getActiveProject' | 'subscribe'> & Partial<Pick<CodingProjectStore, 'listProjects'>>;
export type ProjectProgressSyncOptions = {
apiBaseUrl?: string;
@@ -50,7 +50,7 @@ export type ProjectProgressSyncOptions = {
};
type ProjectProgressState = {
project: OpencodeProject;
project: CodingProject;
watcher: ProjectProgressWatcher | null;
timer: ReturnType<typeof setTimeout> | null;
pendingProgress: boolean;
@@ -137,7 +137,7 @@ async function readProductOverview(projectPath: string): Promise<string> {
}
async function resolveProjectProgressIdentity(
project: OpencodeProject,
project: CodingProject,
): Promise<ProjectProgressIdentity> {
const binding = await readWorksSubmissionBinding(project.path, project.id);
if (binding?.status === 'submitted' && binding.app_id) {
@@ -210,7 +210,7 @@ export function createProjectProgressSync(
}, immediate ? 0 : debounceMs);
}
function attachProject(project: OpencodeProject): void {
function attachProject(project: CodingProject): void {
const previous = states.get(project.id);
if (previous && previous.project.path === project.path) {
previous.project = project;

View File

@@ -4,8 +4,8 @@ import { clearWorksSquareAIGatewayCredential } from './works-square-ai-gateway';
import { getProviderService } from './providers/provider-service';
export type WorksSquareRuntimeContext = {
opencodeManager: {
stop(): Promise<unknown>;
codingProducts?: {
sleep(): Promise<unknown>;
};
imageWorkspace?: {
closeEventSessions?(options?: {
@@ -31,7 +31,7 @@ async function runManagedWorksSquareRuntimeCleanup(
accessToken,
tolerateRemoteFailure,
}))(),
(async () => await ctx.opencodeManager.stop())(),
(async () => await ctx.codingProducts?.sleep())(),
(async () => {
const deleted = await getProviderService().deleteAccountApiKey(
NIANCODE_USER_MODEL_ACCOUNT_ID,

View File

@@ -1,6 +1,6 @@
import { readFile, writeFile } from 'node:fs/promises';
import { join } from 'node:path';
import type { OpencodeProjectStore } from '../opencode/project-store';
import type { CodingProjectStore } from '../coding-projects/project-store';
import { logger } from '../utils/logger';
import {
WORKS_SUBMISSION_BINDING_FILE_NAME,
@@ -17,8 +17,8 @@ const LEGACY_PENDING_STATUSES = new Set([
]);
const LEGACY_RETIRED_MESSAGE = '旧版自动部署任务已停用,请在项目配置中点击“提交审核”重新提交。';
type ProjectStore = Pick<OpencodeProjectStore, 'listProjects'>
& Partial<Pick<OpencodeProjectStore, 'getActiveProject'>>;
type ProjectStore = Pick<CodingProjectStore, 'listProjects'>
& Partial<Pick<CodingProjectStore, 'getActiveProject'>>;
type SubmittedBindingInput = {
appId: string;