源码快照 @ 2026-09-02 (source-only, 剔除非源码素材)
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
import { createHash } from "node:crypto";
|
||||
import { basename, resolve } from "node:path";
|
||||
import type { WorkspaceConfig, WorkspaceInfo } from "./types.js";
|
||||
|
||||
function workspaceIdForKey(key: string): string {
|
||||
const hash = createHash("sha256").update(key).digest("hex");
|
||||
return `ws_${hash.slice(0, 12)}`;
|
||||
}
|
||||
|
||||
export function workspaceIdForPath(path: string): string {
|
||||
return workspaceIdForKey(path);
|
||||
}
|
||||
|
||||
export function workspaceIdForRemote(baseUrl: string, directory?: string | null): string {
|
||||
const normalizedBaseUrl = baseUrl.trim();
|
||||
const normalizedDirectory = directory?.trim() ?? "";
|
||||
const key = normalizedDirectory
|
||||
? `remote::${normalizedBaseUrl}::${normalizedDirectory}`
|
||||
: `remote::${normalizedBaseUrl}`;
|
||||
return workspaceIdForKey(key);
|
||||
}
|
||||
|
||||
export function workspaceIdForOpenwork(hostUrl: string, workspaceId?: string | null): string {
|
||||
const normalizedHostUrl = hostUrl.trim();
|
||||
const normalizedWorkspaceId = workspaceId?.trim() ?? "";
|
||||
const key = normalizedWorkspaceId
|
||||
? `openwork::${normalizedHostUrl}::${normalizedWorkspaceId}`
|
||||
: `openwork::${normalizedHostUrl}`;
|
||||
return workspaceIdForKey(key);
|
||||
}
|
||||
|
||||
export function buildWorkspaceInfos(
|
||||
workspaces: WorkspaceConfig[],
|
||||
cwd: string,
|
||||
): WorkspaceInfo[] {
|
||||
return workspaces.map((workspace) => {
|
||||
const rawPath = workspace.path?.trim() ?? "";
|
||||
const workspaceType = workspace.workspaceType ?? "local";
|
||||
const resolvedPath = rawPath ? resolve(cwd, rawPath) : "";
|
||||
const remoteType = workspace.remoteType;
|
||||
const id = workspace.id?.trim()
|
||||
|| (workspaceType === "remote"
|
||||
? remoteType === "openwork"
|
||||
? workspaceIdForOpenwork(workspace.openworkHostUrl ?? workspace.baseUrl ?? "", workspace.openworkWorkspaceId)
|
||||
: workspaceIdForRemote(workspace.baseUrl ?? "", workspace.directory)
|
||||
: workspaceIdForPath(resolvedPath));
|
||||
const name = workspace.name?.trim()
|
||||
|| workspace.displayName?.trim()
|
||||
|| workspace.openworkWorkspaceName?.trim()
|
||||
|| basename(resolvedPath || workspace.directory?.trim() || workspace.baseUrl?.trim() || "Workspace");
|
||||
return {
|
||||
id,
|
||||
name,
|
||||
path: resolvedPath,
|
||||
preset: workspace.preset?.trim() || (workspaceType === "remote" ? "remote" : "starter"),
|
||||
workspaceType,
|
||||
remoteType,
|
||||
baseUrl: workspace.baseUrl,
|
||||
directory: workspace.directory,
|
||||
displayName: workspace.displayName,
|
||||
openworkHostUrl: workspace.openworkHostUrl,
|
||||
openworkToken: workspace.openworkToken,
|
||||
openworkWorkspaceId: workspace.openworkWorkspaceId,
|
||||
openworkWorkspaceName: workspace.openworkWorkspaceName,
|
||||
sandboxBackend: workspace.sandboxBackend,
|
||||
sandboxRunId: workspace.sandboxRunId,
|
||||
sandboxContainerName: workspace.sandboxContainerName,
|
||||
opencodeUsername: workspace.opencodeUsername,
|
||||
opencodePassword: workspace.opencodePassword,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Pick the workspace the server-managed OpenCode engine should boot in.
|
||||
*
|
||||
* The engine serves every workspace but needs one local directory to start in.
|
||||
* `config.workspaces[0]` is not reliably that: a freshly added remote worker is
|
||||
* prepended to the list, so index 0 can be a remote workspace (no local path)
|
||||
* even when local workspaces exist — which would leave the engine unstarted.
|
||||
* Select the first non-remote workspace with a resolved local path so the engine
|
||||
* starts regardless of ordering; returns undefined for remote-only setups (which
|
||||
* need no local engine).
|
||||
*/
|
||||
export function findManagedEngineWorkspace(workspaces: WorkspaceInfo[]): WorkspaceInfo | undefined {
|
||||
return workspaces.find((workspace) => workspace.workspaceType !== "remote" && workspace.path.trim() !== "");
|
||||
}
|
||||
Reference in New Issue
Block a user