feat(plugins): type clawhub security reports

This commit is contained in:
Vincent Koc
2026-05-02 11:34:14 -07:00
parent ba5723d38b
commit a3f2f3a4eb
2 changed files with 73 additions and 0 deletions

View File

@@ -9,6 +9,7 @@ import {
downloadClawHubSkillArchive,
fetchClawHubPackageArtifact,
fetchClawHubPackageReadiness,
fetchClawHubPackageSecurity,
normalizeClawHubSha256Integrity,
normalizeClawHubSha256Hex,
parseClawHubPluginSpec,
@@ -292,6 +293,40 @@ describe("clawhub helpers", () => {
);
});
it("fetches typed package security reports", async () => {
let requestedUrl = "";
await expect(
fetchClawHubPackageSecurity({
name: "@openclaw/diagnostics-otel",
version: "2026.3.22",
fetchImpl: async (input) => {
requestedUrl = input instanceof Request ? input.url : String(input);
return new Response(
JSON.stringify({
releaseId: "rel_demo",
state: "approved",
reasonCode: "clean",
createdAt: 1774256733107,
scanState: "clean",
moderationState: "approved",
}),
{ status: 200, headers: { "content-type": "application/json" } },
);
},
}),
).resolves.toEqual({
releaseId: "rel_demo",
state: "approved",
reasonCode: "clean",
createdAt: 1774256733107,
scanState: "clean",
moderationState: "approved",
});
expect(new URL(requestedUrl).pathname).toBe(
"/api/v1/packages/%40openclaw%2Fdiagnostics-otel/versions/2026.3.22/security",
);
});
it("downloads package archives to sanitized temp paths and cleans them up", async () => {
const archive = await downloadClawHubPackageArchive({
name: "@hyf/zai-external-alpha",

View File

@@ -62,6 +62,14 @@ export type ClawHubArtifactScanState =
| "not-run"
| (string & {});
export type ClawHubArtifactModerationState = "approved" | "quarantined" | "revoked" | (string & {});
export type ClawHubPackageSecurityState =
| "pending"
| "approved"
| "limited"
| "quarantined"
| "rejected"
| "revoked"
| (string & {});
export type ClawHubResolvedArtifact =
| {
source: "clawhub";
@@ -90,6 +98,17 @@ export type ClawHubPackageArtifactResolverResponse = {
version?: { version?: string | null } | string | null;
artifact?: ClawHubResolvedArtifact | null;
};
export type ClawHubPackageSecurityResponse = {
packageId?: string | null;
releaseId?: string | null;
state: ClawHubPackageSecurityState;
reasonCode?: string | null;
moderatorNote?: string | null;
actorId?: string | null;
createdAt?: number | null;
scanState?: ClawHubArtifactScanState | null;
moderationState?: ClawHubArtifactModerationState | null;
};
export type ClawHubPackageClawPackSummary = {
available: boolean;
specVersion?: number | null;
@@ -674,6 +693,25 @@ export async function fetchClawHubPackageArtifact(params: {
});
}
export async function fetchClawHubPackageSecurity(params: {
name: string;
version: string;
baseUrl?: string;
token?: string;
timeoutMs?: number;
fetchImpl?: FetchLike;
}): Promise<ClawHubPackageSecurityResponse> {
return await fetchJson<ClawHubPackageSecurityResponse>({
baseUrl: params.baseUrl,
path: `/api/v1/packages/${encodeURIComponent(params.name)}/versions/${encodeURIComponent(
params.version,
)}/security`,
token: params.token,
timeoutMs: params.timeoutMs,
fetchImpl: params.fetchImpl,
});
}
export async function fetchClawHubPackageReadiness(params: {
name: string;
baseUrl?: string;