Remove legacy client-manager workflows

This commit is contained in:
npc0-hue
2026-09-03 13:08:08 +08:00
parent bf3c382d15
commit fe09d21a56
56 changed files with 304 additions and 4121 deletions
+5 -69
View File
@@ -10,7 +10,6 @@ import {
canRequestBridgeAction,
createAIInvocationRequest,
createArtifactOpenRequest,
createClientManagerRequest,
createBridgeExecutionRequest,
createLifecycleDispatchRequest,
createProductionPluginLifecycleRequest,
@@ -22,7 +21,6 @@ import {
createRunDistributionRequest,
hasPluginPermission,
parseArtifactReference,
parseClientManagerLifecycleStatus,
parseBridgeExecutionResponse,
parseAIInvocationResponse,
type GameClientBridgeQueryTemplateDeclaration,
@@ -256,17 +254,7 @@ describe("plugin manifest validation", () => {
files: Array<{ key: string; directoryKey: string; label: string; kind: string; streamKey?: string; editable?: boolean }>;
configFields: Array<{ key: string; fileKey: string; configKey: string; label: string }>;
};
runtimeProfiles?: {
lifecycleProfiles?: Array<{ key: string; capabilities?: string[] }>;
logSources?: Array<{ key: string }>;
clientManagers?: Array<{
key: string;
build?: { workspaceRef?: string; entryRef?: string };
configTemplates?: Array<{ key?: string; templateRef?: string; outputRef?: string }>;
deployment?: { arguments?: string[] };
health?: { intervalSeconds?: number; degradedAfterSeconds?: number; offlineAfterSeconds?: number };
}>;
};
runtimeProfiles?: { lifecycleProfiles?: Array<{ key: string; capabilities?: string[] }>; logSources?: Array<{ key: string }>; clientManagers?: unknown[] };
version: string;
};
const installAction = JSON.parse(fs.readFileSync(path.join(pluginsRoot, "examples/scum-server-plugin/actions/install.json"), "utf8")) as { environment?: Record<string, string> };
@@ -724,9 +712,7 @@ describe("plugin manifest validation", () => {
expect(errors.some((error) => error.includes("raw host path"))).toBe(true);
expect(errors.some((error) => error.includes("arbitrary shell"))).toBe(true);
expect(errors.some((error) => error.includes("not approved for dependency download"))).toBe(true);
expect(errors.some((error) => error.includes("client-manager.deploy is required"))).toBe(true);
expect(errors.some((error) => error.includes("offline threshold"))).toBe(true);
expect(errors.some((error) => error.includes("profile version is below minimumVersion"))).toBe(true);
expect(errors.some((error) => error.includes("runtimeProfiles.clientManagers") && error.includes("no longer supported"))).toBe(true);
});
it("validates typed lifecycle declarations and rejects shell/path escapes", () => {
@@ -1050,24 +1036,6 @@ describe("plugin SDK", () => {
});
it("types runtime profile declarations without raw credentials", () => {
const clientManager: RuntimeClientManagerProfile = {
key: "safe-client-manager",
version: "1.2.3",
repository: { url: "https://github.com/example/safe-client.git", revisionPolicy: "pinned", revision: "0123456789abcdef" },
supportedTargets: [{ os: "linux", arch: "amd64" }],
build: { system: "go", entryRef: "cmd/client/main.go" },
outputArtifacts: ["safe-client"],
deployment: {
mode: "run-supervised",
executableRef: "safe-client",
arguments: ["--config", "config.json"],
requiredRunCapabilities: ["client-manager.deploy", "client-manager.control", "client-manager.update", "client-manager.rollback", "client-manager.uninstall"]
},
lifecycle: { actions: ["start", "stop", "restart", "status", "update", "rollback", "uninstall"], startupTimeoutSeconds: 30, stopTimeoutSeconds: 15 },
health: { mode: "component-heartbeat", intervalSeconds: 15, degradedAfterSeconds: 45, offlineAfterSeconds: 120, requiredCapabilities: ["component.register", "component.heartbeat", "component.health"] },
compatibility: { minimumVersion: "1.0.0", allowDowngrade: false },
updatePolicy: { strategy: "manual-staged", requireApproval: true, healthConfirmationSeconds: 60, retainPrevious: true }
};
const manifest: GamePluginManifest = {
id: "game.runtime",
name: "Runtime Fixture",
@@ -1081,22 +1049,20 @@ describe("plugin SDK", () => {
discovery: [{ key: "java", kind: "command.version", targetKey: "java", required: true }],
dependencyProbes: [{ key: "java-21", kind: "java.version", targetKey: "java", minimumVersion: "21" }],
logSources: [{ key: "console", kind: "process.stdout", streamKey: "console", cursorKind: "sequence" }],
transportProfiles: [{ key: "files", kind: "file", capabilities: ["files.read"] }],
clientManagers: [clientManager]
transportProfiles: [{ key: "files", kind: "file", capabilities: ["files.read"] }]
}
};
expect(manifest.runtimeProfiles?.discovery?.[0].targetKey).toBe("java");
expect(manifest.runtimeProfiles?.clientManagers?.[0].deployment?.requiredRunCapabilities).toContain("client-manager.deploy");
expect(JSON.stringify(manifest)).not.toContain("password=");
});
it("builds run distribution, dependency, log backfill, and client-manager envelopes", () => {
it("builds run distribution, dependency, and log backfill envelopes", () => {
const context: PluginBridgeContext = {
pluginId: "game.scum",
routeKey: "remote",
serverInstanceId: "server-1",
permissions: ["server.run.distribution", "server.dependencies.manage", "server.logs.read", "server.client-manager.manage"]
permissions: ["server.run.distribution", "server.dependencies.manage", "server.logs.read"]
};
expect(canRequestBridgeAction(context, "run.distribution.request")).toBe(true);
@@ -1117,36 +1083,6 @@ describe("plugin SDK", () => {
action: "logs.backfill.request",
payload: { sourceKey: "chat-log", limit: "500" }
});
expect(createClientManagerRequest({ requestId: "client-1", context, operation: "generate", profileKey: "example-client-manager", targetOS: "windows", targetArch: "amd64", idempotencyKey: "idem-client" })).toMatchObject({
action: "client-manager.request",
payload: { operation: "generate", profileKey: "example-client-manager" }
});
expect(JSON.stringify(createClientManagerRequest({ requestId: "client-2", context, operation: "reset-key", profileKey: "example-client-manager", idempotencyKey: "idem-reset" }))).not.toContain("secret");
expect(createClientManagerRequest({ requestId: "client-3", context, operation: "deploy", profileKey: "example-client-manager", installationId: "cm-install-1", artifactId: "artifact-1", expectedDeploymentGeneration: 2, idempotencyKey: "idem-deploy" })).toMatchObject({
action: "client-manager.request",
payload: { operation: "deploy", installationId: "cm-install-1", artifactId: "artifact-1", expectedDeploymentGeneration: "2" }
});
expect(parseClientManagerLifecycleStatus({
installationId: "cm-install-1",
profileKey: "example-client-manager",
status: "online",
phase: "healthy",
targetOS: "windows",
targetArch: "amd64",
version: "1.0.0",
artifactId: "artifact-1",
deploymentGeneration: "2",
health: "healthy",
actions: "stop,restart,update,uninstall"
})).toMatchObject({ installationId: "cm-install-1", deploymentGeneration: 2, actions: ["stop", "restart", "update", "uninstall"] });
expect(parseClientManagerLifecycleStatus({
installationId: "cm-install-1",
profileKey: "example-client-manager",
status: "online",
deploymentGeneration: "2",
actions: "stop",
healthReason: "Bearer stolen-session"
})).toBeUndefined();
});
it("builds full plugin lifecycle envelopes through Platform only", () => {