mirror of
https://github.com/openclaw/clawhub.git
synced 2026-08-14 00:47:57 +00:00
feat: export skillspector issue details (#2430)
This commit is contained in:
@@ -359,6 +359,7 @@ function normalizeSkillSpectorAnalysis(analysis: StoredSkillSpectorAnalysis) {
|
||||
issueCount: analysis.issueCount,
|
||||
issues: analysis.issues.map((issue) => ({
|
||||
issueId: issue.issueId,
|
||||
category: issue.category ?? null,
|
||||
severity: issue.severity,
|
||||
confidence: issue.confidence ?? null,
|
||||
explanation: issue.explanation,
|
||||
|
||||
@@ -61,9 +61,11 @@ const baseArtifact: ArtifactExportInput = {
|
||||
issues: [
|
||||
{
|
||||
issueId: "SDI-1",
|
||||
category: "Sensitive Data Exposure",
|
||||
severity: "HIGH",
|
||||
confidence: 0.98,
|
||||
explanation: "The skill body does not match the declared purpose.",
|
||||
explanation:
|
||||
"The skill body does not match the declared purpose and mentions token=supersecret123.",
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -175,7 +177,19 @@ describe("security dataset normalizer", () => {
|
||||
scanner_version: "skillspector-v2.0.0",
|
||||
status: "suspicious",
|
||||
verdict: "DO_NOT_INSTALL",
|
||||
score: 55,
|
||||
severity: "HIGH",
|
||||
reason_codes: ["SDI-1"],
|
||||
issues: [
|
||||
{
|
||||
code: "SDI-1",
|
||||
category: "Sensitive Data Exposure",
|
||||
severity: "HIGH",
|
||||
confidence: 0.98,
|
||||
explanation_redacted:
|
||||
"The skill body does not match the declared purpose and mentions [REDACTED_SECRET]",
|
||||
},
|
||||
],
|
||||
raw_status_family: "suspicious",
|
||||
});
|
||||
expect(rows.staticFindings[0]).toMatchObject({
|
||||
|
||||
@@ -58,6 +58,7 @@ export type SkillSpectorAnalysisInput = {
|
||||
issueCount: number;
|
||||
issues: Array<{
|
||||
issueId: string;
|
||||
category?: string | null;
|
||||
severity: string;
|
||||
confidence: number | null;
|
||||
explanation: string;
|
||||
@@ -173,10 +174,19 @@ export type ScanResultRow = {
|
||||
verdict: string | null;
|
||||
confidence: string | null;
|
||||
checked_at: number | null;
|
||||
score?: number | null;
|
||||
severity?: string | null;
|
||||
reason_codes: string[];
|
||||
engine_stats: VtAnalysisInput["engineStats"];
|
||||
summary_redacted: string | null;
|
||||
raw_status_family: DatasetLabel;
|
||||
issues?: Array<{
|
||||
code: string;
|
||||
category: string | null;
|
||||
severity: string;
|
||||
confidence: number | null;
|
||||
explanation_redacted: string | null;
|
||||
}>;
|
||||
};
|
||||
|
||||
export type StaticFindingRow = {
|
||||
@@ -408,9 +418,12 @@ function buildScanResultRows(input: ArtifactExportInput, artifactId: string): Sc
|
||||
verdict: input.skillSpectorAnalysis.recommendation,
|
||||
confidence: null,
|
||||
checked_at: input.skillSpectorAnalysis.checkedAt,
|
||||
score: input.skillSpectorAnalysis.score,
|
||||
severity: input.skillSpectorAnalysis.severity,
|
||||
reason_codes: input.skillSpectorAnalysis.issues
|
||||
.map((issue) => issue.issueId)
|
||||
.sort((a, b) => a.localeCompare(b)),
|
||||
issues: normalizeSkillSpectorIssues(input.skillSpectorAnalysis.issues),
|
||||
engine_stats: null,
|
||||
summary_redacted: redactText(
|
||||
input.skillSpectorAnalysis.summary ?? input.skillSpectorAnalysis.error,
|
||||
@@ -473,6 +486,18 @@ function buildStaticFindingRows(
|
||||
}));
|
||||
}
|
||||
|
||||
function normalizeSkillSpectorIssues(issues: SkillSpectorAnalysisInput["issues"]) {
|
||||
return issues
|
||||
.map((issue) => ({
|
||||
code: issue.issueId,
|
||||
category: issue.category ?? null,
|
||||
severity: issue.severity,
|
||||
confidence: issue.confidence ?? null,
|
||||
explanation_redacted: redactText(issue.explanation),
|
||||
}))
|
||||
.sort((left, right) => left.code.localeCompare(right.code));
|
||||
}
|
||||
|
||||
function buildClawScanFindingRows(
|
||||
input: ArtifactExportInput,
|
||||
artifactId: string,
|
||||
|
||||
Reference in New Issue
Block a user