refactor(plugin-sdk): remove unused private QA helpers (#119437)

This commit is contained in:
Peter Steinberger
2026-08-04 20:16:07 -07:00
committed by GitHub
parent 1f3d45b76f
commit a8caab5c3d
4 changed files with 22 additions and 166 deletions
-14
View File
@@ -27,20 +27,6 @@ export {
listImportedBundledPluginFacadeIds,
} from "./facade-loader.js";
/** Create a lazy value/function proxy for one property of a facade module. */
export function createLazyFacadeValue<TFacade extends object, K extends keyof TFacade>(
loadFacadeModule: () => TFacade,
key: K,
): TFacade[K] {
return ((...args: unknown[]) => {
const value = loadFacadeModule()[key];
if (typeof value !== "function") {
return value;
}
return (value as (...innerArgs: unknown[]) => unknown)(...args);
}) as TFacade[K];
}
const OPENCLAW_PACKAGE_ROOT =
resolveLoaderPackageRoot({
modulePath: fileURLToPath(import.meta.url),
-23
View File
@@ -224,29 +224,6 @@ describe("plugin-sdk qa-runtime", () => {
});
});
it("builds shared live-lane artifact errors", async () => {
const module = await import("./qa-runtime.js");
expect(
module.buildQaLiveLaneArtifactsError({
heading: "Matrix QA failed.",
details: ["cleanup: ok"],
artifacts: {
report: "/tmp/report.md",
summary: "/tmp/summary.json",
},
}),
).toBe(
[
"Matrix QA failed.",
"cleanup: ok",
"Artifacts:",
"- report: /tmp/report.md",
"- summary: /tmp/summary.json",
].join("\n"),
);
});
it("shares Docker health parsing across array and jsonl compose output", async () => {
const module = await import("./qa-runtime.js");
const runtime = module.createQaDockerRuntime({ auditContext: "qa-test" });
-97
View File
@@ -1,10 +1,5 @@
import fs from "node:fs";
import fsp from "node:fs/promises";
import { createServer } from "node:net";
import path from "node:path";
// QA runtime helpers register and execute plugin QA scenarios from local files.
import { toErrorObject } from "@openclaw/normalization-core/error-coercion";
import { formatErrorMessage } from "./error-runtime.js";
import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-runtime.js";
import { resolvePrivateQaBundledPluginsEnv } from "./private-qa-bundled-env.js";
import { runExec } from "./process-runtime.js";
@@ -110,35 +105,6 @@ export type QaDockerFetchLike = (
const DEFAULT_QA_DOCKER_COMMAND_TIMEOUT_MS = 120_000;
const DEFAULT_QA_DOCKER_HEALTH_REQUEST_TIMEOUT_MS = 2_000;
/** Append a formatted live-lane issue while preserving the caller-owned issue list. */
export function appendQaLiveLaneIssue(issues: string[], label: string, error: unknown) {
issues.push(`${label}: ${formatErrorMessage(error)}`);
}
/** Format a live-lane failure message that includes artifact labels and paths. */
export function buildQaLiveLaneArtifactsError(params: {
heading: string;
artifacts: Record<string, string>;
details?: string[];
}) {
return [
params.heading,
...(params.details ?? []),
"Artifacts:",
...Object.entries(params.artifacts).map(([label, filePath]) => `- ${label}: ${filePath}`),
].join("\n");
}
/** Print live-transport QA artifact paths with a lane label for CI log parsers. */
export function printLiveTransportQaArtifacts(
laneLabel: string,
artifacts: Record<string, string>,
) {
for (const [label, filePath] of Object.entries(artifacts)) {
process.stdout.write(`${laneLabel} ${label}: ${filePath}\n`);
}
}
function describeQaDockerError(error: unknown) {
if (error instanceof Error) {
return error.message;
@@ -461,66 +427,3 @@ export function createQaDockerRuntime(params: {
waitForHealth,
};
}
type ProcessWriteCallback = (err?: Error | null) => void;
/** Tee stdout and stderr into a private artifact file until the returned stop hook runs. */
export async function startLiveTransportQaOutputTee(params: {
fileName: string;
outputDir: string;
}) {
await fsp.mkdir(params.outputDir, { recursive: true });
const outputPath = path.join(params.outputDir, params.fileName);
const output = fs.createWriteStream(outputPath, {
encoding: "utf8",
flags: "a",
mode: 0o600,
});
let outputError: Error | null = null;
output.on("error", (error) => {
outputError ??= error;
});
const originalStdoutWrite = Reflect.get(process.stdout, "write");
const originalStderrWrite = Reflect.get(process.stderr, "write");
const boundStdoutWrite = originalStdoutWrite.bind(process.stdout);
const boundStderrWrite = originalStderrWrite.bind(process.stderr);
let stopped = false;
const tee = (originalWrite: typeof process.stdout.write) =>
function writeWithTee(
this: NodeJS.WriteStream,
chunk: string | Uint8Array,
encodingOrCallback?: BufferEncoding | ProcessWriteCallback,
callback?: ProcessWriteCallback,
) {
if (!stopped && !outputError) {
output.write(chunk);
}
return Reflect.apply(originalWrite, this, [chunk, encodingOrCallback, callback]) as boolean;
};
process.stdout.write = tee(boundStdoutWrite) as typeof process.stdout.write;
process.stderr.write = tee(boundStderrWrite) as typeof process.stderr.write;
return {
outputPath,
async stop() {
if (stopped) {
return;
}
stopped = true;
process.stdout.write = originalStdoutWrite;
process.stderr.write = originalStderrWrite;
if (outputError) {
throw outputError;
}
await new Promise<void>((resolve, reject) => {
output.once("error", reject);
output.end(resolve);
});
if (outputError) {
throw toErrorObject(outputError, "Non-Error thrown");
}
},
};
}
+22 -32
View File
@@ -304,6 +304,21 @@ export function buildComputedAccountStatusSnapshot<TExtra extends StatusSnapshot
);
}
function buildResolvedComputedAccountStatusSnapshot<
ResolvedAccount,
Probe,
Audit,
TExtra extends StatusSnapshotExtra,
>(
params: ComputedAccountStatusAdapterParams<ResolvedAccount, Probe, Audit>,
{ extra, ...snapshot }: ComputedAccountStatusSnapshot<TExtra>,
) {
return buildComputedAccountStatusSnapshot(
{ ...snapshot, runtime: params.runtime, probe: params.probe },
extra,
);
}
/** Build a full status adapter when only configured/extras vary per account. */
export function createComputedAccountStatusAdapter<
ResolvedAccount,
@@ -319,22 +334,8 @@ export function createComputedAccountStatusAdapter<
): ChannelStatusAdapter<ResolvedAccount, Probe, Audit> {
return {
...buildComputedAccountStatusAdapterBase(options),
buildAccountSnapshot: (params) => {
const typedParams = params as ComputedAccountStatusAdapterParams<
ResolvedAccount,
Probe,
Audit
>;
const { extra, ...snapshot } = options.resolveAccountSnapshot(typedParams);
return buildComputedAccountStatusSnapshot(
{
...snapshot,
runtime: typedParams.runtime,
probe: typedParams.probe,
},
extra,
);
},
buildAccountSnapshot: (params) =>
buildResolvedComputedAccountStatusSnapshot(params, options.resolveAccountSnapshot(params)),
};
}
@@ -353,22 +354,11 @@ export function createAsyncComputedAccountStatusAdapter<
): ChannelStatusAdapter<ResolvedAccount, Probe, Audit> {
return {
...buildComputedAccountStatusAdapterBase(options),
buildAccountSnapshot: async (params) => {
const typedParams = params as ComputedAccountStatusAdapterParams<
ResolvedAccount,
Probe,
Audit
>;
const { extra, ...snapshot } = await options.resolveAccountSnapshot(typedParams);
return buildComputedAccountStatusSnapshot(
{
...snapshot,
runtime: typedParams.runtime,
probe: typedParams.probe,
},
extra,
);
},
buildAccountSnapshot: async (params) =>
buildResolvedComputedAccountStatusSnapshot(
params,
await options.resolveAccountSnapshot(params),
),
};
}