@gpzhang2001/sharpkit-reporting 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.d.ts +10 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +182 -31
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +203 -32
- package/src/state.ts +13 -1
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["normalizeCwe","args"],"sources":["../src/cvss.ts","../src/dedupe.ts","../src/state.ts","../src/writers.ts","../src/sarif.ts","../src/index.ts"],"sourcesContent":["/**\n * CVSS v3.1 base-score math, ported from strix's usage of the `cvss`\n * package (tool.py `_calculate_cvss` :134-153): build the vector string,\n * compute the base score and qualitative severity. The score uses the\n * CVSS 3.1 spec formula with the spec's Roundup1 (ceil to one decimal with\n * the IEEE-754 guard), and a \"none\" base severity is remapped to \"info\"\n * (strix parity).\n * @module @gpzhang2001/sharpkit-reporting/cvss\n */\n\n/** The eight CVSS metrics with their allowed values (strix `_CVSS_VALID`). */\nexport const CVSS_VALID = {\n attack_vector: ['N', 'A', 'L', 'P'],\n attack_complexity: ['L', 'H'],\n privileges_required: ['N', 'L', 'H'],\n user_interaction: ['N', 'R'],\n scope: ['U', 'C'],\n confidentiality: ['N', 'L', 'H'],\n integrity: ['N', 'L', 'H'],\n availability: ['N', 'L', 'H'],\n} as const\n\nexport type CvssMetricName = keyof typeof CVSS_VALID\n\n/** The eight metrics in vector order (strix vector build order). */\nconst METRIC_ORDER: readonly CvssMetricName[] = [\n 'attack_vector', 'attack_complexity', 'privileges_required', 'user_interaction',\n 'scope', 'confidentiality', 'integrity', 'availability',\n]\n\n/** Weight tables (CVSS v3.1 spec §3.1). */\nconst AV: Record<string, number | undefined> = { N: 0.85, A: 0.62, L: 0.55, P: 0.2 }\nconst AC: Record<string, number | undefined> = { L: 0.77, H: 0.44 }\nconst PR_UNCHANGED: Record<string, number | undefined> = { N: 0.85, L: 0.62, H: 0.27 }\nconst PR_CHANGED: Record<string, number | undefined> = { N: 0.85, L: 0.68, H: 0.5 }\nconst UI: Record<string, number | undefined> = { N: 0.85, R: 0.62 }\nconst CIA: Record<string, number | undefined> = { H: 0.56, L: 0.22, N: 0 }\n\n/**\n * CVSS 3.1 Roundup1: smallest one-decimal value >= the input (the `cvss`\n * package quantizes with Decimal ROUND_CEILING; the 5-decimal pre-round\n * absorbs float artifacts the same way the spec intends).\n */\nfunction roundup(value: number): number {\n const quantized = Number(value.toFixed(5))\n return Math.ceil(Number((quantized * 10).toFixed(6))) / 10\n}\n\n/**\n * Validate a breakdown against the allowed metric/value sets.\n * @param breakdown - the model-supplied 8-metric dict.\n * @returns validation errors, empty when valid.\n */\nexport function validateCvssBreakdown(breakdown: Record<string, unknown>): string[] {\n const errors: string[] = []\n if (typeof breakdown !== 'object' || breakdown === null || Object.keys(breakdown).length === 0) {\n return ['cvss_breakdown must be a non-empty object with all 8 metrics']\n }\n for (const metric of METRIC_ORDER) {\n const value = breakdown[metric]\n const allowed = CVSS_VALID[metric]\n if (typeof value !== 'string' || !(allowed as readonly string[]).includes(value)) {\n errors.push(`Invalid ${metric}: ${String(value)}. Must be one of: [${allowed.join(', ')}]`)\n }\n }\n return errors\n}\n\n/**\n * Build the vector string (strix format: CVSS:3.1/AV:../AC:../PR:../UI:../S:../C:../I:../A:..).\n * @param breakdown - a validated breakdown.\n */\nexport function buildCvssVector(breakdown: Readonly<Record<CvssMetricName, string>>): string {\n const parts = METRIC_ORDER.map(metric => {\n const short = { attack_vector: 'AV', attack_complexity: 'AC', privileges_required: 'PR', user_interaction: 'UI', scope: 'S', confidentiality: 'C', integrity: 'I', availability: 'A' }[metric]\n return `${short}:${breakdown[metric]}`\n })\n return `CVSS:3.1/${parts.join('/')}`\n}\n\n/**\n * Compute the CVSS v3.1 base score for a breakdown (the `cvss` package's\n * `compute_base_score`: Scope U ISC = 6.42×ISCBase; Scope C ISC = the 7.52\n * formula; Scope C multiplies the total by 1.08 before the cap).\n * @param breakdown - a validated breakdown.\n * @returns the rounded base score (0.0 when impact is non-positive).\n */\nexport function cvssBaseScore(breakdown: Readonly<Record<CvssMetricName, string>>): number {\n const scopeChanged = breakdown.scope === 'C'\n const c = CIA[breakdown.confidentiality] ?? 0\n const i = CIA[breakdown.integrity] ?? 0\n const a = CIA[breakdown.availability] ?? 0\n const iscBase = 1 - (1 - c) * (1 - i) * (1 - a)\n const isc = scopeChanged\n ? 7.52 * (iscBase - 0.029) - 3.25 * (iscBase - 0.02) ** 15\n : 6.42 * iscBase\n if (isc <= 0) return 0\n const pr = ((scopeChanged ? PR_CHANGED : PR_UNCHANGED)[breakdown.privileges_required]) ?? 0\n const exploitability = 8.22 * (AV[breakdown.attack_vector] ?? 0) * (AC[breakdown.attack_complexity] ?? 0) * pr * (UI[breakdown.user_interaction] ?? 0)\n const raw = scopeChanged ? Math.min(1.08 * (isc + exploitability), 10) : Math.min(isc + exploitability, 10)\n return roundup(raw)\n}\n\n/**\n * Qualitative severity banding (the `cvss` package's rating bands).\n * @param score - the base score.\n */\nexport function cvssSeverity(score: number): 'none' | 'low' | 'medium' | 'high' | 'critical' {\n if (score === 0) return 'none'\n if (score <= 3.9) return 'low'\n if (score <= 6.9) return 'medium'\n if (score <= 8.9) return 'high'\n return 'critical'\n}\n\n/**\n * Full computation: vector + score + severity with the \"none\"→\"info\" remap\n * (strix `_calculate_cvss` return contract).\n * @param breakdown - a validated breakdown.\n */\nexport function calculateCvss(breakdown: Readonly<Record<CvssMetricName, string>>): { readonly vector: string; readonly score: number; readonly severity: string } {\n const vector = buildCvssVector(breakdown)\n const score = cvssBaseScore(breakdown)\n const severity = cvssSeverity(score)\n return { vector, score, severity: severity === 'none' ? 'info' : severity }\n}\n\n/**\n * Dependency severity banding from an advisory score (strix\n * `_DEP_SEVERITY_FROM_CVSS` :1363-1378, top band inclusive at 10.0).\n * @param score - the advisory base score.\n */\nexport function dependencySeverity(score: number): string {\n if (score === null || score === undefined || Number.isNaN(score)) return 'info'\n const clamped = Math.min(10, Math.max(0, score))\n if (clamped >= 9.0) return 'critical'\n if (clamped >= 7.0) return 'high'\n if (clamped >= 4.0) return 'medium'\n if (clamped >= 0.0) return 'low'\n return 'none'\n}\n","/**\n * Dedupe — port of strix report/dedupe.py decision flow: the deterministic\n * dependency identity fast path (CVE × package × ecosystem, distinct\n * manifests are separate findings, legacy word-bounded mention fallback) and\n * an injectable LLM judge for dynamic findings. Every judge failure defaults\n * to NOT duplicate (strix parity: dedupe failures never block a finding).\n * @module @gpzhang2001/sharpkit-reporting/dedupe\n */\n\nimport type { VulnerabilityReport } from './state.ts'\n\n/** Dependency identity fields (strix `_dependency_identity`). */\nexport interface DependencyIdentity {\n readonly cve: string\n readonly packageName: string\n readonly ecosystem: string\n}\n\n/** The dedupe verdict shape (strix `DuplicateCheckResult`). */\nexport interface DuplicateVerdict {\n readonly isDuplicate: boolean\n readonly duplicateId: string\n readonly confidence: number\n readonly reason: string\n}\n\n/** Pluggable LLM judge (Config-injected; dsh-side LLM wiring lands with M4). */\nexport type DedupeJudge = (candidate: Record<string, unknown>, existing: readonly VulnerabilityReport[]) => Promise<DuplicateVerdict>\n\n/** Extract the dependency identity from metadata (strix :162-177). */\nexport function dependencyIdentity(metadata: unknown): DependencyIdentity | null {\n if (typeof metadata !== 'object' || metadata === null) return null\n const record = metadata as Record<string, unknown>\n const cve = record['cve']\n const packageName = record['package_name']\n const ecosystem = record['package_ecosystem']\n if (typeof cve !== 'string' || cve === '' || typeof packageName !== 'string' || packageName === '' || typeof ecosystem !== 'string' || ecosystem === '') {\n return null\n }\n return { cve: cve.toUpperCase(), packageName: packageName.toLowerCase(), ecosystem: ecosystem.toLowerCase() }\n}\n\n/** Whether two manifest paths are both present AND different (strix `_distinct_manifest_paths`). */\nexport function distinctManifestPaths(a: unknown, b: unknown): boolean {\n const first = typeof a === 'string' && a !== '' ? a : null\n const second = typeof b === 'string' && b !== '' ? b : null\n return first !== null && second !== null && first !== second\n}\n\n/** Word-bounded regex mention check over prose fields (strix `_legacy_report_mentions_package`). */\nexport function legacyReportMentionsPackage(report: VulnerabilityReport, identity: DependencyIdentity): boolean {\n const fields = ['title', 'description', 'impact', 'target', 'technical_analysis', 'poc_description', 'evidence']\n // strix boundaries: [\\w@./-] on both sides break the match (dedupe.py :218-224).\n const packagePattern = new RegExp(`(?<![\\\\w@./-])${escapeRegExp(identity.packageName)}(?![\\\\w@./-])`, 'i')\n const ecosystemPattern = new RegExp(`(?<![\\\\w@./-])${escapeRegExp(identity.ecosystem)}(?![\\\\w@./-])`, 'i')\n for (const field of fields) {\n const value = (report as unknown as Record<string, unknown>)[field]\n if (typeof value !== 'string') continue\n if (packagePattern.test(value) && ecosystemPattern.test(value)) return true\n }\n return false\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\n/**\n * The deterministic dependency fast path (strix `_check_dependency_duplicate`).\n * @param candidateIdentity - the candidate's identity.\n * @param candidateMetadata - the candidate's dependency metadata (manifest comparison).\n * @param existing - current reports.\n * @returns a verdict, or null to defer to the LLM judge.\n */\nexport function checkDependencyDuplicate(\n candidateIdentity: DependencyIdentity,\n candidateMetadata: Record<string, unknown> | undefined,\n existing: readonly VulnerabilityReport[],\n): DuplicateVerdict | null {\n let sawLegacySameCve = false\n for (const report of existing) {\n const metadata = (report as unknown as Record<string, unknown>)['dependency_metadata']\n const identity = dependencyIdentity(metadata)\n if (identity === null) {\n // Legacy report: CVE match + prose mention of the package.\n if (String((report as unknown as Record<string, unknown>)['cve'] ?? '').toUpperCase() === candidateIdentity.cve) {\n sawLegacySameCve = true\n if (legacyReportMentionsPackage(report, candidateIdentity)) {\n return { isDuplicate: true, duplicateId: report.id, confidence: 1.0, reason: 'Same dependency CVE/package identity (legacy report)' }\n }\n }\n continue\n }\n if (identity.cve !== candidateIdentity.cve || identity.packageName !== candidateIdentity.packageName) continue\n const existingMetadata = (report as unknown as Record<string, unknown>)['dependency_metadata'] as Record<string, unknown>\n if (distinctManifestPaths(candidateMetadata?.['manifest_path'], existingMetadata['manifest_path'])) continue\n if (identity.ecosystem === candidateIdentity.ecosystem) {\n return { isDuplicate: true, duplicateId: report.id, confidence: 1.0, reason: 'Same dependency CVE/package identity' }\n }\n return { isDuplicate: true, duplicateId: report.id, confidence: 1.0, reason: 'Same dependency CVE/package identity with missing ecosystem' }\n }\n if (sawLegacySameCve) return null\n return { isDuplicate: false, duplicateId: '', confidence: 1.0, reason: `No existing dependency report for ${candidateIdentity.cve} in ${candidateIdentity.ecosystem}/${candidateIdentity.packageName}` }\n}\n\n/**\n * Entry point (strix `check_duplicate`): fast path for dependency\n * candidates, then the injected judge; every judge failure is NOT duplicate.\n * @param candidate - the candidate fields sent for comparison.\n * @param candidateMetadata - dependency metadata when present.\n * @param existing - current reports.\n * @param judge - the injected LLM judge (absent → not duplicate).\n */\nexport async function checkDuplicate(\n candidate: Record<string, unknown>,\n candidateMetadata: Record<string, unknown> | undefined,\n existing: readonly VulnerabilityReport[],\n judge: DedupeJudge | undefined,\n): Promise<DuplicateVerdict> {\n if (existing.length === 0) {\n return { isDuplicate: false, duplicateId: '', confidence: 1.0, reason: 'No existing reports to compare against' }\n }\n const identity = dependencyIdentity(candidateMetadata)\n if (identity !== null) {\n const fastPath = checkDependencyDuplicate(identity, candidateMetadata, existing)\n if (fastPath !== null) return fastPath\n }\n if (judge === undefined) {\n return { isDuplicate: false, duplicateId: '', confidence: 0.0, reason: 'No dedupe judge is configured; defaulting to not duplicate' }\n }\n try {\n return await judge(candidate, existing)\n } catch (error) {\n return { isDuplicate: false, duplicateId: '', confidence: 0.0, reason: `Deduplication check failed: ${String(error instanceof Error ? error.message : error)}` }\n }\n}\n","/**\n * Report state — port of strix report/state.py: the per-scan report store\n * with sequential `vuln-NNNN` ids, strix's exact field insertion order,\n * title cleaning, update whitelist with dependent-field dropping, update\n * history, and hydration from a previous run dir. Key order matters: the\n * stored dicts are JSON-serialized byte-for-byte into vulnerabilities.json,\n * so fields are inserted in state.py `add_vulnerability_report` order.\n * @module @gpzhang2001/sharpkit-reporting/state\n */\n\n/** A stored vulnerability/dependency report dict (strix shape). */\nexport interface VulnerabilityReport {\n readonly id: string\n title: string\n severity: string\n readonly timestamp: string\n [key: string]: unknown\n}\n\n/** Injectable clock (tests pass fixed times; default wall clock). */\nexport type Clock = () => Date\n\n/** strix display timestamp format (state.py :349). */\nexport function formatTimestamp(date: Date): string {\n const pad = (value: number): string => String(value).padStart(2, '0')\n return `${date.getUTCFullYear()}-${pad(date.getUTCMonth() + 1)}-${pad(date.getUTCDate())} ${pad(date.getUTCHours())}:${pad(date.getUTCMinutes())}:${pad(date.getUTCSeconds())} UTC`\n}\n\n/** strix ISO instant format (start/end times). */\nexport function formatIso(date: Date): string {\n return date.toISOString().replace('Z', '+00:00')\n}\n\n/** Control-char → space + whitespace collapse (state.py `_clean_title`). */\nexport function cleanTitle(title: string): string {\n // eslint-disable-next-line no-control-regex -- strix strips exactly these control chars (state.py :36)\n return title.replace(/[\\u0000-\\u001f\\u007f]+/g, ' ').replace(/\\s+/g, ' ').trim()\n}\n\n/** strix severity order (tool.py `_SEVERITY_ORDER`). */\nexport const SEVERITY_ORDER = ['critical', 'high', 'medium', 'low', 'info', 'none'] as const\n\n/** Severity rank with unknown → last (writer parity). */\nexport function severityRank(severity: string): number {\n const index = (SEVERITY_ORDER as readonly string[]).indexOf(severity)\n return index === -1 ? SEVERITY_ORDER.length : index\n}\n\n/** Field insertion order for optional string fields (state.py :352-396). */\nconst OPTIONAL_STRING_FIELDS = [\n 'description', 'impact', 'target', 'technical_analysis', 'poc_description', 'poc_script_code',\n 'remediation_steps', 'evidence', 'assumptions', 'counterevidence', 'confidence_rationale',\n 'severity_change_conditions', 'fix_verification', 'fix_pr_body', 'endpoint', 'method', 'cve',\n] as const\n\n/** Lowercased optional fields (state.py `_LOWERCASE_REPORT_FIELDS` subset). */\nconst LOWERCASE_FIELDS = new Set(['confidence', 'fix_effort'])\n\n/** Updatable field whitelist (state.py `UPDATABLE_REPORT_FIELDS`). */\nexport const UPDATABLE_REPORT_FIELDS = new Set([\n 'title', 'dependency_metadata', 'severity', 'description', 'impact', 'target', 'technical_analysis',\n 'poc_description', 'poc_script_code', 'remediation_steps', 'evidence', 'assumptions', 'counterevidence',\n 'confidence', 'confidence_rationale', 'severity_change_conditions', 'fix_effort', 'cvss', 'cvss_breakdown',\n 'endpoint', 'method', 'cve', 'cwe', 'code_locations', 'fix_verification', 'fix_pr_body',\n])\n\n/** Dependent fields dropped when their primary changes without replacement. */\nexport const DEPENDENT_REPORT_FIELDS: Readonly<Record<string, string>> = {\n confidence: 'confidence_rationale',\n severity: 'severity_change_conditions',\n cvss: 'cvss_breakdown',\n code_locations: 'fix_verification',\n}\n\n/** One update-history entry (state.py :467-487). */\nexport interface UpdateHistoryEntry {\n readonly timestamp: string\n fields: string[]\n dropped_fields?: string[]\n reason?: string\n agent_id?: string\n agent_name?: string\n previous_severity?: string\n previous_cvss?: number\n previous_confidence?: string\n}\n\nexport interface AddReportInput {\n readonly title: string\n readonly severity: string\n readonly findingClass?: string | undefined\n readonly dependencyMetadata?: Record<string, unknown> | undefined\n readonly agentId?: string | undefined\n readonly agentName?: string | undefined\n /** All remaining report fields (already validated/normalized by the tool layer). */\n readonly fields: Record<string, unknown>\n}\n\n/** The revision outcome: null = no-op (strix parity). */\nexport type UpdateOutcome =\n | { readonly report: VulnerabilityReport }\n | { readonly noop: true }\n\n/**\n * One scan's report store. Not a process singleton — the suite runs one per\n * scan id inside the tool package's closure (strix's module-global maps to a\n * per-scan instance in dsh).\n */\nexport class ReportState {\n readonly runId: string\n runName: string | null\n readonly startTime: string\n endTime: string | null = null\n status = 'running'\n finalScanResult: string | null = null\n readonly vulnerabilityReports: VulnerabilityReport[] = []\n /** Ids already rendered to markdown (incremental writer input). */\n readonly savedVulnIds = new Set<string>()\n updateHistoryAgent: { readonly agentId?: string; readonly agentName?: string } | undefined\n private readonly clock: Clock\n\n constructor(options: { readonly runId?: string; readonly runName?: string | null; readonly clock?: Clock } = {}) {\n this.clock = options.clock ?? (() => new Date())\n this.runId = options.runId ?? `run-${Math.random().toString(16).slice(2, 10)}`\n this.runName = options.runName ?? null\n this.startTime = formatIso(this.clock())\n }\n\n /** Allocate the next sequential id (state.py :343 — length-derived). */\n private nextId(): string {\n return `vuln-${String(this.vulnerabilityReports.length + 1).padStart(4, '0')}`\n }\n\n /**\n * Add one report with strix's exact field construction order.\n * @param input - the validated/normalized create payload.\n */\n addVulnerabilityReport(input: AddReportInput): VulnerabilityReport {\n const report: Record<string, unknown> = {\n id: this.nextId(),\n title: cleanTitle(input.title),\n severity: input.severity.toLowerCase().trim(),\n timestamp: formatTimestamp(this.clock()),\n }\n for (const field of OPTIONAL_STRING_FIELDS) {\n const value = input.fields[field]\n if (typeof value === 'string' && value.trim() !== '') report[field] = value.trim()\n }\n const confidence = input.fields['confidence']\n if (typeof confidence === 'string' && confidence.trim() !== '') report['confidence'] = confidence.trim().toLowerCase()\n const fixEffort = input.fields['fix_effort']\n if (typeof fixEffort === 'string' && fixEffort.trim() !== '') report['fix_effort'] = fixEffort.trim().toLowerCase()\n const cvss = input.fields['cvss']\n if (cvss !== null && cvss !== undefined) report['cvss'] = cvss\n const breakdown = input.fields['cvss_breakdown']\n if (breakdown !== null && breakdown !== undefined && Object.keys(breakdown as object).length > 0) report['cvss_breakdown'] = breakdown\n const cwe = input.fields['cwe']\n if (typeof cwe === 'string' && cwe.trim() !== '') report['cwe'] = cwe.trim()\n const codeLocations = input.fields['code_locations']\n if (codeLocations !== null && codeLocations !== undefined && (codeLocations as unknown[]).length > 0) report['code_locations'] = codeLocations\n report['finding_class'] = (input.findingClass ?? 'dynamic').toLowerCase().trim()\n if (input.dependencyMetadata !== undefined && Object.keys(input.dependencyMetadata).length > 0) report['dependency_metadata'] = input.dependencyMetadata\n if (input.agentId !== undefined && input.agentId !== '') report['agent_id'] = input.agentId\n if (input.agentName !== undefined && input.agentName !== '') report['agent_name'] = input.agentName\n const frozen = report as VulnerabilityReport\n this.vulnerabilityReports.push(frozen)\n return frozen\n }\n\n /**\n * Revise one report in place (state.py `update_vulnerability_report`):\n * whitelist + strip/lowercase, unchanged-skip, dependent-field dropping,\n * history append, and the MD invalidation marker.\n * @param reportId - the `vuln-NNNN` id.\n * @param changes - only the fields the model passed.\n * @param reason - the update_reason (truncated to 500).\n */\n updateVulnerabilityReport(reportId: string, changes: Record<string, unknown>, reason: string): UpdateOutcome {\n const report = this.vulnerabilityReports.find(entry => entry.id === reportId)\n if (report === undefined) return { noop: true }\n const mutable = report as Record<string, unknown>\n const changed: string[] = []\n const dropped: string[] = []\n const history: UpdateHistoryEntry = {\n timestamp: formatTimestamp(this.clock()),\n fields: [],\n reason: reason.slice(0, 500),\n ...(this.updateHistoryAgent?.agentId !== undefined ? { agent_id: this.updateHistoryAgent.agentId } : {}),\n ...(this.updateHistoryAgent?.agentName !== undefined ? { agent_name: this.updateHistoryAgent.agentName } : {}),\n }\n const previous: { severity?: string; cvss?: number; confidence?: string } = {}\n for (const [field, rawValue] of Object.entries(changes)) {\n if (!UPDATABLE_REPORT_FIELDS.has(field)) continue\n let value: unknown = rawValue\n if (field === 'title' && typeof value === 'string') value = cleanTitle(value)\n else if (typeof value === 'string') value = value.trim()\n if (LOWERCASE_FIELDS.has(field) && typeof value === 'string') value = value.toLowerCase()\n if (Object.is(mutable[field], value)) continue\n if (JSON.stringify(mutable[field]) === JSON.stringify(value)) continue\n if (mutable[field] !== undefined) {\n if (field === 'severity') previous.severity = mutable['severity'] as string\n if (field === 'cvss') previous.cvss = mutable['cvss'] as number\n if (field === 'confidence') previous.confidence = mutable['confidence'] as string\n }\n const dependent = DEPENDENT_REPORT_FIELDS[field]\n if (dependent !== undefined && mutable[dependent] !== undefined && changes[dependent] === undefined) {\n delete mutable[dependent]\n dropped.push(dependent)\n }\n mutable[field] = value\n changed.push(field)\n }\n if (changed.length === 0 && dropped.length === 0) return { noop: true }\n history.fields = [...changed].sort()\n if (dropped.length > 0) history.dropped_fields = [...dropped].sort()\n if (previous.severity !== undefined) history.previous_severity = previous.severity\n if (previous.cvss !== undefined) history.previous_cvss = previous.cvss\n if (previous.confidence !== undefined) history.previous_confidence = previous.confidence\n const historyList = (mutable['update_history'] as UpdateHistoryEntry[] | undefined) ?? []\n historyList.push(history)\n mutable['update_history'] = historyList\n mutable['updated_at'] = history.timestamp\n this.savedVulnIds.delete(reportId)\n return { report }\n }\n\n /**\n * Reload from a previous run's vulnerabilities.json so id allocation does\n * not collide (state.py `hydrate_from_run_dir`; raises on corrupt JSON).\n * @param reports - the parsed JSON array.\n */\n hydrate(reports: unknown): void {\n if (!Array.isArray(reports)) throw new Error('corrupt vulnerabilities.json: expected a list of reports')\n for (const entry of reports) {\n const report = entry as Record<string, unknown>\n if (report['finding_class'] === undefined) {\n report['finding_class'] = report['dependency_metadata'] !== undefined ? 'dependency_cve' : 'dynamic'\n }\n if (typeof report['title'] === 'string') report['title'] = cleanTitle(report['title'])\n this.vulnerabilityReports.push(report as VulnerabilityReport)\n if (typeof report['id'] === 'string') this.savedVulnIds.add(report['id'])\n }\n }\n\n /** Mark the run complete (status transition + end time). */\n complete(exitStatus = 'completed'): void {\n this.endTime = formatIso(this.clock())\n this.status = exitStatus\n }\n}\n","/**\n * Artifact writers — port of strix report/writer.py: atomic writes\n * (temp-in-same-dir + rename, no fsync), run.json, vulnerabilities.csv\n * (formula-injection guard, \\r\\n terminators, uppercase severity,\n * severity-then-timestamp ordering), vulnerabilities.json (byte-identical\n * serialization), the vuln-NNNN.md renderer (exact section order), and the\n * executive report template.\n * @module @gpzhang2001/sharpkit-reporting/writers\n */\n\nimport { mkdir, rename, writeFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path'\nimport { SEVERITY_ORDER, severityRank, type VulnerabilityReport } from './state.ts'\n\n/** JSON.stringify with Python `json.dumps(ensure_ascii=False, indent=2)` parity. */\nexport function dumpsIndent(value: unknown): string {\n return JSON.stringify(value, null, 2)\n}\n\n/**\n * Atomic text write (writer.py `atomic_write_text` :201-220): temp file in\n * the target's directory + rename; no fsync (strix parity).\n * @param path - target file path.\n * @param payload - exact bytes to write.\n */\nexport async function atomicWriteText(path: string, payload: string): Promise<void> {\n await mkdir(dirname(path), { recursive: true })\n const temp = `${dirname(path)}/.${join('', basenameOf(path))}.${process.pid}.tmp`\n await writeFile(temp, payload, 'utf8')\n await rename(temp, path)\n}\n\nfunction basenameOf(path: string): string {\n const index = path.lastIndexOf('/')\n return index === -1 ? path : path.slice(index + 1)\n}\n\n/**\n * Formula-injection guard (writer.py `csv_safe` :35-53): prefix `'` when the\n * rendered cell starts with `= + - @ \\t \\r`.\n * @param value - the cell value.\n */\nexport function csvSafe(value: string): string {\n return /^[=+\\-@\\t\\r]/.test(value) ? `'${value}` : value\n}\n\n/** CSV columns (writer.py :165-184). */\nconst CSV_COLUMNS = ['id', 'title', 'severity', 'timestamp', 'file'] as const\n\n/** CSV-escape one cell per RFC 4180 as Python's csv module does. */\nfunction csvCell(value: string): string {\n const safe = csvSafe(value)\n if (safe.includes('\"') || safe.includes(',') || safe.includes('\\r') || safe.includes('\\n')) {\n return `\"${safe.replace(/\"/g, '\"\"')}\"`\n }\n return safe\n}\n\n/**\n * Render vulnerabilities.csv: header + rows sorted by (severity rank,\n * timestamp), uppercase severity, \\r\\n terminators.\n * @param reports - the stored reports.\n */\nexport function renderVulnerabilitiesCsv(reports: readonly VulnerabilityReport[]): string {\n const sorted = [...reports].sort((a, b) =>\n severityRank(String(a.severity)) - severityRank(String(b.severity))\n || String(a.timestamp).localeCompare(String(b.timestamp)),\n )\n const lines = [CSV_COLUMNS.join(',')]\n for (const report of sorted) {\n const cells = [\n csvCell(String(report.id)),\n csvCell(String(report.title)),\n csvCell(String(report.severity).toUpperCase()),\n csvCell(String(report.timestamp)),\n csvCell(`vulnerabilities/${String(report.id)}.md`),\n ]\n lines.push(cells.join(','))\n }\n return `${lines.join('\\r\\n')}\\r\\n`\n}\n\n/** title-case one word (strix Confidence/Fix Effort display). */\nfunction titleCase(value: string): string {\n return value.charAt(0).toUpperCase() + value.slice(1)\n}\n\n/** Safe fence length: one longer than the longest backtick run (writer.py :56-66). */\nfunction safeFence(code: string): string {\n let longest = 0\n let current = 0\n for (const char of code) {\n if (char === '`') {\n current++\n longest = Math.max(longest, current)\n } else {\n current = 0\n }\n }\n return '`'.repeat(Math.max(3, longest + 1))\n}\n\n/** Unwrap an existing fence and return its language (writer.py :69-82). */\nfunction parseFencedCode(code: string): { readonly language: string; readonly body: string } {\n const match = /^```([A-Za-z0-9_+-]*)\\n([\\s\\S]*?)\\n?```$/.exec(code.trim())\n if (match === null) return { language: '', body: code }\n return { language: match[1] ?? '', body: match[2] ?? '' }\n}\n\n/** Guess a fenced language for a PoC script (writer.py :107-116). */\nfunction guessLanguageName(code: string): string {\n if (/^\\s*(import |from |def |class |print\\()/.test(code)) return 'python'\n if (/^\\s*(const |let |var |function |require\\()/.test(code)) return 'javascript'\n if (/^\\s*(curl |GET |POST |PUT |DELETE )/.test(code)) return 'bash'\n return 'python'\n}\n\n/** Metadata lines of the vuln markdown header block (writer.py :222-259 order). */\nfunction renderMetadataLines(report: Record<string, unknown>): string[] {\n const lines: string[] = [`**ID:** ${String(report['id'])}`, `**Severity:** ${String(report['severity']).toUpperCase()}`, `**Found:** ${String(report['timestamp'])}`]\n const depMeta = (report['dependency_metadata'] as Record<string, unknown> | null | undefined) ?? {}\n const cvss = report['cvss']\n const metadata: Array<[string, unknown]> = [\n ['Target', report['target']],\n ['Package', depMeta['package_name']],\n ['Ecosystem', depMeta['package_ecosystem']],\n ['Installed Version', depMeta['installed_version']],\n ['Fixed Version', depMeta['fixed_version']],\n ['Introduced By', depMeta['introduced_by']],\n ['Dependency Chain', depMeta['dependency_path']],\n ['Endpoint', report['endpoint']],\n ['Method', report['method']],\n ['CVE', report['cve']],\n ['CWE', report['cwe']],\n ]\n if (cvss !== null && cvss !== undefined) metadata.push(['CVSS', cvss])\n const advisory = depMeta['advisory_cvss']\n if (advisory !== null && advisory !== undefined && advisory !== cvss) metadata.push(['Advisory CVSS', advisory])\n if (depMeta['contextual_cvss_vector'] !== undefined && depMeta['contextual_cvss_vector'] !== null && depMeta['contextual_cvss_vector'] !== '') {\n metadata.push(['Contextual CVSS Vector', depMeta['contextual_cvss_vector']])\n }\n if (report['confidence'] !== undefined && report['confidence'] !== null && report['confidence'] !== '') {\n metadata.push(['Confidence', titleCase(String(report['confidence']))])\n }\n if (report['fix_effort'] !== undefined && report['fix_effort'] !== null && report['fix_effort'] !== '') {\n metadata.push(['Fix Effort', titleCase(String(report['fix_effort']))])\n }\n for (const [label, value] of metadata) {\n if (value !== null && value !== undefined && value !== '') lines.push(`**${label}:** ${String(value)}`)\n }\n return lines\n}\n\n/** One code-location section (writer.py :315-342, 2-space indents verbatim). */\nfunction renderCodeLocation(location: Record<string, unknown>, index: number): string[] {\n const lines: string[] = ['## Code Analysis', '']\n const file = String(location['file'] ?? 'unknown')\n const start = location['start_line']\n const end = location['end_line']\n let lineLabel = ''\n if (start !== null && start !== undefined) {\n lineLabel = end !== undefined && end !== null && end !== start ? ` (lines ${String(start)}-${String(end)})` : ` (line ${String(start)})`\n }\n lines.push(`**Location ${String(index + 1)}:** \\`${file}\\`${lineLabel}`)\n const label = location['label']\n if (typeof label === 'string' && label !== '') lines.push(` ${label}`)\n const snippet = location['snippet']\n if (typeof snippet === 'string' && snippet !== '') {\n const fence = safeFence(snippet)\n lines.push(` ${fence}`)\n for (const line of snippet.split('\\n')) lines.push(` ${line}`)\n lines.push(` ${fence}`)\n }\n const fixBefore = location['fix_before']\n const fixAfter = location['fix_after']\n if ((typeof fixBefore === 'string' && fixBefore !== '') || (typeof fixAfter === 'string' && fixAfter !== '')) {\n lines.push('')\n lines.push(' **Suggested Fix:**')\n lines.push('```diff')\n if (typeof fixBefore === 'string' && fixBefore !== '') for (const line of fixBefore.split('\\n')) lines.push(`- ${line}`)\n if (typeof fixAfter === 'string' && fixAfter !== '') for (const line of fixAfter.split('\\n')) lines.push(`+ ${line}`)\n lines.push('```')\n }\n lines.push('')\n return lines\n}\n\n/** Update history section (writer.py `render_update_history` :364-396). */\nexport function renderUpdateHistory(report: Record<string, unknown>): string[] {\n const history = report['update_history'] as ReadonlyArray<Record<string, unknown>> | undefined\n if (history === undefined || history.length === 0) return []\n const lines: string[] = ['## Update History', '']\n for (const entry of history) {\n const who = (entry['agent_name'] as string | undefined) ?? (entry['agent_id'] as string | undefined) ?? 'an agent'\n const fields = (entry['fields'] as readonly string[] | undefined)?.join(', ') ?? ''\n lines.push(`**${String(entry['timestamp'])}** — ${who} updated: ${fields}`)\n const dropped = entry['dropped_fields'] as readonly string[] | undefined\n if (dropped !== undefined && dropped.length > 0) lines.push(` Dropped as superseded: ${dropped.join(', ')}`)\n const previousSeverity = entry['previous_severity']\n if (typeof previousSeverity === 'string') lines.push(` Previous severity: ${previousSeverity}`)\n const previousCvss = entry['previous_cvss']\n if (previousCvss !== undefined && previousCvss !== null) lines.push(` Previous CVSS: ${String(previousCvss)}`)\n const previousConfidence = entry['previous_confidence']\n if (typeof previousConfidence === 'string') lines.push(` Previous confidence: ${previousConfidence}`)\n const reason = entry['reason']\n if (typeof reason === 'string' && reason !== '') lines.push(` Reason: ${reason}`)\n lines.push('')\n }\n return lines\n}\n\n/**\n * Render one vulnerability markdown document (writer.py\n * `render_vulnerability_md` :223-361 section order).\n * @param report - the stored report dict.\n */\nexport function renderVulnerabilityMd(report: VulnerabilityReport): string {\n const record = report as unknown as Record<string, unknown>\n const lines: string[] = [`# ${String(record['title'])}`, '']\n lines.push(...renderMetadataLines(record), '')\n\n const section = (heading: string, field: string): void => {\n const value = record[field]\n if (typeof value === 'string' && value !== '') lines.push(`## ${heading}`, '', value, '')\n }\n section('Description', 'description')\n section('Evidence', 'evidence')\n section('Impact', 'impact')\n section('Counterevidence', 'counterevidence')\n section('Confidence Rationale', 'confidence_rationale')\n section('What Would Change This Severity', 'severity_change_conditions')\n section('Technical Analysis', 'technical_analysis')\n\n const metadata = record['dependency_metadata'] as Record<string, unknown> | undefined\n const contextualReasoning = metadata?.['contextual_cvss_reasoning']\n if (typeof contextualReasoning === 'string' && contextualReasoning !== '') {\n lines.push('## Contextual CVSS', '', contextualReasoning, '')\n }\n\n const pocDescription = record['poc_description']\n const pocScript = record['poc_script_code']\n if ((typeof pocDescription === 'string' && pocDescription !== '') || (typeof pocScript === 'string' && pocScript !== '')) {\n lines.push('## Proof of Concept', '')\n if (typeof pocDescription === 'string' && pocDescription !== '') lines.push(pocDescription, '')\n if (typeof pocScript === 'string' && pocScript !== '') {\n const fenced = parseFencedCode(pocScript)\n const language = fenced.language !== '' ? fenced.language : guessLanguageName(fenced.body)\n const fence = safeFence(fenced.body)\n lines.push(`${fence}${language}`, fenced.body, fence, '')\n }\n }\n\n const locations = record['code_locations'] as ReadonlyArray<Record<string, unknown>> | undefined\n if (locations !== undefined && locations.length > 0) {\n for (const [index, location] of locations.entries()) lines.push(...renderCodeLocation(location, index))\n }\n\n section('Remediation', 'remediation_steps')\n section('Fix Verification', 'fix_verification')\n section('Assumptions', 'assumptions')\n lines.push(...renderUpdateHistory(record))\n return lines.join('\\n')\n}\n\n/**\n * Write the per-run artifacts handled outside SARIF (writer.py parity):\n * vulnerabilities/*.md (incremental), vulnerabilities.csv,\n * vulnerabilities.json.\n * @param runDir - the run directory.\n * @param reports - all stored reports.\n * @param savedIds - ids whose MD is already on disk (updated ids must be re-rendered by the caller removing them).\n */\nexport async function writeVulnerabilities(\n runDir: string,\n reports: readonly VulnerabilityReport[],\n savedIds: ReadonlySet<string>,\n): Promise<void> {\n for (const report of reports) {\n if (savedIds.has(report.id)) continue\n await atomicWriteText(join(runDir, 'vulnerabilities', `${report.id}.md`), renderVulnerabilityMd(report))\n }\n await atomicWriteText(join(runDir, 'vulnerabilities.csv'), renderVulnerabilitiesCsv(reports))\n await atomicWriteText(join(runDir, 'vulnerabilities.json'), dumpsIndent(reports))\n}\n\n/**\n * Write the assembled coverage document (coverage.py `write_coverage`).\n * @param runDir - the run directory.\n * @param document - the assembled coverage document.\n */\nexport async function writeCoverage(runDir: string, document: Record<string, unknown>): Promise<void> {\n await atomicWriteText(join(runDir, 'coverage.json'), dumpsIndent(document))\n}\n\n/**\n * Write run.json last (state.py ordering).\n * @param runDir - the run directory.\n * @param runRecord - the run record dict.\n */\nexport async function writeRunRecord(runDir: string, runRecord: Record<string, unknown>): Promise<void> {\n await atomicWriteText(join(runDir, 'run.json'), dumpsIndent(runRecord))\n}\n\n/**\n * Write the executive report (plain truncate-write, writer.py :139-145).\n * @param runDir - the run directory.\n * @param finalScanResult - the composed final report body.\n * @param generatedAt - display timestamp.\n */\nexport async function writeExecutiveReport(runDir: string, finalScanResult: string, generatedAt: string): Promise<void> {\n await mkdir(runDir, { recursive: true })\n await writeFile(join(runDir, 'penetration_test_report.md'), `# Security Penetration Test Report\\n\\n**Generated:** ${generatedAt}\\n\\n${finalScanResult}`, 'utf8')\n}\n\n/** Severity list used by callers that need the canonical order. */\nexport const severityOrder = SEVERITY_ORDER\n","/**\n * SARIF 2.1.0 writer — port of strix report/sarif.py: rule ids normalized\n * CWE→CVE→id→slug, GitHub security-severity, STRIDE tags from the CWE map,\n * physical + synthetic (SECURITY.md anchor) locations with endpoint logical\n * locations, PR-suggestion fixes, deterministic partial fingerprints\n * (sha256), and the strix-namespaced properties (PoC script body never\n * exported). Key insertion order matches Python dict construction\n * byte-for-byte (golden-diff locked).\n * @module @gpzhang2001/sharpkit-reporting/sarif\n */\n\nimport { createHash } from 'node:crypto'\nimport { rename, writeFile, rm } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport { dumpsIndent } from './writers.ts'\nimport type { VulnerabilityReport } from './state.ts'\n\nexport const SARIF_SCHEMA = 'https://json.schemastore.org/sarif-2.1.0.json'\nexport const SARIF_VERSION = '2.1.0'\nexport const TOOL_NAME = 'sharpkit'\nexport const TOOL_INFORMATION_URI = 'https://github.com/gpzhang2001/sharpkit'\nconst SYNTHETIC_LOCATION_URI = 'SECURITY.md'\nconst DEFAULT_STRIDE_LEGS: readonly string[] = ['T', 'I']\n\n/** CWE → STRIDE legs (sarif.py `_CWE_TO_STRIDE`, verbatim). */\nconst CWE_TO_STRIDE: Readonly<Record<string, readonly string[]>> = {\n '287': ['S'], '290': ['S'], '294': ['S'], '306': ['S', 'E'], '345': ['S', 'T'], '346': ['S'],\n '352': ['T', 'S'], '384': ['S'], '521': ['S'], '613': ['S'], '640': ['S'],\n '259': ['S', 'I'], '798': ['S', 'I'], '1391': ['S'],\n '20': ['T'], '73': ['T', 'I'], '78': ['T', 'E'], '79': ['T', 'I'], '89': ['T'], '91': ['T'],\n '94': ['T', 'E'], '434': ['T'], '502': ['T', 'E'], '915': ['E', 'T'], '918': ['T', 'I'], '1336': ['T', 'E'],\n '117': ['R'], '223': ['R'], '778': ['R'],\n '200': ['I'], '201': ['I'], '209': ['I'], '256': ['I'], '311': ['I'], '319': ['I'], '327': ['I'],\n '328': ['I'], '522': ['I'], '525': ['I'], '532': ['I'], '538': ['I'], '598': ['I'],\n '400': ['D'], '770': ['D'], '1333': ['D'],\n '269': ['E'], '284': ['E'], '285': ['E'], '639': ['E'], '732': ['E'], '862': ['E'], '863': ['E'], '1220': ['E'],\n '22': ['T', 'I'], '611': ['I', 'T'],\n}\n\n/** Curated vulnerability-class keywords (sarif.py `_VULN_CLASS_KEYWORDS`). */\nconst VULN_CLASS_KEYWORDS: readonly string[] = [\n 'missing authentication', 'missing authorization', 'broken access control', 'incorrect authorization',\n 'default credentials', 'hardcoded credentials', 'hardcoded secret', 'hardcoded password', 'default admin',\n 'default password', 'session fixation', 'open redirect', 'path traversal', 'directory traversal',\n 'command injection', 'sql injection', 'code injection', 'template injection', 'xpath injection',\n 'ldap injection', 'log injection', 'header injection', 'csv injection', 'prompt injection',\n 'deserialization', 'ssrf', 'xss', 'csrf', 'xxe', 'race condition', 'toctou', 'information disclosure',\n 'insecure direct object reference', 'idor', 'bola', 'bfla', 'cross-tenant', 'cross-project', 'tenant bypass',\n]\n\nconst SEVERITY_TO_LEVEL: Readonly<Record<string, string>> = {\n critical: 'error', high: 'error', medium: 'warning', low: 'note', info: 'note', informational: 'note',\n}\n\nconst SEVERITY_TO_SCORE: Readonly<Record<string, string>> = {\n critical: '9.5', high: '8.0', medium: '5.5', low: '3.0', info: '1.0', informational: '1.0',\n}\n\ntype Json = string | number | boolean | null | Json[] | { [key: string]: Json }\n\nfunction stringValue(value: unknown): string | null {\n if (typeof value === 'string') {\n const stripped = value.trim()\n return stripped === '' ? null : stripped\n }\n return null\n}\n\nfunction sha256(text: string): string {\n return createHash('sha256').update(text, 'utf8').digest('hex')\n}\n\n/** CWE variants (`CWE-89` / `cwe: 89` / `89`) → `CWE-89`. */\nfunction normalizeCwe(value: string): string | null {\n const digits = value.replace(/\\D/g, '')\n return digits === '' ? null : `CWE-${digits}`\n}\n\n/** Stable rule id: CWE → CVE → finding id → slug → sharpkit-finding. */\nexport function ruleIdOf(report: VulnerabilityReport): string {\n const cwe = stringValue(report.cwe)\n if (cwe !== null) {\n const normalized = normalizeCwe(cwe)\n if (normalized !== null) return normalized\n }\n const cve = stringValue(report.cve)\n if (cve !== null) return cve\n const id = stringValue(report.id)\n if (id !== null) return id\n const title = stringValue(report.title)\n return title === null ? 'sharpkit-finding' : slugify(title)\n}\n\n/** Lowercase slug joined by dashes (sarif.py `_slugify`). */\nexport function slugify(value: string): string {\n const chars = [...value.toLowerCase()].map(char => (/[a-z0-9]/.test(char) ? char : '-')).join('')\n const slug = chars.split('-').filter(part => part !== '').join('-')\n return slug === '' ? 'sharpkit-finding' : slug\n}\n\n/** STRIDE legs for a CWE, default legs when unmapped (every finding gets ≥1). */\nexport function strideLegsForCwe(cwe: unknown): readonly string[] {\n if (typeof cwe !== 'string' || cwe === '') return DEFAULT_STRIDE_LEGS\n const digits = cwe.replace(/\\D/g, '')\n if (digits === '') return DEFAULT_STRIDE_LEGS\n return CWE_TO_STRIDE[digits] ?? DEFAULT_STRIDE_LEGS\n}\n\n/** First curated keyword in the title, else the first 5 alphanumeric words. */\nexport function classKeyword(title: string): string {\n const lower = title.toLowerCase()\n for (const keyword of VULN_CLASS_KEYWORDS) {\n if (lower.includes(keyword)) return keyword\n }\n const words = lower.match(/[a-z0-9]+/g)?.slice(0, 5) ?? []\n return words.join(' ')\n}\n\n/** SARIF level mapping. */\nexport function sarifLevel(severity: unknown): string {\n const normalized = (typeof severity === 'string' ? severity : '').toLowerCase()\n return SEVERITY_TO_LEVEL[normalized] ?? 'note'\n}\n\n/** GitHub security-severity: \"%.1f\" CVSS else the label score. */\nexport function securitySeverity(report: VulnerabilityReport): string {\n if (report.cvss !== null && report.cvss !== undefined) {\n const score = Number(report.cvss)\n if (!Number.isNaN(score)) return score.toFixed(1)\n }\n const normalized = (typeof report.severity === 'string' ? report.severity : 'info').toLowerCase()\n return SEVERITY_TO_SCORE[normalized] ?? '1.0'\n}\n\n/** Reject unsafe SARIF artifact URIs; normalize backslashes (sarif.py `_sarif_uri`). */\nexport function sarifUri(file: string): string | null {\n const uri = file.replace(/\\\\/g, '/')\n if (uri.startsWith('/')) return null\n const first = uri.split('/')[0] ?? ''\n if (/^[A-Za-z]:$/.test(first)) return null\n if (uri.split('/').some(part => part === '..')) return null\n return uri\n}\n\n/** Help text: description + impact + remediation joined by blank lines. */\nfunction helpText(report: VulnerabilityReport, fallback: string): string {\n const sections = [report.description, report.impact, report.remediation_steps]\n .filter((value): value is string => typeof value === 'string' && value.trim() !== '')\n return sections.length > 0 ? sections.join('\\n\\n') : fallback\n}\n\ninterface PhysicalLocationInput {\n readonly file: unknown\n readonly start_line: unknown\n readonly end_line?: unknown\n readonly snippet?: unknown\n readonly label?: unknown\n}\n\n/** Validated physical locations + dropped count (sarif.py `_build_physical_locations`). */\nfunction buildPhysicalLocations(rawLocations: unknown): { readonly locations: Json[]; readonly dropped: number } {\n const locations: Json[] = []\n let dropped = 0\n if (!Array.isArray(rawLocations)) return { locations, dropped }\n for (const raw of rawLocations) {\n if (typeof raw !== 'object' || raw === null) continue\n const location = raw as PhysicalLocationInput\n const file = stringValue(location.file)\n const startLine = location.start_line\n if (file === null || typeof startLine !== 'number' || !Number.isInteger(startLine) || startLine < 1) {\n dropped++\n continue\n }\n const uri = sarifUri(file)\n if (uri === null) {\n dropped++\n continue\n }\n const physical: { [key: string]: Json } = {\n artifactLocation: { uri },\n }\n const region: { [key: string]: Json } = { startLine }\n const endLine = location.end_line\n if (typeof endLine === 'number' && Number.isInteger(endLine) && endLine >= startLine) region['endLine'] = endLine\n const snippet = stringValue(location.snippet)\n if (snippet !== null) region['snippet'] = { text: snippet }\n physical['region'] = region\n const entry: { [key: string]: Json } = { physicalLocation: physical }\n const label = stringValue(location.label)\n if (label !== null) entry['message'] = { text: label }\n locations.push(entry)\n }\n return { locations, dropped }\n}\n\n/** Locations with the synthetic anchor and endpoint/resource logical entries. */\nfunction buildLocations(report: VulnerabilityReport): { readonly locations: Json[]; readonly isSynthetic: boolean; readonly dropped: number } {\n const physical = buildPhysicalLocations(report.code_locations)\n const isSynthetic = physical.locations.length === 0\n const locations: Json[] = isSynthetic ? [{ physicalLocation: { artifactLocation: { uri: SYNTHETIC_LOCATION_URI } } }] : [...physical.locations]\n const endpoint = stringValue(report.endpoint)\n if (endpoint !== null) {\n locations.push({ logicalLocations: [{ fullyQualifiedName: endpoint, kind: 'endpoint' }] })\n } else if (isSynthetic) {\n const resource = stringValue(report.target) ?? stringValue(report.title)\n if (resource !== null) locations.push({ logicalLocations: [{ fullyQualifiedName: resource, kind: 'resource' }] })\n }\n return { locations, isSynthetic, dropped: physical.dropped }\n}\n\n/** Deterministic per-finding fingerprint (sarif.py `_primary_fingerprint`). */\nfunction primaryFingerprint(ruleId: string, report: VulnerabilityReport, locations: readonly Json[], isSynthetic: boolean): string | null {\n let uri = ''\n let startLine: number | null = null\n const first = locations.find(location => typeof location === 'object' && location !== null && 'physicalLocation' in location) as { physicalLocation?: { artifactLocation?: { uri?: unknown }; region?: { startLine?: unknown } } } | undefined\n if (first?.physicalLocation !== undefined) {\n uri = typeof first.physicalLocation.artifactLocation?.uri === 'string' ? first.physicalLocation.artifactLocation.uri : ''\n const line = first.physicalLocation.region?.startLine\n if (typeof line === 'number' && Number.isInteger(line) && line >= 1) startLine = line\n }\n const method = stringValue(report.method) ?? ''\n const endpoint = stringValue(report.endpoint) ?? ''\n const route = method !== '' || endpoint !== '' ? `${method.toUpperCase()} ${endpoint}`.trim() : ''\n if (uri === '' && route === '') return null\n const parts: string[] = [`rule:${ruleId}`]\n if (uri !== '') {\n parts.push(`uri:${uri}`)\n if (startLine !== null) parts.push(`line:${String(startLine)}`)\n }\n if (route !== '') parts.push(`route:${route}`)\n if (isSynthetic) {\n const title = stringValue(report.title)\n if (title !== null) parts.push(`synth_class:${classKeyword(title)}`)\n }\n return sha256(parts.join('|'))\n}\n\n/** File-independent class fingerprint (sarif.py `_class_fingerprint`). */\nfunction classFingerprint(ruleId: string, report: VulnerabilityReport): string | null {\n const title = stringValue(report.title)\n if (title === null) return null\n const keyword = classKeyword(title)\n if (keyword === '') return null\n return sha256(`rule:${ruleId}|class:${keyword}`)\n}\n\n/** PR-suggestion fixes from fix-bearing code locations (sarif.py `_build_fixes`). */\nfunction buildFixes(report: VulnerabilityReport): Json[] | null {\n const artifactChanges: Json[] = []\n if (!Array.isArray(report.code_locations)) return null\n for (const raw of report.code_locations) {\n if (typeof raw !== 'object' || raw === null) continue\n const location = raw as Record<string, unknown>\n const file = stringValue(location['file'])\n const fixBefore = stringValue(location['fix_before'])\n const fixAfter = stringValue(location['fix_after'])\n const startLine = location['start_line']\n if (file === null || fixBefore === null || fixAfter === null) continue\n if (typeof startLine !== 'number' || !Number.isInteger(startLine) || startLine < 1) continue\n const uri = sarifUri(file)\n if (uri === null) continue\n const deletedRegion: { [key: string]: Json } = { startLine }\n const endLine = location['end_line']\n if (typeof endLine === 'number' && Number.isInteger(endLine) && endLine >= startLine) deletedRegion['endLine'] = endLine\n artifactChanges.push({\n artifactLocation: { uri },\n replacements: [{ deletedRegion, insertedContent: { text: fixAfter } }],\n })\n }\n if (artifactChanges.length === 0) return null\n const fix: { [key: string]: Json } = { artifactChanges }\n const remediation = stringValue(report.remediation_steps)\n if (remediation !== null) fix['description'] = { text: remediation, markdown: remediation }\n return [fix]\n}\n\n/** Result properties (security-severity, class hash, synthetic flag, strix tree). */\nfunction resultProperties(report: VulnerabilityReport, classFp: string | null, isSynthetic: boolean): { [key: string]: Json } {\n const properties: { [key: string]: Json } = { 'security-severity': securitySeverity(report) }\n if (classFp !== null) properties['sharpkit_vuln_class_hash'] = classFp\n if (isSynthetic) properties['synthetic_location'] = true\n const sharpkitProps: { [key: string]: Json } = {}\n for (const key of [\n 'id', 'severity', 'cvss', 'timestamp', 'target', 'endpoint', 'method', 'cve', 'cwe', 'impact',\n 'technical_analysis', 'remediation_steps', 'counterevidence', 'confidence', 'confidence_rationale',\n 'severity_change_conditions', 'fix_verification',\n ]) {\n const value = (report as unknown as Record<string, unknown>)[key]\n if (value !== null && value !== undefined && value !== '') sharpkitProps[key] = value as Json\n }\n const metadata = (report as unknown as Record<string, unknown>)['dependency_metadata']\n if (typeof metadata === 'object' && metadata !== null && Object.keys(metadata).length > 0) sharpkitProps['dependency_metadata'] = metadata as Json\n const pocDescription = stringValue(report.poc_description)\n const pocScript = stringValue(report.poc_script_code)\n if (pocDescription !== null || pocScript !== null) {\n const poc: { [key: string]: Json } = {}\n if (pocDescription !== null) poc['description'] = pocDescription\n if (pocScript !== null) poc['script_available'] = true\n sharpkitProps['poc'] = poc\n }\n if (Object.keys(sharpkitProps).length > 0) properties['sharpkit'] = sharpkitProps\n return properties\n}\n\n/** Build one rule descriptor (sarif.py `_build_rule` key order). */\nfunction buildRule(ruleId: string, report: VulnerabilityReport): { [key: string]: Json } {\n const title = stringValue(report.title) ?? ruleId\n const fullDescription = stringValue(report.description) ?? title\n const help = helpText(report, fullDescription)\n const rule: { [key: string]: Json } = {\n id: ruleId,\n name: title !== '' ? title : ruleId.replace(/-/g, '_'),\n shortDescription: { text: title },\n fullDescription: { text: fullDescription },\n defaultConfiguration: { level: sarifLevel(report.severity) },\n help: { text: help, markdown: help },\n }\n const properties: { [key: string]: Json } = { 'security-severity': securitySeverity(report) }\n const tags: string[] = ['security']\n if (ruleId.startsWith('CWE-')) tags.push(ruleId)\n const cve = stringValue(report.cve)\n if (cve !== null && !tags.includes(cve)) tags.push(cve)\n for (const leg of strideLegsForCwe(report.cwe)) {\n const tag = `stride:${leg}`\n if (!tags.includes(tag)) tags.push(tag)\n }\n properties['tags'] = tags\n rule['properties'] = properties\n if (ruleId.startsWith('CWE-')) rule['helpUri'] = `https://cwe.mitre.org/data/definitions/${ruleId.slice('CWE-'.length)}.html`\n return rule\n}\n\n/** Build one result (sarif.py `_build_result` key order). */\nfunction buildResult(ruleId: string, ruleIndex: number, report: VulnerabilityReport): { readonly result: { [key: string]: Json }; readonly synthetic: boolean; readonly dropped: number } {\n const title = stringValue(report.title) ?? ruleId\n const description = stringValue(report.description)\n const messageText = description !== null ? `${title}\\n\\n${description}` : title\n const { locations, isSynthetic, dropped } = buildLocations(report)\n const result: { [key: string]: Json } = {\n ruleId,\n ruleIndex,\n level: sarifLevel(report.severity),\n message: { text: messageText },\n }\n if (locations.length > 0) result['locations'] = locations\n const fixes = buildFixes(report)\n if (fixes !== null) result['fixes'] = fixes\n const fingerprint = primaryFingerprint(ruleId, report, locations, isSynthetic)\n if (fingerprint !== null) result['partialFingerprints'] = { primaryLocationLineHash: fingerprint }\n result['properties'] = resultProperties(report, classFingerprint(ruleId, report), isSynthetic)\n return { result, synthetic: isSynthetic, dropped }\n}\n\n/** One coverage entry projected into SARIF (strix coverage.py shape). */\nexport interface SarifCoverageEntry {\n readonly risk_area: string\n readonly surface: string\n readonly outcome: string\n readonly evidence?: unknown\n readonly recorded_by?: unknown\n}\n\n/** The coverage document subset the SARIF bridge consumes. */\nexport interface SarifCoverage {\n readonly entries: readonly SarifCoverageEntry[]\n readonly completeness?: { readonly complete?: boolean; readonly caveats?: readonly string[] } | undefined\n}\n\n/** Coverage outcome → SARIF result kind (`reported` deliberately absent). */\nconst OUTCOME_TO_KIND: Readonly<Record<string, string>> = {\n no_issue_found: 'pass',\n ruled_out: 'pass',\n not_applicable: 'notApplicable',\n needs_follow_up: 'open',\n}\n\nconst OUTCOME_LABELS: Readonly<Record<string, string>> = {\n reported: 'Finding reported',\n no_issue_found: 'No issue identified',\n ruled_out: 'Ruled out',\n not_applicable: 'Not applicable',\n needs_follow_up: 'Requires further review',\n}\n\nexport interface SarifOptions {\n readonly toolVersion: string\n readonly coverage?: SarifCoverage | undefined\n /** Exactly-one-repository provenance (strix passes None in our port for now). */\n readonly repositoryContext?: {\n readonly repositoryUri?: string\n readonly repositoryFullName?: string\n readonly commitSha?: string\n readonly branch?: string\n readonly ref?: string\n } | undefined\n}\n\n/**\n * Build the full SARIF document (top-level key order and run properties).\n * Coverage results and invocations join when the coverage tool lands (批 4).\n * @param reports - all stored reports.\n * @param options - tool version and optional repository provenance.\n */\nexport function buildSarif(reports: readonly VulnerabilityReport[], options: SarifOptions): { [key: string]: Json } {\n const rules: { [key: string]: Json }[] = []\n const ruleIndex = new Map<string, number>()\n const results: Json[] = []\n let syntheticCount = 0\n const droppedFindings: { [key: string]: Json }[] = []\n let droppedLocationCount = 0\n for (const report of reports) {\n const id = ruleIdOf(report)\n let index = ruleIndex.get(id)\n if (index === undefined) {\n index = rules.length\n ruleIndex.set(id, index)\n rules.push(buildRule(id, report))\n }\n const { result, synthetic, dropped } = buildResult(id, index, report)\n if (synthetic) syntheticCount++\n if (dropped > 0) {\n droppedLocationCount += dropped\n droppedFindings.push({ droppedLocationCount: dropped, id: report.id, title: report.title })\n }\n results.push(result)\n }\n const driver: { [key: string]: Json } = {\n name: TOOL_NAME,\n informationUri: TOOL_INFORMATION_URI,\n rules,\n version: options.toolVersion,\n }\n const run: { [key: string]: Json } = { tool: { driver }, results }\n if (options.coverage !== undefined) appendCoverage(run, options.coverage, ruleIndex, rules)\n const runProperties: { [key: string]: Json } = {}\n if (syntheticCount > 0) runProperties['syntheticLocationCount'] = syntheticCount\n if (droppedLocationCount > 0) {\n runProperties['droppedUnsafeLocationCount'] = droppedLocationCount\n runProperties['droppedUnsafeLocationFindings'] = droppedFindings\n }\n const repo = options.repositoryContext\n if (repo !== undefined) {\n const provenance: { [key: string]: Json } = {}\n if (repo.repositoryUri !== undefined) provenance['repositoryUri'] = repo.repositoryUri\n if (repo.commitSha !== undefined) provenance['revisionId'] = repo.commitSha\n if (repo.branch !== undefined) provenance['branch'] = repo.branch\n if (Object.keys(provenance).length > 0) run['versionControlProvenance'] = [provenance]\n if (repo.repositoryFullName !== undefined) runProperties['repository'] = repo.repositoryFullName\n if (repo.ref !== undefined) runProperties['ref'] = repo.ref\n if (repo.commitSha !== undefined) runProperties['commit_sha'] = repo.commitSha\n }\n if (Object.keys(runProperties).length > 0) run['properties'] = runProperties\n return { version: SARIF_VERSION, $schema: SARIF_SCHEMA, runs: [run] }\n}\n\n/** Coverage rule + result builders and the run invocation (sarif.py :641-747). */\nfunction appendCoverage(run: { [key: string]: Json }, coverage: SarifCoverage, ruleIndex: Map<string, number>, rules: { [key: string]: Json }[]): void {\n const coverageResults: Json[] = []\n for (const entry of coverage.entries) {\n const outcome = typeof entry.outcome === 'string' ? entry.outcome : ''\n const kind = OUTCOME_TO_KIND[outcome]\n if (kind === undefined) continue\n const riskArea = typeof entry.risk_area === 'string' ? entry.risk_area : ''\n const ruleId = `sharpkit-coverage/${riskArea === '' ? 'unspecified' : slugify(riskArea)}`\n let index = ruleIndex.get(ruleId)\n if (index === undefined) {\n index = rules.length\n ruleIndex.set(ruleId, index)\n const name = riskArea !== '' ? riskArea : ruleId.replaceAll('-', '_')\n const description = `Coverage: ${riskArea}`\n rules.push({\n id: ruleId,\n name,\n shortDescription: { text: description },\n fullDescription: { text: description },\n defaultConfiguration: { level: 'none' },\n help: { text: description, markdown: description },\n properties: { tags: ['coverage'] },\n })\n }\n const label = OUTCOME_LABELS[outcome] ?? outcome\n const surface = typeof entry.surface === 'string' ? entry.surface : ''\n let messageText = `${riskArea} — ${label}: ${surface}`\n const evidence = typeof entry.evidence === 'string' && entry.evidence !== '' ? entry.evidence : null\n if (evidence !== null) messageText += `\\n\\n${evidence}`\n const sharpkitProps: { [key: string]: Json } = { coverage_outcome: outcome, risk_area: riskArea, surface }\n if (entry.recorded_by !== undefined && entry.recorded_by !== null) sharpkitProps['recorded_by'] = entry.recorded_by as Json\n sharpkitProps['source'] = 'agent_reported'\n coverageResults.push({\n ruleId,\n ruleIndex: index,\n kind,\n level: 'none',\n message: { text: messageText },\n locations: [{ logicalLocations: [{ fullyQualifiedName: surface }] }],\n properties: { sharpkit: sharpkitProps },\n })\n }\n if (coverageResults.length > 0) {\n const existing = run['results']\n run['results'] = [...(Array.isArray(existing) ? existing : []), ...coverageResults]\n }\n const invocation: { [key: string]: Json } = { executionSuccessful: coverage.completeness?.complete ?? true }\n const caveats = coverage.completeness?.caveats?.filter(caveat => caveat !== '')\n if (caveats !== undefined && caveats.length > 0) {\n invocation['toolExecutionNotifications'] = caveats.map(caveat => ({ level: 'warning', message: { text: caveat } }))\n }\n run['invocations'] = [invocation]\n}\n\n/**\n * Write findings.sarif (temp sibling + rename, trailing newline; sarif.py\n * `write_sarif_report`). Always emitted, even with zero findings, so a fresh\n * empty doc overwrites stale results.\n * @param runDir - the run directory.\n * @param reports - all stored reports.\n * @param options - tool version and provenance.\n */\nexport async function writeSarif(runDir: string, reports: readonly VulnerabilityReport[], options: SarifOptions): Promise<void> {\n const output = join(runDir, 'findings.sarif')\n const temp = `${output}.${process.pid}.tmp`\n try {\n await writeFile(temp, `${dumpsIndent(buildSarif(reports, options))}\\n`, 'utf8')\n await rename(temp, output)\n } finally {\n await rm(temp, { force: true }).catch(() => {})\n }\n}\n\n/** Reproduce a fingerprint for tests (exposed for golden diagnostics). */\nexport const internals = { primaryFingerprint, classFingerprint }\n","/**\n * Vulnerability / dependency reporting tools — port of strix\n * tools/reporting/tool.py: create_vulnerability_report,\n * create_dependency_report, update_vulnerability_report, list_reports,\n * get_report. Validation parity (runtime-validated value sets, CVSS\n * computation, cross-class update guards), strix's exact response JSON\n * shapes, and the artifacts fan-out on every mutation (md/csv/json/sarif +\n * run.json last, atomic writes; SARIF always emitted even when empty).\n * The dedupe LLM judge is a Config callback (deterministic dependency fast\n * path runs regardless; judge failures default to not-duplicate).\n * @module @gpzhang2001/sharpkit-reporting\n */\n\nimport { mkdir, readFile } from 'node:fs/promises'\nimport { join, resolve } from 'node:path'\nimport type { Context } from '@deepseek-ai/cordis'\nimport type Schema from '@deepseek-ai/schemastery'\nimport z from '@deepseek-ai/schemastery'\nimport { defineTool } from '@deepseek-ai/dsh-tools'\nimport { calculateCvss, dependencySeverity, validateCvssBreakdown, type CvssMetricName } from './cvss.ts'\nimport { checkDuplicate, type DedupeJudge } from './dedupe.ts'\nimport { ReportState, formatTimestamp, severityRank, type VulnerabilityReport } from './state.ts'\nimport { renderVulnerabilityMd, writeCoverage, writeExecutiveReport, writeRunRecord, writeVulnerabilities } from './writers.ts'\nimport { writeSarif, type SarifCoverage } from './sarif.ts'\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context {\n pentestReporting: ReportingHandle\n }\n}\n\nexport { renderVulnerabilityMd }\nexport { ReportState, cleanTitle, severityRank } from './state.ts'\nexport { calculateCvss, cvssBaseScore, cvssSeverity, validateCvssBreakdown, dependencySeverity, buildCvssVector } from './cvss.ts'\nexport { checkDuplicate, dependencyIdentity } from './dedupe.ts'\nexport { buildSarif, sarifUri, ruleIdOf, classKeyword } from './sarif.ts'\n\n/** Deployment-tunable configuration. */\nexport interface Config {\n /** Run-name slug basis (strix derives it from the target label). */\n readonly runName?: string\n /** Runs root directory (sharpkit_runs; configurable back to strix_runs for legacy compat). */\n readonly runsRoot?: string\n /** Sandbox image version stamped into SARIF (tool.driver.version). */\n readonly toolVersion?: string\n /** Scan mode recorded into run.json. */\n readonly scanMode?: string\n /** Targets recorded into run.json. */\n readonly targetsInfo?: readonly Record<string, unknown>[]\n /** Pluggable dedupe LLM judge (dynamic findings; failures = not duplicate). */\n readonly dedupeJudge?: DedupeJudge\n /** File the CVSS-broad-CWE ban borrows from strix's guidance. */\n readonly strictCwe?: boolean\n /** Coverage document source (the analysis package wires itself in). */\n readonly coverageSource?: CoverageSource\n /** Auth mode recorded into run.json (strix codex.auth_mode; default \"none\"). */\n readonly authMode?: string\n /** Scan instruction recorded into run.json (strix set_scan_config). */\n readonly instruction?: string\n /** Diff scope recorded into run.json (diff-scope scans). */\n readonly diffScope?: string\n /** Non-interactive flag recorded into run.json. */\n readonly nonInteractive?: boolean\n /** Local source trees recorded into run.json. */\n readonly localSources?: readonly Record<string, unknown>[]\n /** Scope mode recorded into run.json (strix default \"auto\"). */\n readonly scopeMode?: string\n /** Diff base ref recorded into run.json (diff-scope scans). */\n readonly diffBase?: string\n /** MCP connection names recorded into run.json (strix record_mcp_connections). */\n readonly mcpConnections?: readonly string[]\n}\n\nexport const name = 'pentest-tool-reporting'\n\nexport const inject = ['tools']\n\nexport const Config: Schema<Config> = z.object({\n runName: z.string(),\n runsRoot: z.string().default('sharpkit_runs'),\n toolVersion: z.string().default('0.1.0'),\n scanMode: z.string().default('quick'),\n targetsInfo: z.array(z.object({})),\n strictCwe: z.boolean().default(true),\n authMode: z.string().default('none'),\n instruction: z.string(),\n diffScope: z.string(),\n nonInteractive: z.boolean(),\n localSources: z.array(z.object({})),\n scopeMode: z.string().default('auto'),\n diffBase: z.string(),\n mcpConnections: z.array(z.string()),\n}) as unknown as Schema<Config>\n\n/** strix-clean an optional string: literal null-words and empties → undefined. */\nfunction cleanOptional(value: string | undefined): string | undefined {\n if (value === undefined) return undefined\n const trimmed = value.trim()\n if (trimmed === '' || /^(null|none|nil|undefined)$/i.test(trimmed)) return undefined\n return trimmed\n}\n\n/** CVSS metric enum value sets (schema-level, matching strix runtime validation). */\nconst CVSS_METRIC_SCHEMAS = {\n attack_vector: { type: 'string' as const, required: true as const, enum: ['N', 'A', 'L', 'P'] } as const,\n attack_complexity: { type: 'string' as const, required: true as const, enum: ['L', 'H'] },\n privileges_required: { type: 'string' as const, required: true as const, enum: ['N', 'L', 'H'] },\n user_interaction: { type: 'string' as const, required: true as const, enum: ['N', 'R'] },\n scope: { type: 'string' as const, required: true as const, enum: ['U', 'C'] },\n confidentiality: { type: 'string' as const, required: true as const, enum: ['N', 'L', 'H'] },\n integrity: { type: 'string' as const, required: true as const, enum: ['N', 'L', 'H'] },\n availability: { type: 'string' as const, required: true as const, enum: ['N', 'L', 'H'] },\n}\n\nconst CODE_LOCATION_SCHEMA = {\n type: 'object' as const,\n properties: {\n file: { type: 'string' as const, required: true as const },\n start_line: { type: 'integer' as const, required: true as const },\n end_line: { type: 'integer' as const, required: true as const },\n snippet: { type: 'string' as const },\n label: { type: 'string' as const },\n fix_before: { type: 'string' as const },\n fix_after: { type: 'string' as const },\n },\n additionalProperties: false,\n} as const\n\n/** Normalize + validate code_locations (tool.py `_normalize_code_locations`). */\nexport function normalizeCodeLocations(raw: unknown): { readonly locations?: Record<string, unknown>[]; readonly errors: string[] } {\n if (!Array.isArray(raw) || raw.length === 0) return { errors: [] }\n const errors: string[] = []\n const locations: Record<string, unknown>[] = []\n for (const [index, item] of raw.entries()) {\n if (typeof item !== 'object' || item === null) continue\n const entry = item as Record<string, unknown>\n const normalized: Record<string, unknown> = {}\n const file = entry['file']\n if (typeof file === 'string' && file !== '') normalized['file'] = file.trim()\n const startLine = entry['start_line']\n if (typeof startLine === 'number' && Number.isInteger(startLine)) normalized['start_line'] = startLine\n else if (typeof startLine === 'string' && startLine !== '' && Number.isInteger(Number(startLine))) normalized['start_line'] = Number(startLine)\n const endLine = entry['end_line']\n if (typeof endLine === 'number' && Number.isInteger(endLine)) normalized['end_line'] = endLine\n else if (typeof endLine === 'string' && endLine !== '' && Number.isInteger(Number(endLine))) normalized['end_line'] = Number(endLine)\n for (const field of ['snippet', 'fix_before', 'fix_after'] as const) {\n const value = entry[field]\n if (typeof value === 'string' && value.trim() !== '') normalized[field] = value.replace(/^\\n+|\\n+$/g, '')\n }\n for (const field of ['label'] as const) {\n const value = entry[field]\n if (typeof value === 'string' && value.trim() !== '') normalized[field] = value.trim()\n }\n if (normalized['file'] === undefined || normalized['start_line'] === undefined) continue\n if (typeof normalized['file'] === 'string' && (normalized['file'] as string).startsWith('/')) {\n errors.push(`code_locations[${String(index)}]: file must be a repo-relative path (no leading '/')`)\n }\n if (typeof normalized['start_line'] !== 'number' || (normalized['start_line'] as number) < 1) {\n errors.push(`code_locations[${String(index)}]: start_line must be an integer >= 1`)\n }\n if (normalized['end_line'] === undefined) {\n errors.push(`code_locations[${String(index)}]: end_line is required`)\n } else {\n const start = normalized['start_line'] as number\n const end = normalized['end_line'] as number\n if (typeof end !== 'number' || end < 1) errors.push(`code_locations[${String(index)}]: end_line must be an integer >= 1`)\n else if (end < start) errors.push(`code_locations[${String(index)}]: end_line (${String(end)}) must be >= start_line (${String(start)})`)\n }\n locations.push(normalized)\n }\n return { ...(locations.length > 0 ? { locations } : {}), errors }\n}\n\n/** CVE normalization (tool.py `_extract_cve` + `_validate_cve`). */\nexport function normalizeCve(value: string | undefined): string | undefined {\n const cleaned = cleanOptional(value)\n if (cleaned === undefined) return undefined\n const match = /CVE-\\d{4}-\\d{4,}/.exec(cleaned)\n if (match === null) return undefined\n return match[0]\n}\n\n/** CWE normalization (tool.py `_extract_cwe`). */\nexport function normalizeCwe(value: string | undefined): string | undefined {\n const cleaned = cleanOptional(value)\n if (cleaned === undefined) return undefined\n const match = /CWE-\\d+/.exec(cleaned)\n if (match === null) return undefined\n return match[0]\n}\n\n/** Dependency metadata builder (tool.py `_build_dependency_metadata` order). */\nexport function buildDependencyMetadata(fields: {\n readonly packageName: string\n readonly installedVersion: string\n readonly advisoryCvss?: number | undefined\n readonly packageEcosystem: string\n readonly manifestPath: string\n readonly fixedVersion?: string | undefined\n readonly introducedBy?: string | undefined\n readonly dependencyPath?: string | undefined\n readonly reachability: string\n readonly reachabilityEvidence?: string | undefined\n readonly contextual?: {\n readonly breakdown: Record<string, string>\n readonly score: number\n readonly vector: string\n readonly reasoning: string\n } | undefined\n}): Record<string, unknown> {\n const metadata: Record<string, unknown> = {\n package_name: fields.packageName,\n installed_version: fields.installedVersion,\n }\n if (fields.advisoryCvss !== undefined) metadata['advisory_cvss'] = fields.advisoryCvss\n metadata['package_ecosystem'] = fields.packageEcosystem\n metadata['manifest_path'] = fields.manifestPath\n if (fields.fixedVersion !== undefined) metadata['fixed_version'] = fields.fixedVersion\n if (fields.introducedBy !== undefined) metadata['introduced_by'] = fields.introducedBy\n if (fields.dependencyPath !== undefined) metadata['dependency_path'] = fields.dependencyPath\n metadata['reachability'] = fields.reachability\n if (fields.reachabilityEvidence !== undefined) metadata['reachability_evidence'] = fields.reachabilityEvidence\n if (fields.contextual !== undefined) {\n metadata['contextual_cvss_breakdown'] = fields.contextual.breakdown\n metadata['contextual_cvss_score'] = fields.contextual.score\n metadata['contextual_cvss_vector'] = fields.contextual.vector\n metadata['contextual_cvss_reasoning'] = fields.contextual.reasoning.slice(0, 2000)\n }\n return metadata\n}\n\n/** Valid severities (strix `_VALID_SEVERITIES`). */\nconst VALID_SEVERITIES = new Set(['critical', 'high', 'medium', 'low', 'info', 'none'])\nconst VALID_FIX_EFFORT = new Set(['trivial', 'low', 'medium', 'high'])\nconst VALID_CONFIDENCE = new Set(['high', 'medium', 'low'])\nconst VALID_FINDING_CLASSES = new Set(['dynamic', 'dependency_cve'])\nconst VALID_REACHABILITY = new Set(['not_imported', 'imported', 'vulnerable_symbol_used', 'reachable_call_path', 'unknown'])\n\n/** Broad CWEs strix's guidance forbids (tool.py docstring; enforced lightly). */\nconst BROADCWES = new Set(['CWE-74', 'CWE-20', 'CWE-200', 'CWE-284', 'CWE-693'])\n\n/** Fields only a dynamic finding may carry on update (strix `_DYNAMIC_ONLY_UPDATE_FIELDS` inverse). */\nconst DEPENDENCY_ONLY_UPDATE_FIELDS = new Set(['contextual_cvss_reasoning'])\nconst DYNAMIC_ONLY_UPDATE_FIELDS = new Set(['endpoint', 'method', 'poc_description', 'poc_script_code'])\n\nexport interface ReportingHandle {\n readonly state: ReportState\n readonly runDir: string\n finishScan(sections: { readonly executiveSummary: string; readonly methodology: string; readonly technicalAnalysis: string; readonly recommendations: string }, status?: string): Promise<void>\n writeNow(): Promise<void>\n readRaw(relative: string): Promise<string>\n}\n\n/** Coverage document provider the analysis package supplies at wiring time. */\nexport interface CoverageSource {\n entries(): Array<Record<string, unknown>>\n outcomeCounts(): Record<string, number>\n}\n\n/**\n * Tool bodies are written with concrete arg/result types and bridged onto\n * the DSL at registration (`as never`); the registry re-validates every\n * call against the declared schema at the boundary.\n */\ntype ToolExecute = (args: never, exec: never) => Promise<never>\n\ninterface ToolRunContextLike {\n readonly signal: AbortSignal\n}\n\ninterface CvssBreakdownArgs extends Record<CvssMetricName, string> {}\n\ninterface CreateVulnArgs {\n title: string\n description: string\n impact: string\n target: string\n technical_analysis: string\n poc_description: string\n poc_script_code: string\n remediation_steps: string\n evidence: string\n assumptions: string\n counterevidence: string\n confidence: string\n confidence_rationale?: string\n severity_change_conditions: string\n fix_effort: string\n cvss_breakdown: CvssBreakdownArgs\n endpoint?: string\n method?: string\n cve?: string\n cwe?: string\n code_locations?: Record<string, unknown>[]\n fix_verification?: string\n fix_pr_body?: string\n}\n\ninterface UpdateArgs {\n report_id: string\n update_reason: string\n title?: string\n description?: string\n impact?: string\n target?: string\n technical_analysis?: string\n poc_description?: string\n poc_script_code?: string\n remediation_steps?: string\n evidence?: string\n assumptions?: string\n counterevidence?: string\n confidence?: string\n confidence_rationale?: string\n severity_change_conditions?: string\n fix_effort?: string\n cvss_breakdown?: CvssBreakdownArgs\n endpoint?: string\n method?: string\n cve?: string\n cwe?: string\n code_locations?: Record<string, unknown>[]\n fix_verification?: string\n fix_pr_body?: string\n contextual_cvss_reasoning?: string\n}\n\ninterface CreateDepArgs {\n title: string\n description: string\n target: string\n cve: string\n package_name: string\n installed_version: string\n advisory_cvss: number\n impact: string\n remediation_steps: string\n assumptions: string\n package_ecosystem: string\n manifest_path?: string\n fixed_version?: string\n cwe?: string\n technical_analysis?: string\n fix_effort?: string\n introduced_by?: string\n dependency_path?: string\n reachability?: string\n reachability_evidence?: string\n contextual_cvss_breakdown?: CvssBreakdownArgs\n contextual_cvss_reasoning?: string\n}\n\ninterface ListArgs {\n severity?: string\n finding_class?: string\n target?: string\n search?: string\n include_details?: boolean\n}\n\ninterface GetArgs {\n report_id: string\n}\n\nexport function apply(ctx: Context, config: Config = {}): ReportingHandle {\n const runsRoot = config.runsRoot ?? 'sharpkit_runs'\n const runName = config.runName ?? `pentest-${Math.random().toString(16).slice(2, 6)}`\n const runDir = resolve(join(resolve(runsRoot), runName))\n const state = new ReportState({ runName })\n const toolVersion = config.toolVersion ?? '0.1.0'\n /** scan_results block, set by finishScan and appended to run.json. */\n let scanResults: Record<string, unknown> | undefined\n\n // llm_usage ledger: session assistant/message usage events are the only\n // host-side token source (dsh emits no cost events). Counts every session\n // in this host process — single-scan deployments are exact; concurrent\n // scans in one host share the ledger (session log stays authoritative).\n const usageLedger = { requests: 0, inputTokens: 0, outputTokens: 0, totalTokens: 0 }\n void ctx.on('session/event', (_session: unknown, event: unknown) => {\n const record = event as { type?: string; data?: { usage?: { inputTokens?: number; outputTokens?: number; totalTokens?: number } } }\n if (record.type !== 'assistant/message') return\n const usage = record.data?.usage\n if (usage === undefined || usage === null) return\n usageLedger.requests += 1\n usageLedger.inputTokens += usage.inputTokens ?? 0\n usageLedger.outputTokens += usage.outputTokens ?? 0\n usageLedger.totalTokens += usage.totalTokens ?? (usage.inputTokens ?? 0) + (usage.outputTokens ?? 0)\n })\n const llmUsageRecord = (): Record<string, unknown> => ({\n requests: usageLedger.requests,\n input_tokens: usageLedger.inputTokens,\n output_tokens: usageLedger.outputTokens,\n total_tokens: usageLedger.totalTokens,\n // dsh session events carry tokens only; cost stays null (parity deviation\n // recorded in the manual — strix estimates cost via LiteLLM callbacks).\n cost: null,\n agents: [],\n })\n\n const ensureRunDir = async (): Promise<string> => {\n await mkdir(runDir, { recursive: true })\n return runDir\n }\n\n /** Resolve the coverage source: Config hook first, else the analysis package's service. */\n const coverageSource = (): CoverageSource | undefined => {\n if (config.coverageSource !== undefined) return config.coverageSource\n const analysis = ctx.get('pentestAnalysis') as\n | { coverageEntries(): Array<Record<string, unknown>>; outcomeCounts(): Record<string, number> }\n | undefined\n return analysis === undefined ? undefined : { entries: () => analysis.coverageEntries(), outcomeCounts: () => analysis.outcomeCounts() }\n }\n\n /** Assemble the coverage document (state.py `_coverage_document`, minus agent-graph gaps). */\n const coverageDocument = (): Record<string, unknown> => {\n const source = coverageSource()\n const entries = source?.entries() ?? []\n const outcomes = source?.outcomeCounts() ?? {}\n return {\n schema_version: 1,\n generated_at: formatTimestamp(new Date()),\n run_id: state.runId,\n run_name: state.runName,\n scope: { targets: config.targetsInfo ?? [], scan_mode: config.scanMode ?? null, scope_mode: null, diff_scope: null, instruction: '' },\n summary: {\n surfaces_reviewed: entries.length,\n outcomes,\n findings_filed: state.vulnerabilityReports.length,\n gaps: entries.filter(entry => entry['outcome'] === 'needs_follow_up').length,\n },\n completeness: { complete: state.status === 'completed', scan_status: state.status, exit_reason: null, caveats: state.status === 'running' ? ['scan still running'] : [] },\n entries: entries.map(entry => ({\n surface: entry['surface'],\n risk_area: entry['risk_area'],\n outcome: entry['outcome'],\n outcome_label: { reported: 'Finding reported', no_issue_found: 'No issue identified', ruled_out: 'Ruled out', not_applicable: 'Not applicable', needs_follow_up: 'Requires further review' }[String(entry['outcome'])] ?? String(entry['outcome']),\n ...(entry['evidence'] !== undefined ? { evidence: entry['evidence'] } : {}),\n recorded_by: entry['agent_name'] ?? null,\n recorded_at: entry['created_at'],\n ...(entry['updated_at'] !== undefined ? { updated_at: entry['updated_at'] } : {}),\n previous_outcomes: (entry['history'] as Array<Record<string, unknown>> | undefined)?.map(item => item['outcome']) ?? [],\n source: 'agent_reported',\n })),\n gaps: entries.filter(entry => entry['outcome'] === 'needs_follow_up').map(entry => ({\n kind: 'needs_follow_up',\n surface: entry['surface'],\n risk_area: entry['risk_area'],\n detail: `'${String(entry['surface'])}' (${String(entry['risk_area'])}) still needs follow-up.`,\n })),\n }\n }\n\n /** Full artifacts fan-out (state.py `_save_artifacts` order; run.json LAST). */\n const saveArtifacts = async (): Promise<void> => {\n try {\n const dir = await ensureRunDir()\n const coverage = coverageDocument()\n await writeCoverage(dir, coverage)\n await writeVulnerabilities(dir, state.vulnerabilityReports, state.savedVulnIds)\n const source = coverageSource()\n const sarifCoverage: SarifCoverage | undefined = source === undefined ? undefined : { entries: coverage['entries'] as unknown as SarifCoverage['entries'], completeness: coverage['completeness'] as unknown as SarifCoverage['completeness'] }\n await writeSarif(dir, state.vulnerabilityReports, { toolVersion, coverage: sarifCoverage })\n // Key order follows strix's run_record construction (state.py :207-216\n // initial fields, :612-631 set_scan_config appends, :560-582 scan_results).\n const runRecord: Record<string, unknown> = {\n run_id: state.runId,\n run_name: state.runName,\n start_time: state.startTime,\n end_time: state.endTime,\n status: state.status,\n auth_mode: config.authMode ?? 'none',\n targets_info: config.targetsInfo ?? [],\n llm_usage: llmUsageRecord(),\n instruction: config.instruction ?? null,\n scan_mode: config.scanMode ?? 'quick',\n diff_scope: config.diffScope ?? null,\n non_interactive: config.nonInteractive ?? false,\n local_sources: config.localSources ?? [],\n scope_mode: config.scopeMode ?? 'auto',\n diff_base: config.diffBase ?? null,\n }\n if (config.mcpConnections !== undefined && config.mcpConnections.length > 0) {\n runRecord['mcp_connections'] = config.mcpConnections\n }\n if (scanResults !== undefined) runRecord['scan_results'] = scanResults\n await writeRunRecord(dir, runRecord)\n } catch (error) {\n // Best-effort persistence surface (strix swallows OSError/RuntimeError)\n // but said out loud: a silent artifact failure hides lost findings.\n ctx.logger.warn(`pentest-reporting: artifact save failed: ${String(error instanceof Error ? error.message : error)}`)\n }\n }\n\n /** The create-side validation + dedupe + persistence shared by both create tools. */\n const persistCreate = async (\n input: { readonly title: string; readonly severity: string; readonly findingClass: string; readonly dependencyMetadata?: Record<string, unknown>; readonly fields: Record<string, unknown> },\n dedupeCandidate: Record<string, unknown>,\n ): Promise<Record<string, unknown>> => {\n const verdict = await checkDuplicate(dedupeCandidate, input.dependencyMetadata, state.vulnerabilityReports, config.dedupeJudge)\n if (verdict.isDuplicate) {\n const existing = state.vulnerabilityReports.find(report => report.id === verdict.duplicateId)\n const title = existing?.title ?? ''\n return {\n success: false,\n error: `Potential duplicate of '${title}' (id=${verdict.duplicateId.slice(0, 8)}...) — do not re-report the same vulnerability`,\n duplicate_of: verdict.duplicateId,\n confidence: verdict.confidence,\n reason: verdict.reason,\n }\n }\n try {\n const report = state.addVulnerabilityReport(input)\n await saveArtifacts()\n return {\n success: true,\n message: `${input.findingClass === 'dependency_cve' ? 'Dependency finding' : 'Vulnerability report'} '${input.title}' created successfully`,\n report_id: report.id,\n severity: report.severity,\n ...(report.cvss !== undefined ? { cvss_score: report.cvss } : {}),\n ...(input.findingClass === 'dependency_cve' && report.cve !== undefined ? { cve: report.cve } : {}),\n }\n } catch (error) {\n return { success: false, error: `Failed to create ${input.findingClass === 'dependency_cve' ? 'dependency' : 'vulnerability'} report: ${String(error instanceof Error ? error.message : error)}` }\n }\n }\n\n ctx.tools.register(defineTool({\n name: 'create_vulnerability_report',\n description: \"File a vulnerability report — one report per fully-verified finding, with a working PoC. Severity and CVSS are computed from the 8-metric cvss_breakdown you provide. On a duplicate verdict, revise the existing report via update_vulnerability_report instead of retrying. Never for known-CVE dependency findings — use create_dependency_report.\",\n parameters: {\n title: { type: 'string', required: true, description: 'Specific finding title (e.g. \"SQL Injection in /api/users login parameter\").' },\n description: { type: 'string', required: true, description: 'Concise, non-technical TL;DR (1-3 sentences).' },\n impact: { type: 'string', required: true, description: 'The unauthorized result demonstrated by the PoC and its scope.' },\n target: { type: 'string', required: true, description: 'Affected URL / domain / repository.' },\n technical_analysis: { type: 'string', required: true, description: 'The mechanism and root cause.' },\n poc_description: { type: 'string', required: true, description: 'Step-by-step reproduction (steps only, no code).' },\n poc_script_code: { type: 'string', required: true, description: 'Working PoC (Python preferred).' },\n remediation_steps: { type: 'string', required: true, description: 'Specific, actionable fix (prose, no code).' },\n evidence: { type: 'string', required: true, description: 'Concrete proof: request/response excerpts, observed behavior, tool output.' },\n assumptions: { type: 'string', required: true, description: 'Assumptions/prerequisites that make this finding impactful.' },\n counterevidence: { type: 'string', required: true, description: 'REQUIRED: the strongest case against this finding, after actively looking for it.' },\n confidence: { type: 'string', required: true, enum: ['high', 'medium', 'low'], description: 'Calibrated confidence.' },\n confidence_rationale: { type: 'string', description: 'Required when confidence is not high: name the specific gap.' },\n severity_change_conditions: { type: 'string', required: true, description: 'One concrete sentence on what evidence would raise or lower severity.' },\n fix_effort: { type: 'string', required: true, enum: ['trivial', 'low', 'medium', 'high'], description: 'Estimated fix effort.' },\n cvss_breakdown: { type: 'object', required: true, properties: CVSS_METRIC_SCHEMAS, additionalProperties: false, description: 'All 8 CVSS v3.1 metrics; score and severity are computed from it.' },\n endpoint: { type: 'string', description: 'API path / Git path (e.g. /api/login).' },\n method: { type: 'string', description: 'HTTP method when relevant.' },\n cve: { type: 'string', description: 'CVE-YYYY-NNNNN if certain, else omit.' },\n cwe: { type: 'string', description: 'CWE-NNN (most specific child) if certain, else omit.' },\n code_locations: { type: 'array', items: CODE_LOCATION_SCHEMA, description: 'White-box findings: file/start_line/end_line/snippet/label/fix_before/fix_after.' },\n fix_verification: { type: 'string', description: 'Required whenever any code_locations entry carries fix_after: the 4 ordered verification gates.' },\n fix_pr_body: { type: 'string', description: 'Optional markdown PR-description body proposing the fix.' },\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean', required: true },\n message: { type: 'string' },\n report_id: { type: 'string' },\n severity: { type: 'string' },\n cvss_score: { type: 'number' },\n error: { type: 'string' },\n errors: { type: 'array', items: { type: 'string' } },\n duplicate_of: { type: 'string' },\n confidence: { type: 'number' },\n reason: { type: 'string' },\n warning: { type: 'string' },\n },\n additionalProperties: false,\n },\n render: (_args, value) => {\n const result = value as { success: boolean; report_id?: string; severity?: string; cvss_score?: number; error?: string }\n if (!result.success) return [{ type: 'text', text: `create_vulnerability_report failed: ${result.error ?? 'unknown'}` }]\n return [{ type: 'text', text: `filed ${result.report_id} (${String(result.severity)}, CVSS ${String(result.cvss_score)})` }]\n },\n presentationMeta: (args: unknown, value: unknown) => findingPresentationMeta(args, value),\n },\n execute: (async (rawArgs: never, rawExec: never) => {\n const args = rawArgs as never as CreateVulnArgs\n const exec = rawExec as never as ToolRunContextLike\n void exec\n const errors: string[] = []\n const breakdown = args.cvss_breakdown as unknown as Record<CvssMetricName, string>\n errors.push(...validateCvssBreakdown(breakdown))\n const confidence = args.confidence.toLowerCase()\n if (!VALID_CONFIDENCE.has(confidence)) errors.push(`Invalid confidence: ${args.confidence}. Must be one of: [high, low, medium]`)\n const fixEffort = args.fix_effort.toLowerCase()\n if (!VALID_FIX_EFFORT.has(fixEffort)) errors.push(`Invalid fix_effort: ${args.fix_effort}. Must be one of: [high, low, medium, trivial]`)\n const cve = normalizeCve(args.cve)\n if (args.cve !== undefined && cve === undefined) errors.push(`Invalid cve: ${args.cve}. Must match CVE-YYYY-NNNNN`)\n const cwe = normalizeCwe(args.cwe)\n if (args.cwe !== undefined && cwe === undefined) errors.push(`Invalid cwe: ${args.cwe}. Must match CWE-NNN`)\n if (cwe !== undefined && config.strictCwe === true && BROADCWES.has(cwe)) errors.push(`${cwe} is too broad — file the most specific child CWE`)\n const locations = normalizeCodeLocations(args.code_locations)\n errors.push(...locations.errors)\n const hasFixAfter = locations.locations?.some(location => typeof location['fix_after'] === 'string' && location['fix_after'] !== '') ?? false\n if (hasFixAfter && cleanOptional(args.fix_verification) === undefined) errors.push('fix_verification is required when any code_locations entry carries fix_after')\n if (args.confidence !== 'high' && cleanOptional(args.confidence_rationale) === undefined) errors.push('confidence_rationale is required when confidence is not high')\n if (errors.length > 0) return { success: false, error: 'Validation failed', errors }\n let cvssScore: number | undefined\n let severity: string | undefined\n try {\n const computed = calculateCvss(breakdown)\n cvssScore = computed.score\n severity = computed.severity\n } catch (error) {\n return { success: false, error: 'Validation failed', errors: [String(error instanceof Error ? error.message : error)] }\n }\n const fields: Record<string, unknown> = {\n description: args.description, impact: args.impact, target: args.target,\n technical_analysis: args.technical_analysis, poc_description: args.poc_description,\n poc_script_code: args.poc_script_code, remediation_steps: args.remediation_steps,\n evidence: args.evidence, assumptions: args.assumptions, counterevidence: args.counterevidence,\n confidence, confidence_rationale: args.confidence_rationale,\n severity_change_conditions: args.severity_change_conditions, fix_effort: fixEffort,\n cvss: cvssScore, cvss_breakdown: breakdown,\n endpoint: args.endpoint, method: args.method, cve, cwe,\n code_locations: locations.locations, fix_verification: args.fix_verification, fix_pr_body: args.fix_pr_body,\n }\n return persistCreate({ title: args.title, severity, findingClass: 'dynamic', fields }, {\n title: args.title, description: args.description, impact: args.impact, target: args.target,\n technical_analysis: args.technical_analysis, poc_description: args.poc_description,\n poc_script_code: args.poc_script_code, endpoint: args.endpoint, method: args.method,\n })\n }) as unknown as ToolExecute,\n }))\n\n ctx.tools.register(defineTool({\n name: 'update_vulnerability_report',\n description: \"Revise a vulnerability report that is already filed, keeping its id. Pass only the fields to replace; create's reporting rules apply. cvss_breakdown replaces the whole vector (score + severity recomputed). Reports keep their id, author, and filing time; the revision is recorded as update history.\",\n parameters: {\n report_id: { type: 'string', required: true, description: 'Id of the report to revise (format vuln-NNNN).' },\n update_reason: { type: 'string', required: true, description: 'What you learned that the report does not yet carry (1-2 sentences).' },\n title: { type: 'string' }, description: { type: 'string' }, impact: { type: 'string' },\n target: { type: 'string' }, technical_analysis: { type: 'string' }, poc_description: { type: 'string' },\n poc_script_code: { type: 'string' }, remediation_steps: { type: 'string' }, evidence: { type: 'string' },\n assumptions: { type: 'string' }, counterevidence: { type: 'string' },\n confidence: { type: 'string', enum: ['high', 'medium', 'low'] },\n confidence_rationale: { type: 'string' }, severity_change_conditions: { type: 'string' },\n fix_effort: { type: 'string', enum: ['trivial', 'low', 'medium', 'high'] },\n cvss_breakdown: { type: 'object', properties: CVSS_METRIC_SCHEMAS, additionalProperties: false },\n endpoint: { type: 'string' }, method: { type: 'string' }, cve: { type: 'string' }, cwe: { type: 'string' },\n code_locations: { type: 'array', items: CODE_LOCATION_SCHEMA },\n fix_verification: { type: 'string' }, fix_pr_body: { type: 'string' },\n contextual_cvss_reasoning: { type: 'string', description: 'Dependency findings only: what you observed in this codebase justifying the contextual cvss_breakdown.' },\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean', required: true },\n action: { type: 'string' },\n message: { type: 'string' },\n report_id: { type: 'string' },\n updated_fields: { type: 'array', items: { type: 'string' } },\n severity: { type: 'string' },\n cvss_score: { type: 'number' },\n error: { type: 'string' },\n errors: { type: 'array', items: { type: 'string' } },\n finding_class: { type: 'string' },\n rejected_fields: { type: 'array', items: { type: 'string' } },\n },\n additionalProperties: false,\n },\n render: (_args, value) => {\n const result = value as { success: boolean; report_id?: string; error?: string }\n if (!result.success) return [{ type: 'text', text: `update_vulnerability_report failed: ${result.error ?? 'unknown'}` }]\n return [{ type: 'text', text: `revised ${result.report_id}` }]\n },\n presentationMeta: (args: unknown, value: unknown) => findingPresentationMeta(args, value),\n },\n execute: (async (rawArgs: never, rawExec: never) => {\n const args = rawArgs as never as UpdateArgs\n const exec = rawExec as never as ToolRunContextLike\n void exec\n const reportId = cleanOptional(args.report_id)\n const reason = cleanOptional(args.update_reason)\n if (reportId === undefined || reason === undefined) {\n return { success: false, error: `${reportId === undefined ? 'report_id' : 'update_reason'} cannot be empty - name the report you are revising and state what you learned that it does not yet carry` }\n }\n const report = state.vulnerabilityReports.find(entry => entry.id === reportId)\n if (report === undefined) return { success: false, error: `Report with id '${reportId}' not found`, report_id: reportId }\n const changes: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(args)) {\n if (key === 'report_id' || key === 'update_reason') continue\n const cleaned = typeof value === 'string' ? cleanOptional(value) : value\n if (cleaned === undefined) continue\n changes[key] = cleaned\n }\n if (Object.keys(changes).length === 0) {\n return { success: false, error: 'No fields to update - pass at least one field you want to replace', report_id: reportId }\n }\n // Cross-class guard (tool.py `_fit_revision_to_class`).\n const findingClass = (typeof report.finding_class === 'string' ? report.finding_class : (report.dependency_metadata !== undefined ? 'dependency_cve' : 'dynamic')) as string\n const rejected: string[] = []\n if (findingClass === 'dependency_cve') {\n for (const field of DYNAMIC_ONLY_UPDATE_FIELDS) {\n if (changes[field] !== undefined) rejected.push(field)\n }\n } else {\n for (const field of DEPENDENCY_ONLY_UPDATE_FIELDS) {\n if (changes[field] !== undefined) rejected.push(field)\n }\n }\n if (rejected.length > 0) {\n return {\n success: false,\n error: `Report '${reportId}' is a ${findingClass} finding, so it cannot carry ${rejected.join(', ')}. File your proof as its own vulnerability report instead of writing it onto this one.`,\n report_id: reportId,\n finding_class: findingClass,\n rejected_fields: rejected,\n }\n }\n // Dependency re-rating: breakdown must carry contextual reasoning.\n if (changes['cvss_breakdown'] !== undefined && findingClass === 'dependency_cve') {\n if (changes['contextual_cvss_reasoning'] === undefined && report.dependency_metadata === undefined) {\n return { success: false, error: 'Validation failed', errors: ['contextual_cvss_reasoning is required when re-rating a dependency finding'], report_id: reportId }\n }\n const errors = validateCvssBreakdown(changes['cvss_breakdown'] as Record<string, unknown>)\n if (errors.length > 0) return { success: false, error: 'Validation failed', errors, report_id: reportId }\n const computed = calculateCvss(changes['cvss_breakdown'] as Record<CvssMetricName, string>)\n changes['cvss'] = computed.score\n changes['severity'] = computed.severity\n } else if (changes['cvss_breakdown'] !== undefined) {\n const errors = validateCvssBreakdown(changes['cvss_breakdown'] as Record<string, unknown>)\n if (errors.length > 0) return { success: false, error: 'Validation failed', errors, report_id: reportId }\n const computed = calculateCvss(changes['cvss_breakdown'] as Record<CvssMetricName, string>)\n changes['cvss'] = computed.score\n changes['severity'] = computed.severity\n }\n const outcome = state.updateVulnerabilityReport(reportId, changes, reason)\n if ('noop' in outcome) {\n return { success: false, error: `Report '${reportId}' already says this - nothing in your update changes it`, report_id: reportId }\n }\n await saveArtifacts()\n const updated = outcome.report\n return {\n success: true,\n action: 'updated',\n message: `Report '${reportId}' now carries your revision. Do not file it again.`,\n report_id: reportId,\n updated_fields: (updated['update_history'] as { fields: string[] }[] | undefined)?.at(-1)?.fields ?? [],\n severity: updated.severity,\n ...(updated.cvss !== undefined ? { cvss_score: updated.cvss as number } : {}),\n }\n }) as unknown as ToolExecute,\n }))\n\n ctx.tools.register(defineTool({\n name: 'create_dependency_report',\n description: \"File a known-CVE dependency (SCA) finding — one report per CVE x package. For vulnerable third-party package versions pinned in a lockfile/manifest/SBOM; no live PoC needed. Severity comes from the contextual_cvss_breakdown when provided, else the advisory score. Never for dynamically-proven vulnerabilities — use create_vulnerability_report.\",\n parameters: {\n title: { type: 'string', required: true, description: 'e.g. \"CVE-2024-1234 in lodash 4.17.20 (prototype pollution)\".' },\n description: { type: 'string', required: true, description: 'What the CVE is and why the pinned version is affected.' },\n target: { type: 'string', required: true, description: 'Affected repository / project / manifest.' },\n cve: { type: 'string', required: true, description: 'CVE-YYYY-NNNNN — required and verified.' },\n package_name: { type: 'string', required: true, description: 'Affected package name (e.g. lodash).' },\n installed_version: { type: 'string', required: true, description: 'The version currently pinned/installed.' },\n advisory_cvss: { type: 'number', required: true, description: 'Published advisory base score (0.0-10.0).' },\n impact: { type: 'string', required: true, description: 'What the CVE enables; business risk in this context.' },\n remediation_steps: { type: 'string', required: true, description: 'How to fix (usually upgrade to a fixed version).' },\n assumptions: { type: 'string', required: true, description: 'Exploitability/reachability assumptions & confidence.' },\n package_ecosystem: { type: 'string', required: true, description: 'e.g. npm / pypi / maven / go.' },\n manifest_path: { type: 'string', description: 'Repo-relative lockfile/manifest path (required).' },\n fixed_version: { type: 'string', description: 'First non-vulnerable version, if known.' },\n cwe: { type: 'string', description: 'CWE-NNN (most specific) if certain.' },\n technical_analysis: { type: 'string', description: 'Optional deeper mechanism/root-cause detail.' },\n fix_effort: { type: 'string', enum: ['trivial', 'low', 'medium', 'high'], description: 'Default low.' },\n introduced_by: { type: 'string', description: 'For a transitive dep, the direct dependency pulling it in (name@version).' },\n dependency_path: { type: 'string', description: 'Resolution chain joined with \" > \".' },\n reachability: { type: 'string', enum: ['not_imported', 'imported', 'vulnerable_symbol_used', 'reachable_call_path', 'unknown'], description: 'Usage-evidence level (default unknown).' },\n reachability_evidence: { type: 'string', description: 'Concrete proof for the level (required).' },\n contextual_cvss_breakdown: { type: 'object', properties: CVSS_METRIC_SCHEMAS, additionalProperties: false, description: 'Full CVSS v3.1 rating of this CVE in this codebase (required).' },\n contextual_cvss_reasoning: { type: 'string', description: '2-4 verifiable sentences with file:line hops (required).' },\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean', required: true },\n message: { type: 'string' },\n report_id: { type: 'string' },\n severity: { type: 'string' },\n cve: { type: 'string' },\n error: { type: 'string' },\n errors: { type: 'array', items: { type: 'string' } },\n duplicate_of: { type: 'string' },\n confidence: { type: 'number' },\n reason: { type: 'string' },\n warning: { type: 'string' },\n },\n additionalProperties: false,\n },\n render: (_args, value) => {\n const result = value as { success: boolean; report_id?: string; severity?: string; cve?: string; error?: string }\n if (!result.success) return [{ type: 'text', text: `create_dependency_report failed: ${result.error ?? 'unknown'}` }]\n return [{ type: 'text', text: `filed ${result.report_id} (${String(result.severity)}) for ${result.cve ?? 'CVE'}` }]\n },\n presentationMeta: (args: unknown, value: unknown) => findingPresentationMeta(args, value),\n },\n execute: (async (rawArgs: never, _rawExec: never) => {\n const args = rawArgs as never as CreateDepArgs\n const errors: string[] = []\n const requireText = (value: string | undefined, name: string): string | undefined => {\n const cleaned = cleanOptional(value)\n if (cleaned === undefined) errors.push(`${name} cannot be empty`)\n return cleaned\n }\n const packageName = requireText(args.package_name, 'package_name')\n const installedVersion = requireText(args.installed_version, 'installed_version')\n const packageEcosystem = requireText(args.package_ecosystem, 'package_ecosystem')\n const manifestPath = requireText(args.manifest_path, 'manifest_path')\n const reachabilityEvidence = requireText(args.reachability_evidence, 'reachability_evidence')\n const contextualReasoning = requireText(args.contextual_cvss_reasoning, 'contextual_cvss_reasoning')\n const cve = normalizeCve(args.cve)\n if (cve === undefined) errors.push(`Invalid cve: ${String(args.cve)}. Must match CVE-YYYY-NNNNN`)\n const cwe = normalizeCwe(args.cwe)\n if (args.cwe !== undefined && cwe === undefined) errors.push(`Invalid cwe: ${args.cwe}. Must match CWE-NNN`)\n const advisory = args.advisory_cvss\n if (typeof advisory !== 'number' || Number.isNaN(advisory) || advisory < 0 || advisory > 10) errors.push(`Invalid advisory_cvss: ${String(advisory)}. Must be between 0.0 and 10.0`)\n const reachability = (args.reachability ?? 'unknown').toLowerCase()\n if (!VALID_REACHABILITY.has(reachability)) errors.push(`Invalid reachability: ${String(args.reachability)}. Must be one of: [imported, not_imported, reachable_call_path, unknown, vulnerable_symbol_used]`)\n const fixEffort = (args.fix_effort ?? 'low').toLowerCase()\n if (!VALID_FIX_EFFORT.has(fixEffort)) errors.push(`Invalid fix_effort: ${String(args.fix_effort)}. Must be one of: [high, low, medium, trivial]`)\n if (manifestPath !== undefined && (manifestPath.startsWith('/') || manifestPath.includes('\\\\') || manifestPath.split('/').some(part => part === '' || part === '.' || part === '..'))) {\n errors.push(`Invalid manifest_path: ${manifestPath}. Must be a repo-relative path without absolute or traversal segments`)\n }\n let contextual: Parameters<typeof buildDependencyMetadata>[0]['contextual'] | undefined\n const hasContextualBreakdown = args.contextual_cvss_breakdown !== undefined\n if (hasContextualBreakdown || contextualReasoning !== undefined) {\n if (!hasContextualBreakdown) errors.push('contextual_cvss_breakdown is required when contextual_cvss_reasoning is given')\n if (contextualReasoning === undefined) errors.push('contextual_cvss_reasoning is required when contextual_cvss_breakdown is given')\n if (hasContextualBreakdown && contextualReasoning !== undefined) {\n const breakdown = args.contextual_cvss_breakdown as unknown as Record<CvssMetricName, string>\n errors.push(...validateCvssBreakdown(breakdown))\n const computed = calculateCvss(breakdown)\n contextual = { breakdown, score: computed.score, vector: computed.vector, reasoning: contextualReasoning }\n }\n }\n if (errors.length > 0) return { success: false, error: 'Validation failed', errors }\n const severity = contextual !== undefined\n ? calculateCvss(contextual.breakdown as CvssBreakdownArgs).severity\n : dependencySeverity(advisory)\n const metadata = buildDependencyMetadata({\n packageName: packageName as string,\n installedVersion: installedVersion as string,\n advisoryCvss: advisory,\n packageEcosystem: packageEcosystem as string,\n manifestPath: manifestPath as string,\n fixedVersion: cleanOptional(args.fixed_version),\n introducedBy: cleanOptional(args.introduced_by),\n dependencyPath: cleanOptional(args.dependency_path),\n reachability,\n reachabilityEvidence,\n contextual,\n })\n const fields: Record<string, unknown> = {\n description: args.description, impact: args.impact, target: args.target,\n technical_analysis: args.technical_analysis, remediation_steps: args.remediation_steps,\n assumptions: args.assumptions, fix_effort: fixEffort,\n cve, cwe,\n cvss: contextual !== undefined ? contextual.score : advisory,\n }\n return persistCreate({ title: args.title, severity, findingClass: 'dependency_cve', dependencyMetadata: metadata, fields }, {\n title: args.title, description: args.description, target: args.target, cve,\n dependency_metadata: metadata, technical_analysis: args.technical_analysis,\n })\n }) as unknown as ToolExecute,\n }))\n\n ctx.tools.register(defineTool({\n name: 'list_reports',\n description: \"List vulnerability reports filed so far in this scan — metadata-first. Read-only and shared across all agents. Filters compose (AND); compact entries by default, full bodies with include_details.\",\n parameters: {\n severity: { type: 'string', enum: ['critical', 'high', 'medium', 'low', 'info', 'none'], description: 'Filter to one severity.' },\n finding_class: { type: 'string', enum: ['dynamic', 'dependency_cve'], description: 'dynamic or dependency_cve.' },\n target: { type: 'string', description: 'Substring match against target/endpoint.' },\n search: { type: 'string', description: 'Substring match against title and description.' },\n include_details: { type: 'boolean', description: 'Full report bodies instead of compact entries (default false).' },\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean', required: true },\n reports: { type: 'array', items: { type: 'object', properties: {}, additionalProperties: true } },\n filtered_count: { type: 'integer', required: true },\n total_count: { type: 'integer', required: true },\n severity_counts: { type: 'object', properties: {}, additionalProperties: true, required: true },\n warning: { type: 'string' },\n error: { type: 'string' },\n },\n additionalProperties: false,\n },\n render: (_args, value) => {\n const result = value as { reports: unknown[]; total_count: number }\n return [{ type: 'text', text: `${String(result.reports.length)} of ${String(result.total_count)} report(s)` }]\n },\n },\n execute: (async (rawArgs: never, rawExec: never) => {\n const args = rawArgs as never as ListArgs\n const exec = rawExec as never as ToolRunContextLike\n void exec\n const severityFilter = cleanOptional(args.severity)?.toLowerCase()\n const classFilter = cleanOptional(args.finding_class)?.toLowerCase()\n const targetFilter = cleanOptional(args.target)?.toLowerCase()\n const searchFilter = cleanOptional(args.search)?.toLowerCase()\n if (severityFilter !== undefined && !VALID_SEVERITIES.has(severityFilter)) {\n return { success: false, reports: [], filtered_count: 0, total_count: 0, severity_counts: {}, error: `Invalid severity: ${severityFilter}. Must be one of: [critical, high, info, low, medium, none]` }\n }\n if (classFilter !== undefined && !VALID_FINDING_CLASSES.has(classFilter)) {\n return { success: false, reports: [], filtered_count: 0, total_count: 0, severity_counts: {}, error: `Invalid finding_class: ${classFilter}. Must be one of: [dependency_cve, dynamic]` }\n }\n const severityCounts: Record<string, number> = {}\n for (const report of state.vulnerabilityReports) {\n const key = String(report.severity)\n severityCounts[key] = (severityCounts[key] ?? 0) + 1\n }\n const filtered = state.vulnerabilityReports.filter(report => {\n if (severityFilter !== undefined && report.severity !== severityFilter) return false\n if (classFilter !== undefined && String(report.finding_class) !== classFilter) return false\n if (targetFilter !== undefined) {\n const target = String(report.target ?? '').toLowerCase()\n const endpoint = String(report.endpoint ?? '').toLowerCase()\n if (!target.includes(targetFilter) && !endpoint.includes(targetFilter)) return false\n }\n if (searchFilter !== undefined) {\n const title = String(report.title ?? '').toLowerCase()\n const description = String(report.description ?? '').toLowerCase()\n if (!title.includes(searchFilter) && !description.includes(searchFilter)) return false\n }\n return true\n })\n filtered.sort((a, b) => severityRank(a.severity) - severityRank(b.severity) || a.id.localeCompare(b.id))\n const entries = filtered.map(report => args.include_details === true ? { ...report as unknown as Record<string, unknown> } : summarize(report))\n return {\n success: true,\n reports: entries,\n filtered_count: filtered.length,\n total_count: state.vulnerabilityReports.length,\n severity_counts: severityCounts,\n }\n }) as unknown as ToolExecute,\n }))\n\n ctx.tools.register(defineTool({\n name: 'get_report',\n description: 'Fetch one vulnerability report by its id (e.g. vuln-0001). Read-only; use list_reports to find ids.',\n parameters: {\n report_id: { type: 'string', required: true, description: \"Report id from list_reports or a create response (format 'vuln-NNNN').\" },\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean', required: true },\n report: { type: 'object', properties: {}, additionalProperties: true },\n error: { type: 'string' },\n },\n additionalProperties: false,\n },\n render: (_args, value) => {\n const result = value as { success: boolean; report?: { id?: string } | null; error?: string }\n if (!result.success) return [{ type: 'text', text: `get_report failed: ${result.error ?? 'unknown'}` }]\n return [{ type: 'text', text: `report ${String(result.report?.id)}` }]\n },\n },\n execute: (async (rawArgs: never, rawExec: never) => {\n const args = rawArgs as never as GetArgs\n const exec = rawExec as never as ToolRunContextLike\n void exec\n const reportId = cleanOptional(args.report_id)\n if (reportId === undefined) return { success: false, error: 'report_id cannot be empty' }\n const report = state.vulnerabilityReports.find(entry => entry.id === reportId)\n if (report === undefined) return { success: false, error: `Report with id '${reportId}' not found` }\n return { success: true, report: { ...report as unknown as Record<string, unknown> } }\n }) as unknown as ToolExecute,\n }))\n\n /** Compact summary entry (tool.py `_to_report_summary_entry` field order). */\n function summarize(report: VulnerabilityReport): Record<string, unknown> {\n const record = report as unknown as Record<string, unknown>\n const summary: Record<string, unknown> = {}\n for (const field of ['id', 'title', 'severity', 'cvss', 'confidence', 'finding_class', 'cve', 'cwe', 'target', 'endpoint', 'method', 'fix_effort', 'agent_name', 'timestamp']) {\n const value = record[field]\n if (value !== null && value !== undefined && value !== '') summary[field] = value\n }\n const description = record['description']\n if (typeof description === 'string' && description !== '') {\n summary['description_preview'] = description.length > 280 ? `${description.slice(0, 280)}...` : description\n }\n return summary\n }\n\n /**\n * Replay-safe toolview meta for finding cards (ui FindingRow consumes\n * severity/report_id/title from `result.meta`). Pure over (args, value);\n * undefined keys are omitted so the snapshot stays lossless JSON.\n */\n function findingPresentationMeta(args: unknown, value: unknown): Record<string, string> {\n const meta: Record<string, string> = {}\n const title = (args as { title?: string }).title\n if (title !== undefined) meta['title'] = title\n const severity = (value as { severity?: string }).severity\n if (severity !== undefined) meta['severity'] = severity\n const reportId = (value as { report_id?: string }).report_id\n if (reportId !== undefined) meta['report_id'] = reportId\n return meta\n }\n\n const composeFinalReport = (sections: { readonly executiveSummary: string; readonly methodology: string; readonly technicalAnalysis: string; readonly recommendations: string }): string =>\n ['# Executive Summary', sections.executiveSummary, '', '# Methodology', sections.methodology, '', '# Technical Analysis', sections.technicalAnalysis, '', '# Recommendations', sections.recommendations].join('\\n')\n\n const handle: ReportingHandle = {\n state,\n runDir,\n /** Mark the scan complete and write the final report + artifacts. */\n async finishScan(sections: { readonly executiveSummary: string; readonly methodology: string; readonly technicalAnalysis: string; readonly recommendations: string }, status = 'completed'): Promise<void> {\n state.finalScanResult = composeFinalReport(sections)\n state.complete(status)\n // strix `update_scan_final_fields` (finish tool → state.py :560-582).\n scanResults = {\n scan_completed: true,\n executive_summary: sections.executiveSummary,\n methodology: sections.methodology,\n technical_analysis: sections.technicalAnalysis,\n recommendations: sections.recommendations,\n success: status === 'completed',\n }\n const dir = await ensureRunDir()\n await writeExecutiveReport(dir, state.finalScanResult, formatTimestamp(new Date()))\n await saveArtifacts()\n },\n /** Dump the current run.json record (golden/test helper). */\n async writeNow(): Promise<void> {\n await saveArtifacts()\n },\n readRaw: async (relative: string): Promise<string> => readFile(join(runDir, relative), 'utf8'),\n }\n ctx.provide('pentestReporting', handle)\n return handle\n}\n\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["normalizeCwe","args"],"sources":["../src/cvss.ts","../src/dedupe.ts","../src/state.ts","../src/writers.ts","../src/sarif.ts","../src/index.ts"],"sourcesContent":["/**\n * CVSS v3.1 base-score math, ported from strix's usage of the `cvss`\n * package (tool.py `_calculate_cvss` :134-153): build the vector string,\n * compute the base score and qualitative severity. The score uses the\n * CVSS 3.1 spec formula with the spec's Roundup1 (ceil to one decimal with\n * the IEEE-754 guard), and a \"none\" base severity is remapped to \"info\"\n * (strix parity).\n * @module @gpzhang2001/sharpkit-reporting/cvss\n */\n\n/** The eight CVSS metrics with their allowed values (strix `_CVSS_VALID`). */\nexport const CVSS_VALID = {\n attack_vector: ['N', 'A', 'L', 'P'],\n attack_complexity: ['L', 'H'],\n privileges_required: ['N', 'L', 'H'],\n user_interaction: ['N', 'R'],\n scope: ['U', 'C'],\n confidentiality: ['N', 'L', 'H'],\n integrity: ['N', 'L', 'H'],\n availability: ['N', 'L', 'H'],\n} as const\n\nexport type CvssMetricName = keyof typeof CVSS_VALID\n\n/** The eight metrics in vector order (strix vector build order). */\nconst METRIC_ORDER: readonly CvssMetricName[] = [\n 'attack_vector', 'attack_complexity', 'privileges_required', 'user_interaction',\n 'scope', 'confidentiality', 'integrity', 'availability',\n]\n\n/** Weight tables (CVSS v3.1 spec §3.1). */\nconst AV: Record<string, number | undefined> = { N: 0.85, A: 0.62, L: 0.55, P: 0.2 }\nconst AC: Record<string, number | undefined> = { L: 0.77, H: 0.44 }\nconst PR_UNCHANGED: Record<string, number | undefined> = { N: 0.85, L: 0.62, H: 0.27 }\nconst PR_CHANGED: Record<string, number | undefined> = { N: 0.85, L: 0.68, H: 0.5 }\nconst UI: Record<string, number | undefined> = { N: 0.85, R: 0.62 }\nconst CIA: Record<string, number | undefined> = { H: 0.56, L: 0.22, N: 0 }\n\n/**\n * CVSS 3.1 Roundup1: smallest one-decimal value >= the input (the `cvss`\n * package quantizes with Decimal ROUND_CEILING; the 5-decimal pre-round\n * absorbs float artifacts the same way the spec intends).\n */\nfunction roundup(value: number): number {\n const quantized = Number(value.toFixed(5))\n return Math.ceil(Number((quantized * 10).toFixed(6))) / 10\n}\n\n/**\n * Validate a breakdown against the allowed metric/value sets.\n * @param breakdown - the model-supplied 8-metric dict.\n * @returns validation errors, empty when valid.\n */\nexport function validateCvssBreakdown(breakdown: Record<string, unknown>): string[] {\n const errors: string[] = []\n if (typeof breakdown !== 'object' || breakdown === null || Object.keys(breakdown).length === 0) {\n return ['cvss_breakdown must be a non-empty object with all 8 metrics']\n }\n for (const metric of METRIC_ORDER) {\n const value = breakdown[metric]\n const allowed = CVSS_VALID[metric]\n if (typeof value !== 'string' || !(allowed as readonly string[]).includes(value)) {\n errors.push(`Invalid ${metric}: ${String(value)}. Must be one of: [${allowed.join(', ')}]`)\n }\n }\n return errors\n}\n\n/**\n * Build the vector string (strix format: CVSS:3.1/AV:../AC:../PR:../UI:../S:../C:../I:../A:..).\n * @param breakdown - a validated breakdown.\n */\nexport function buildCvssVector(breakdown: Readonly<Record<CvssMetricName, string>>): string {\n const parts = METRIC_ORDER.map(metric => {\n const short = { attack_vector: 'AV', attack_complexity: 'AC', privileges_required: 'PR', user_interaction: 'UI', scope: 'S', confidentiality: 'C', integrity: 'I', availability: 'A' }[metric]\n return `${short}:${breakdown[metric]}`\n })\n return `CVSS:3.1/${parts.join('/')}`\n}\n\n/**\n * Compute the CVSS v3.1 base score for a breakdown (the `cvss` package's\n * `compute_base_score`: Scope U ISC = 6.42×ISCBase; Scope C ISC = the 7.52\n * formula; Scope C multiplies the total by 1.08 before the cap).\n * @param breakdown - a validated breakdown.\n * @returns the rounded base score (0.0 when impact is non-positive).\n */\nexport function cvssBaseScore(breakdown: Readonly<Record<CvssMetricName, string>>): number {\n const scopeChanged = breakdown.scope === 'C'\n const c = CIA[breakdown.confidentiality] ?? 0\n const i = CIA[breakdown.integrity] ?? 0\n const a = CIA[breakdown.availability] ?? 0\n const iscBase = 1 - (1 - c) * (1 - i) * (1 - a)\n const isc = scopeChanged\n ? 7.52 * (iscBase - 0.029) - 3.25 * (iscBase - 0.02) ** 15\n : 6.42 * iscBase\n if (isc <= 0) return 0\n const pr = ((scopeChanged ? PR_CHANGED : PR_UNCHANGED)[breakdown.privileges_required]) ?? 0\n const exploitability = 8.22 * (AV[breakdown.attack_vector] ?? 0) * (AC[breakdown.attack_complexity] ?? 0) * pr * (UI[breakdown.user_interaction] ?? 0)\n const raw = scopeChanged ? Math.min(1.08 * (isc + exploitability), 10) : Math.min(isc + exploitability, 10)\n return roundup(raw)\n}\n\n/**\n * Qualitative severity banding (the `cvss` package's rating bands).\n * @param score - the base score.\n */\nexport function cvssSeverity(score: number): 'none' | 'low' | 'medium' | 'high' | 'critical' {\n if (score === 0) return 'none'\n if (score <= 3.9) return 'low'\n if (score <= 6.9) return 'medium'\n if (score <= 8.9) return 'high'\n return 'critical'\n}\n\n/**\n * Full computation: vector + score + severity with the \"none\"→\"info\" remap\n * (strix `_calculate_cvss` return contract).\n * @param breakdown - a validated breakdown.\n */\nexport function calculateCvss(breakdown: Readonly<Record<CvssMetricName, string>>): { readonly vector: string; readonly score: number; readonly severity: string } {\n const vector = buildCvssVector(breakdown)\n const score = cvssBaseScore(breakdown)\n const severity = cvssSeverity(score)\n return { vector, score, severity: severity === 'none' ? 'info' : severity }\n}\n\n/**\n * Dependency severity banding from an advisory score (strix\n * `_DEP_SEVERITY_FROM_CVSS` :1363-1378, top band inclusive at 10.0).\n * @param score - the advisory base score.\n */\nexport function dependencySeverity(score: number): string {\n if (score === null || score === undefined || Number.isNaN(score)) return 'info'\n const clamped = Math.min(10, Math.max(0, score))\n if (clamped >= 9.0) return 'critical'\n if (clamped >= 7.0) return 'high'\n if (clamped >= 4.0) return 'medium'\n if (clamped >= 0.0) return 'low'\n return 'none'\n}\n","/**\n * Dedupe — port of strix report/dedupe.py decision flow: the deterministic\n * dependency identity fast path (CVE × package × ecosystem, distinct\n * manifests are separate findings, legacy word-bounded mention fallback) and\n * an injectable LLM judge for dynamic findings. Every judge failure defaults\n * to NOT duplicate (strix parity: dedupe failures never block a finding).\n * @module @gpzhang2001/sharpkit-reporting/dedupe\n */\n\nimport type { VulnerabilityReport } from './state.ts'\n\n/** Dependency identity fields (strix `_dependency_identity`). */\nexport interface DependencyIdentity {\n readonly cve: string\n readonly packageName: string\n readonly ecosystem: string\n}\n\n/** The dedupe verdict shape (strix `DuplicateCheckResult`). */\nexport interface DuplicateVerdict {\n readonly isDuplicate: boolean\n readonly duplicateId: string\n readonly confidence: number\n readonly reason: string\n}\n\n/** Pluggable LLM judge (Config-injected; dsh-side LLM wiring lands with M4). */\nexport type DedupeJudge = (candidate: Record<string, unknown>, existing: readonly VulnerabilityReport[]) => Promise<DuplicateVerdict>\n\n/** Extract the dependency identity from metadata (strix :162-177). */\nexport function dependencyIdentity(metadata: unknown): DependencyIdentity | null {\n if (typeof metadata !== 'object' || metadata === null) return null\n const record = metadata as Record<string, unknown>\n const cve = record['cve']\n const packageName = record['package_name']\n const ecosystem = record['package_ecosystem']\n if (typeof cve !== 'string' || cve === '' || typeof packageName !== 'string' || packageName === '' || typeof ecosystem !== 'string' || ecosystem === '') {\n return null\n }\n return { cve: cve.toUpperCase(), packageName: packageName.toLowerCase(), ecosystem: ecosystem.toLowerCase() }\n}\n\n/** Whether two manifest paths are both present AND different (strix `_distinct_manifest_paths`). */\nexport function distinctManifestPaths(a: unknown, b: unknown): boolean {\n const first = typeof a === 'string' && a !== '' ? a : null\n const second = typeof b === 'string' && b !== '' ? b : null\n return first !== null && second !== null && first !== second\n}\n\n/** Word-bounded regex mention check over prose fields (strix `_legacy_report_mentions_package`). */\nexport function legacyReportMentionsPackage(report: VulnerabilityReport, identity: DependencyIdentity): boolean {\n const fields = ['title', 'description', 'impact', 'target', 'technical_analysis', 'poc_description', 'evidence']\n // strix boundaries: [\\w@./-] on both sides break the match (dedupe.py :218-224).\n const packagePattern = new RegExp(`(?<![\\\\w@./-])${escapeRegExp(identity.packageName)}(?![\\\\w@./-])`, 'i')\n const ecosystemPattern = new RegExp(`(?<![\\\\w@./-])${escapeRegExp(identity.ecosystem)}(?![\\\\w@./-])`, 'i')\n for (const field of fields) {\n const value = (report as unknown as Record<string, unknown>)[field]\n if (typeof value !== 'string') continue\n if (packagePattern.test(value) && ecosystemPattern.test(value)) return true\n }\n return false\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\n/**\n * The deterministic dependency fast path (strix `_check_dependency_duplicate`).\n * @param candidateIdentity - the candidate's identity.\n * @param candidateMetadata - the candidate's dependency metadata (manifest comparison).\n * @param existing - current reports.\n * @returns a verdict, or null to defer to the LLM judge.\n */\nexport function checkDependencyDuplicate(\n candidateIdentity: DependencyIdentity,\n candidateMetadata: Record<string, unknown> | undefined,\n existing: readonly VulnerabilityReport[],\n): DuplicateVerdict | null {\n let sawLegacySameCve = false\n for (const report of existing) {\n const metadata = (report as unknown as Record<string, unknown>)['dependency_metadata']\n const identity = dependencyIdentity(metadata)\n if (identity === null) {\n // Legacy report: CVE match + prose mention of the package.\n if (String((report as unknown as Record<string, unknown>)['cve'] ?? '').toUpperCase() === candidateIdentity.cve) {\n sawLegacySameCve = true\n if (legacyReportMentionsPackage(report, candidateIdentity)) {\n return { isDuplicate: true, duplicateId: report.id, confidence: 1.0, reason: 'Same dependency CVE/package identity (legacy report)' }\n }\n }\n continue\n }\n if (identity.cve !== candidateIdentity.cve || identity.packageName !== candidateIdentity.packageName) continue\n const existingMetadata = (report as unknown as Record<string, unknown>)['dependency_metadata'] as Record<string, unknown>\n if (distinctManifestPaths(candidateMetadata?.['manifest_path'], existingMetadata['manifest_path'])) continue\n if (identity.ecosystem === candidateIdentity.ecosystem) {\n return { isDuplicate: true, duplicateId: report.id, confidence: 1.0, reason: 'Same dependency CVE/package identity' }\n }\n return { isDuplicate: true, duplicateId: report.id, confidence: 1.0, reason: 'Same dependency CVE/package identity with missing ecosystem' }\n }\n if (sawLegacySameCve) return null\n return { isDuplicate: false, duplicateId: '', confidence: 1.0, reason: `No existing dependency report for ${candidateIdentity.cve} in ${candidateIdentity.ecosystem}/${candidateIdentity.packageName}` }\n}\n\n/**\n * Entry point (strix `check_duplicate`): fast path for dependency\n * candidates, then the injected judge; every judge failure is NOT duplicate.\n * @param candidate - the candidate fields sent for comparison.\n * @param candidateMetadata - dependency metadata when present.\n * @param existing - current reports.\n * @param judge - the injected LLM judge (absent → not duplicate).\n */\nexport async function checkDuplicate(\n candidate: Record<string, unknown>,\n candidateMetadata: Record<string, unknown> | undefined,\n existing: readonly VulnerabilityReport[],\n judge: DedupeJudge | undefined,\n): Promise<DuplicateVerdict> {\n if (existing.length === 0) {\n return { isDuplicate: false, duplicateId: '', confidence: 1.0, reason: 'No existing reports to compare against' }\n }\n const identity = dependencyIdentity(candidateMetadata)\n if (identity !== null) {\n const fastPath = checkDependencyDuplicate(identity, candidateMetadata, existing)\n if (fastPath !== null) return fastPath\n }\n if (judge === undefined) {\n return { isDuplicate: false, duplicateId: '', confidence: 0.0, reason: 'No dedupe judge is configured; defaulting to not duplicate' }\n }\n try {\n return await judge(candidate, existing)\n } catch (error) {\n return { isDuplicate: false, duplicateId: '', confidence: 0.0, reason: `Deduplication check failed: ${String(error instanceof Error ? error.message : error)}` }\n }\n}\n","/**\n * Report state — port of strix report/state.py: the per-scan report store\n * with sequential `vuln-NNNN` ids, strix's exact field insertion order,\n * title cleaning, update whitelist with dependent-field dropping, update\n * history, and hydration from a previous run dir. Key order matters: the\n * stored dicts are JSON-serialized byte-for-byte into vulnerabilities.json,\n * so fields are inserted in state.py `add_vulnerability_report` order.\n * @module @gpzhang2001/sharpkit-reporting/state\n */\n\n/** A stored vulnerability/dependency report dict (strix shape). */\nexport interface VulnerabilityReport {\n readonly id: string\n title: string\n severity: string\n readonly timestamp: string\n [key: string]: unknown\n}\n\n/** Injectable clock (tests pass fixed times; default wall clock). */\nexport type Clock = () => Date\n\n/** strix display timestamp format (state.py :349). */\nexport function formatTimestamp(date: Date): string {\n const pad = (value: number): string => String(value).padStart(2, '0')\n return `${date.getUTCFullYear()}-${pad(date.getUTCMonth() + 1)}-${pad(date.getUTCDate())} ${pad(date.getUTCHours())}:${pad(date.getUTCMinutes())}:${pad(date.getUTCSeconds())} UTC`\n}\n\n/** strix ISO instant format (start/end times). */\nexport function formatIso(date: Date): string {\n return date.toISOString().replace('Z', '+00:00')\n}\n\n/** Control-char → space + whitespace collapse (state.py `_clean_title`). */\nexport function cleanTitle(title: string): string {\n // eslint-disable-next-line no-control-regex -- strix strips exactly these control chars (state.py :36)\n return title.replace(/[\\u0000-\\u001f\\u007f]+/g, ' ').replace(/\\s+/g, ' ').trim()\n}\n\n/** strix severity order (tool.py `_SEVERITY_ORDER`). */\nexport const SEVERITY_ORDER = ['critical', 'high', 'medium', 'low', 'info', 'none'] as const\n\n/** Severity rank with unknown → last (writer parity). */\nexport function severityRank(severity: string): number {\n const index = (SEVERITY_ORDER as readonly string[]).indexOf(severity)\n return index === -1 ? SEVERITY_ORDER.length : index\n}\n\n/** Field insertion order for optional string fields (state.py :352-396). */\nconst OPTIONAL_STRING_FIELDS = [\n 'description', 'impact', 'target', 'technical_analysis', 'poc_description', 'poc_script_code',\n 'remediation_steps', 'evidence', 'assumptions', 'counterevidence', 'confidence_rationale',\n 'severity_change_conditions', 'fix_verification', 'fix_pr_body', 'endpoint', 'method', 'cve',\n] as const\n\n/** Lowercased optional fields (state.py `_LOWERCASE_REPORT_FIELDS` subset). */\nconst LOWERCASE_FIELDS = new Set(['confidence', 'fix_effort'])\n\n/** Updatable field whitelist (state.py `UPDATABLE_REPORT_FIELDS`). */\nexport const UPDATABLE_REPORT_FIELDS = new Set([\n 'title', 'dependency_metadata', 'severity', 'description', 'impact', 'target', 'technical_analysis',\n 'poc_description', 'poc_script_code', 'remediation_steps', 'evidence', 'assumptions', 'counterevidence',\n 'confidence', 'confidence_rationale', 'severity_change_conditions', 'fix_effort', 'cvss', 'cvss_breakdown',\n 'endpoint', 'method', 'cve', 'cwe', 'code_locations', 'fix_verification', 'fix_pr_body',\n])\n\n/** Dependent fields dropped when their primary changes without replacement. */\nexport const DEPENDENT_REPORT_FIELDS: Readonly<Record<string, string>> = {\n confidence: 'confidence_rationale',\n severity: 'severity_change_conditions',\n cvss: 'cvss_breakdown',\n code_locations: 'fix_verification',\n}\n\n/** One update-history entry (state.py :467-487). */\nexport interface UpdateHistoryEntry {\n readonly timestamp: string\n fields: string[]\n dropped_fields?: string[]\n reason?: string\n agent_id?: string\n agent_name?: string\n previous_severity?: string\n previous_cvss?: number\n previous_confidence?: string\n}\n\nexport interface AddReportInput {\n readonly title: string\n readonly severity: string\n readonly findingClass?: string | undefined\n readonly dependencyMetadata?: Record<string, unknown> | undefined\n readonly agentId?: string | undefined\n readonly agentName?: string | undefined\n /** All remaining report fields (already validated/normalized by the tool layer). */\n readonly fields: Record<string, unknown>\n}\n\n/** The revision outcome: null = no-op (strix parity). */\nexport type UpdateOutcome =\n | { readonly report: VulnerabilityReport }\n | { readonly noop: true }\n\n/**\n * One scan's report store. Not a process singleton — the suite runs one per\n * scan id inside the tool package's closure (strix's module-global maps to a\n * per-scan instance in dsh).\n */\nexport class ReportState {\n /** Reseated per resolved run dir (see reseatRunId); NOT per-process — the state is shared for multi-round continuation. */\n runId: string\n runName: string | null\n readonly startTime: string\n endTime: string | null = null\n status = 'running'\n finalScanResult: string | null = null\n readonly vulnerabilityReports: VulnerabilityReport[] = []\n /** Ids already rendered to markdown (incremental writer input). */\n readonly savedVulnIds = new Set<string>()\n updateHistoryAgent: { readonly agentId?: string; readonly agentName?: string } | undefined\n private readonly clock: Clock\n\n constructor(options: { readonly runId?: string; readonly runName?: string | null; readonly clock?: Clock } = {}) {\n this.clock = options.clock ?? (() => new Date())\n this.runId = options.runId ?? `run-${Math.random().toString(16).slice(2, 10)}`\n this.runName = options.runName ?? null\n this.startTime = formatIso(this.clock())\n }\n\n /**\n * Fresh run id for a newly resolved run directory. The state object stays\n * process-shared so a second scan in the same host process CONTINUES the\n * report ledger (multi-round retest mode) — but each run dir must carry its\n * own id: before this, both rounds' run.json showed the same run_id because\n * the id was minted once per process (2026-09-22).\n */\n reseatRunId(): void {\n this.runId = `run-${Math.random().toString(16).slice(2, 10)}`\n }\n\n /** Allocate the next sequential id (state.py :343 — length-derived). */\n private nextId(): string {\n return `vuln-${String(this.vulnerabilityReports.length + 1).padStart(4, '0')}`\n }\n\n /**\n * Add one report with strix's exact field construction order.\n * @param input - the validated/normalized create payload.\n */\n addVulnerabilityReport(input: AddReportInput): VulnerabilityReport {\n const report: Record<string, unknown> = {\n id: this.nextId(),\n title: cleanTitle(input.title),\n severity: input.severity.toLowerCase().trim(),\n timestamp: formatTimestamp(this.clock()),\n }\n for (const field of OPTIONAL_STRING_FIELDS) {\n const value = input.fields[field]\n if (typeof value === 'string' && value.trim() !== '') report[field] = value.trim()\n }\n const confidence = input.fields['confidence']\n if (typeof confidence === 'string' && confidence.trim() !== '') report['confidence'] = confidence.trim().toLowerCase()\n const fixEffort = input.fields['fix_effort']\n if (typeof fixEffort === 'string' && fixEffort.trim() !== '') report['fix_effort'] = fixEffort.trim().toLowerCase()\n const cvss = input.fields['cvss']\n if (cvss !== null && cvss !== undefined) report['cvss'] = cvss\n const breakdown = input.fields['cvss_breakdown']\n if (breakdown !== null && breakdown !== undefined && Object.keys(breakdown as object).length > 0) report['cvss_breakdown'] = breakdown\n const cwe = input.fields['cwe']\n if (typeof cwe === 'string' && cwe.trim() !== '') report['cwe'] = cwe.trim()\n const codeLocations = input.fields['code_locations']\n if (codeLocations !== null && codeLocations !== undefined && (codeLocations as unknown[]).length > 0) report['code_locations'] = codeLocations\n report['finding_class'] = (input.findingClass ?? 'dynamic').toLowerCase().trim()\n if (input.dependencyMetadata !== undefined && Object.keys(input.dependencyMetadata).length > 0) report['dependency_metadata'] = input.dependencyMetadata\n if (input.agentId !== undefined && input.agentId !== '') report['agent_id'] = input.agentId\n if (input.agentName !== undefined && input.agentName !== '') report['agent_name'] = input.agentName\n const frozen = report as VulnerabilityReport\n this.vulnerabilityReports.push(frozen)\n return frozen\n }\n\n /**\n * Revise one report in place (state.py `update_vulnerability_report`):\n * whitelist + strip/lowercase, unchanged-skip, dependent-field dropping,\n * history append, and the MD invalidation marker.\n * @param reportId - the `vuln-NNNN` id.\n * @param changes - only the fields the model passed.\n * @param reason - the update_reason (truncated to 500).\n */\n updateVulnerabilityReport(reportId: string, changes: Record<string, unknown>, reason: string): UpdateOutcome {\n const report = this.vulnerabilityReports.find(entry => entry.id === reportId)\n if (report === undefined) return { noop: true }\n const mutable = report as Record<string, unknown>\n const changed: string[] = []\n const dropped: string[] = []\n const history: UpdateHistoryEntry = {\n timestamp: formatTimestamp(this.clock()),\n fields: [],\n reason: reason.slice(0, 500),\n ...(this.updateHistoryAgent?.agentId !== undefined ? { agent_id: this.updateHistoryAgent.agentId } : {}),\n ...(this.updateHistoryAgent?.agentName !== undefined ? { agent_name: this.updateHistoryAgent.agentName } : {}),\n }\n const previous: { severity?: string; cvss?: number; confidence?: string } = {}\n for (const [field, rawValue] of Object.entries(changes)) {\n if (!UPDATABLE_REPORT_FIELDS.has(field)) continue\n let value: unknown = rawValue\n if (field === 'title' && typeof value === 'string') value = cleanTitle(value)\n else if (typeof value === 'string') value = value.trim()\n if (LOWERCASE_FIELDS.has(field) && typeof value === 'string') value = value.toLowerCase()\n if (Object.is(mutable[field], value)) continue\n if (JSON.stringify(mutable[field]) === JSON.stringify(value)) continue\n if (mutable[field] !== undefined) {\n if (field === 'severity') previous.severity = mutable['severity'] as string\n if (field === 'cvss') previous.cvss = mutable['cvss'] as number\n if (field === 'confidence') previous.confidence = mutable['confidence'] as string\n }\n const dependent = DEPENDENT_REPORT_FIELDS[field]\n if (dependent !== undefined && mutable[dependent] !== undefined && changes[dependent] === undefined) {\n delete mutable[dependent]\n dropped.push(dependent)\n }\n mutable[field] = value\n changed.push(field)\n }\n if (changed.length === 0 && dropped.length === 0) return { noop: true }\n history.fields = [...changed].sort()\n if (dropped.length > 0) history.dropped_fields = [...dropped].sort()\n if (previous.severity !== undefined) history.previous_severity = previous.severity\n if (previous.cvss !== undefined) history.previous_cvss = previous.cvss\n if (previous.confidence !== undefined) history.previous_confidence = previous.confidence\n const historyList = (mutable['update_history'] as UpdateHistoryEntry[] | undefined) ?? []\n historyList.push(history)\n mutable['update_history'] = historyList\n mutable['updated_at'] = history.timestamp\n this.savedVulnIds.delete(reportId)\n return { report }\n }\n\n /**\n * Reload from a previous run's vulnerabilities.json so id allocation does\n * not collide (state.py `hydrate_from_run_dir`; raises on corrupt JSON).\n * @param reports - the parsed JSON array.\n */\n hydrate(reports: unknown): void {\n if (!Array.isArray(reports)) throw new Error('corrupt vulnerabilities.json: expected a list of reports')\n for (const entry of reports) {\n const report = entry as Record<string, unknown>\n if (report['finding_class'] === undefined) {\n report['finding_class'] = report['dependency_metadata'] !== undefined ? 'dependency_cve' : 'dynamic'\n }\n if (typeof report['title'] === 'string') report['title'] = cleanTitle(report['title'])\n this.vulnerabilityReports.push(report as VulnerabilityReport)\n if (typeof report['id'] === 'string') this.savedVulnIds.add(report['id'])\n }\n }\n\n /** Mark the run complete (status transition + end time). */\n complete(exitStatus = 'completed'): void {\n this.endTime = formatIso(this.clock())\n this.status = exitStatus\n }\n}\n","/**\n * Artifact writers — port of strix report/writer.py: atomic writes\n * (temp-in-same-dir + rename, no fsync), run.json, vulnerabilities.csv\n * (formula-injection guard, \\r\\n terminators, uppercase severity,\n * severity-then-timestamp ordering), vulnerabilities.json (byte-identical\n * serialization), the vuln-NNNN.md renderer (exact section order), and the\n * executive report template.\n * @module @gpzhang2001/sharpkit-reporting/writers\n */\n\nimport { mkdir, rename, writeFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path'\nimport { SEVERITY_ORDER, severityRank, type VulnerabilityReport } from './state.ts'\n\n/** JSON.stringify with Python `json.dumps(ensure_ascii=False, indent=2)` parity. */\nexport function dumpsIndent(value: unknown): string {\n return JSON.stringify(value, null, 2)\n}\n\n/**\n * Atomic text write (writer.py `atomic_write_text` :201-220): temp file in\n * the target's directory + rename; no fsync (strix parity).\n * @param path - target file path.\n * @param payload - exact bytes to write.\n */\nexport async function atomicWriteText(path: string, payload: string): Promise<void> {\n await mkdir(dirname(path), { recursive: true })\n const temp = `${dirname(path)}/.${join('', basenameOf(path))}.${process.pid}.tmp`\n await writeFile(temp, payload, 'utf8')\n await rename(temp, path)\n}\n\nfunction basenameOf(path: string): string {\n const index = path.lastIndexOf('/')\n return index === -1 ? path : path.slice(index + 1)\n}\n\n/**\n * Formula-injection guard (writer.py `csv_safe` :35-53): prefix `'` when the\n * rendered cell starts with `= + - @ \\t \\r`.\n * @param value - the cell value.\n */\nexport function csvSafe(value: string): string {\n return /^[=+\\-@\\t\\r]/.test(value) ? `'${value}` : value\n}\n\n/** CSV columns (writer.py :165-184). */\nconst CSV_COLUMNS = ['id', 'title', 'severity', 'timestamp', 'file'] as const\n\n/** CSV-escape one cell per RFC 4180 as Python's csv module does. */\nfunction csvCell(value: string): string {\n const safe = csvSafe(value)\n if (safe.includes('\"') || safe.includes(',') || safe.includes('\\r') || safe.includes('\\n')) {\n return `\"${safe.replace(/\"/g, '\"\"')}\"`\n }\n return safe\n}\n\n/**\n * Render vulnerabilities.csv: header + rows sorted by (severity rank,\n * timestamp), uppercase severity, \\r\\n terminators.\n * @param reports - the stored reports.\n */\nexport function renderVulnerabilitiesCsv(reports: readonly VulnerabilityReport[]): string {\n const sorted = [...reports].sort((a, b) =>\n severityRank(String(a.severity)) - severityRank(String(b.severity))\n || String(a.timestamp).localeCompare(String(b.timestamp)),\n )\n const lines = [CSV_COLUMNS.join(',')]\n for (const report of sorted) {\n const cells = [\n csvCell(String(report.id)),\n csvCell(String(report.title)),\n csvCell(String(report.severity).toUpperCase()),\n csvCell(String(report.timestamp)),\n csvCell(`vulnerabilities/${String(report.id)}.md`),\n ]\n lines.push(cells.join(','))\n }\n return `${lines.join('\\r\\n')}\\r\\n`\n}\n\n/** title-case one word (strix Confidence/Fix Effort display). */\nfunction titleCase(value: string): string {\n return value.charAt(0).toUpperCase() + value.slice(1)\n}\n\n/** Safe fence length: one longer than the longest backtick run (writer.py :56-66). */\nfunction safeFence(code: string): string {\n let longest = 0\n let current = 0\n for (const char of code) {\n if (char === '`') {\n current++\n longest = Math.max(longest, current)\n } else {\n current = 0\n }\n }\n return '`'.repeat(Math.max(3, longest + 1))\n}\n\n/** Unwrap an existing fence and return its language (writer.py :69-82). */\nfunction parseFencedCode(code: string): { readonly language: string; readonly body: string } {\n const match = /^```([A-Za-z0-9_+-]*)\\n([\\s\\S]*?)\\n?```$/.exec(code.trim())\n if (match === null) return { language: '', body: code }\n return { language: match[1] ?? '', body: match[2] ?? '' }\n}\n\n/** Guess a fenced language for a PoC script (writer.py :107-116). */\nfunction guessLanguageName(code: string): string {\n if (/^\\s*(import |from |def |class |print\\()/.test(code)) return 'python'\n if (/^\\s*(const |let |var |function |require\\()/.test(code)) return 'javascript'\n if (/^\\s*(curl |GET |POST |PUT |DELETE )/.test(code)) return 'bash'\n return 'python'\n}\n\n/** Metadata lines of the vuln markdown header block (writer.py :222-259 order). */\nfunction renderMetadataLines(report: Record<string, unknown>): string[] {\n const lines: string[] = [`**ID:** ${String(report['id'])}`, `**Severity:** ${String(report['severity']).toUpperCase()}`, `**Found:** ${String(report['timestamp'])}`]\n const depMeta = (report['dependency_metadata'] as Record<string, unknown> | null | undefined) ?? {}\n const cvss = report['cvss']\n const metadata: Array<[string, unknown]> = [\n ['Target', report['target']],\n ['Package', depMeta['package_name']],\n ['Ecosystem', depMeta['package_ecosystem']],\n ['Installed Version', depMeta['installed_version']],\n ['Fixed Version', depMeta['fixed_version']],\n ['Introduced By', depMeta['introduced_by']],\n ['Dependency Chain', depMeta['dependency_path']],\n ['Endpoint', report['endpoint']],\n ['Method', report['method']],\n ['CVE', report['cve']],\n ['CWE', report['cwe']],\n ]\n if (cvss !== null && cvss !== undefined) metadata.push(['CVSS', cvss])\n const advisory = depMeta['advisory_cvss']\n if (advisory !== null && advisory !== undefined && advisory !== cvss) metadata.push(['Advisory CVSS', advisory])\n if (depMeta['contextual_cvss_vector'] !== undefined && depMeta['contextual_cvss_vector'] !== null && depMeta['contextual_cvss_vector'] !== '') {\n metadata.push(['Contextual CVSS Vector', depMeta['contextual_cvss_vector']])\n }\n if (report['confidence'] !== undefined && report['confidence'] !== null && report['confidence'] !== '') {\n metadata.push(['Confidence', titleCase(String(report['confidence']))])\n }\n if (report['fix_effort'] !== undefined && report['fix_effort'] !== null && report['fix_effort'] !== '') {\n metadata.push(['Fix Effort', titleCase(String(report['fix_effort']))])\n }\n for (const [label, value] of metadata) {\n if (value !== null && value !== undefined && value !== '') lines.push(`**${label}:** ${String(value)}`)\n }\n return lines\n}\n\n/** One code-location section (writer.py :315-342, 2-space indents verbatim). */\nfunction renderCodeLocation(location: Record<string, unknown>, index: number): string[] {\n const lines: string[] = ['## Code Analysis', '']\n const file = String(location['file'] ?? 'unknown')\n const start = location['start_line']\n const end = location['end_line']\n let lineLabel = ''\n if (start !== null && start !== undefined) {\n lineLabel = end !== undefined && end !== null && end !== start ? ` (lines ${String(start)}-${String(end)})` : ` (line ${String(start)})`\n }\n lines.push(`**Location ${String(index + 1)}:** \\`${file}\\`${lineLabel}`)\n const label = location['label']\n if (typeof label === 'string' && label !== '') lines.push(` ${label}`)\n const snippet = location['snippet']\n if (typeof snippet === 'string' && snippet !== '') {\n const fence = safeFence(snippet)\n lines.push(` ${fence}`)\n for (const line of snippet.split('\\n')) lines.push(` ${line}`)\n lines.push(` ${fence}`)\n }\n const fixBefore = location['fix_before']\n const fixAfter = location['fix_after']\n if ((typeof fixBefore === 'string' && fixBefore !== '') || (typeof fixAfter === 'string' && fixAfter !== '')) {\n lines.push('')\n lines.push(' **Suggested Fix:**')\n lines.push('```diff')\n if (typeof fixBefore === 'string' && fixBefore !== '') for (const line of fixBefore.split('\\n')) lines.push(`- ${line}`)\n if (typeof fixAfter === 'string' && fixAfter !== '') for (const line of fixAfter.split('\\n')) lines.push(`+ ${line}`)\n lines.push('```')\n }\n lines.push('')\n return lines\n}\n\n/** Update history section (writer.py `render_update_history` :364-396). */\nexport function renderUpdateHistory(report: Record<string, unknown>): string[] {\n const history = report['update_history'] as ReadonlyArray<Record<string, unknown>> | undefined\n if (history === undefined || history.length === 0) return []\n const lines: string[] = ['## Update History', '']\n for (const entry of history) {\n const who = (entry['agent_name'] as string | undefined) ?? (entry['agent_id'] as string | undefined) ?? 'an agent'\n const fields = (entry['fields'] as readonly string[] | undefined)?.join(', ') ?? ''\n lines.push(`**${String(entry['timestamp'])}** — ${who} updated: ${fields}`)\n const dropped = entry['dropped_fields'] as readonly string[] | undefined\n if (dropped !== undefined && dropped.length > 0) lines.push(` Dropped as superseded: ${dropped.join(', ')}`)\n const previousSeverity = entry['previous_severity']\n if (typeof previousSeverity === 'string') lines.push(` Previous severity: ${previousSeverity}`)\n const previousCvss = entry['previous_cvss']\n if (previousCvss !== undefined && previousCvss !== null) lines.push(` Previous CVSS: ${String(previousCvss)}`)\n const previousConfidence = entry['previous_confidence']\n if (typeof previousConfidence === 'string') lines.push(` Previous confidence: ${previousConfidence}`)\n const reason = entry['reason']\n if (typeof reason === 'string' && reason !== '') lines.push(` Reason: ${reason}`)\n lines.push('')\n }\n return lines\n}\n\n/**\n * Render one vulnerability markdown document (writer.py\n * `render_vulnerability_md` :223-361 section order).\n * @param report - the stored report dict.\n */\nexport function renderVulnerabilityMd(report: VulnerabilityReport): string {\n const record = report as unknown as Record<string, unknown>\n const lines: string[] = [`# ${String(record['title'])}`, '']\n lines.push(...renderMetadataLines(record), '')\n\n const section = (heading: string, field: string): void => {\n const value = record[field]\n if (typeof value === 'string' && value !== '') lines.push(`## ${heading}`, '', value, '')\n }\n section('Description', 'description')\n section('Evidence', 'evidence')\n section('Impact', 'impact')\n section('Counterevidence', 'counterevidence')\n section('Confidence Rationale', 'confidence_rationale')\n section('What Would Change This Severity', 'severity_change_conditions')\n section('Technical Analysis', 'technical_analysis')\n\n const metadata = record['dependency_metadata'] as Record<string, unknown> | undefined\n const contextualReasoning = metadata?.['contextual_cvss_reasoning']\n if (typeof contextualReasoning === 'string' && contextualReasoning !== '') {\n lines.push('## Contextual CVSS', '', contextualReasoning, '')\n }\n\n const pocDescription = record['poc_description']\n const pocScript = record['poc_script_code']\n if ((typeof pocDescription === 'string' && pocDescription !== '') || (typeof pocScript === 'string' && pocScript !== '')) {\n lines.push('## Proof of Concept', '')\n if (typeof pocDescription === 'string' && pocDescription !== '') lines.push(pocDescription, '')\n if (typeof pocScript === 'string' && pocScript !== '') {\n const fenced = parseFencedCode(pocScript)\n const language = fenced.language !== '' ? fenced.language : guessLanguageName(fenced.body)\n const fence = safeFence(fenced.body)\n lines.push(`${fence}${language}`, fenced.body, fence, '')\n }\n }\n\n const locations = record['code_locations'] as ReadonlyArray<Record<string, unknown>> | undefined\n if (locations !== undefined && locations.length > 0) {\n for (const [index, location] of locations.entries()) lines.push(...renderCodeLocation(location, index))\n }\n\n section('Remediation', 'remediation_steps')\n section('Fix Verification', 'fix_verification')\n section('Assumptions', 'assumptions')\n lines.push(...renderUpdateHistory(record))\n return lines.join('\\n')\n}\n\n/**\n * Write the per-run artifacts handled outside SARIF (writer.py parity):\n * vulnerabilities/*.md (incremental), vulnerabilities.csv,\n * vulnerabilities.json.\n * @param runDir - the run directory.\n * @param reports - all stored reports.\n * @param savedIds - ids whose MD is already on disk (updated ids must be re-rendered by the caller removing them).\n */\nexport async function writeVulnerabilities(\n runDir: string,\n reports: readonly VulnerabilityReport[],\n savedIds: ReadonlySet<string>,\n): Promise<void> {\n for (const report of reports) {\n if (savedIds.has(report.id)) continue\n await atomicWriteText(join(runDir, 'vulnerabilities', `${report.id}.md`), renderVulnerabilityMd(report))\n }\n await atomicWriteText(join(runDir, 'vulnerabilities.csv'), renderVulnerabilitiesCsv(reports))\n await atomicWriteText(join(runDir, 'vulnerabilities.json'), dumpsIndent(reports))\n}\n\n/**\n * Write the assembled coverage document (coverage.py `write_coverage`).\n * @param runDir - the run directory.\n * @param document - the assembled coverage document.\n */\nexport async function writeCoverage(runDir: string, document: Record<string, unknown>): Promise<void> {\n await atomicWriteText(join(runDir, 'coverage.json'), dumpsIndent(document))\n}\n\n/**\n * Write run.json last (state.py ordering).\n * @param runDir - the run directory.\n * @param runRecord - the run record dict.\n */\nexport async function writeRunRecord(runDir: string, runRecord: Record<string, unknown>): Promise<void> {\n await atomicWriteText(join(runDir, 'run.json'), dumpsIndent(runRecord))\n}\n\n/**\n * Write the executive report (plain truncate-write, writer.py :139-145).\n * @param runDir - the run directory.\n * @param finalScanResult - the composed final report body.\n * @param generatedAt - display timestamp.\n */\nexport async function writeExecutiveReport(runDir: string, finalScanResult: string, generatedAt: string): Promise<void> {\n await mkdir(runDir, { recursive: true })\n await writeFile(join(runDir, 'penetration_test_report.md'), `# Security Penetration Test Report\\n\\n**Generated:** ${generatedAt}\\n\\n${finalScanResult}`, 'utf8')\n}\n\n/** Severity list used by callers that need the canonical order. */\nexport const severityOrder = SEVERITY_ORDER\n","/**\n * SARIF 2.1.0 writer — port of strix report/sarif.py: rule ids normalized\n * CWE→CVE→id→slug, GitHub security-severity, STRIDE tags from the CWE map,\n * physical + synthetic (SECURITY.md anchor) locations with endpoint logical\n * locations, PR-suggestion fixes, deterministic partial fingerprints\n * (sha256), and the strix-namespaced properties (PoC script body never\n * exported). Key insertion order matches Python dict construction\n * byte-for-byte (golden-diff locked).\n * @module @gpzhang2001/sharpkit-reporting/sarif\n */\n\nimport { createHash } from 'node:crypto'\nimport { rename, writeFile, rm } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport { dumpsIndent } from './writers.ts'\nimport type { VulnerabilityReport } from './state.ts'\n\nexport const SARIF_SCHEMA = 'https://json.schemastore.org/sarif-2.1.0.json'\nexport const SARIF_VERSION = '2.1.0'\nexport const TOOL_NAME = 'sharpkit'\nexport const TOOL_INFORMATION_URI = 'https://github.com/gpzhang2001/sharpkit'\nconst SYNTHETIC_LOCATION_URI = 'SECURITY.md'\nconst DEFAULT_STRIDE_LEGS: readonly string[] = ['T', 'I']\n\n/** CWE → STRIDE legs (sarif.py `_CWE_TO_STRIDE`, verbatim). */\nconst CWE_TO_STRIDE: Readonly<Record<string, readonly string[]>> = {\n '287': ['S'], '290': ['S'], '294': ['S'], '306': ['S', 'E'], '345': ['S', 'T'], '346': ['S'],\n '352': ['T', 'S'], '384': ['S'], '521': ['S'], '613': ['S'], '640': ['S'],\n '259': ['S', 'I'], '798': ['S', 'I'], '1391': ['S'],\n '20': ['T'], '73': ['T', 'I'], '78': ['T', 'E'], '79': ['T', 'I'], '89': ['T'], '91': ['T'],\n '94': ['T', 'E'], '434': ['T'], '502': ['T', 'E'], '915': ['E', 'T'], '918': ['T', 'I'], '1336': ['T', 'E'],\n '117': ['R'], '223': ['R'], '778': ['R'],\n '200': ['I'], '201': ['I'], '209': ['I'], '256': ['I'], '311': ['I'], '319': ['I'], '327': ['I'],\n '328': ['I'], '522': ['I'], '525': ['I'], '532': ['I'], '538': ['I'], '598': ['I'],\n '400': ['D'], '770': ['D'], '1333': ['D'],\n '269': ['E'], '284': ['E'], '285': ['E'], '639': ['E'], '732': ['E'], '862': ['E'], '863': ['E'], '1220': ['E'],\n '22': ['T', 'I'], '611': ['I', 'T'],\n}\n\n/** Curated vulnerability-class keywords (sarif.py `_VULN_CLASS_KEYWORDS`). */\nconst VULN_CLASS_KEYWORDS: readonly string[] = [\n 'missing authentication', 'missing authorization', 'broken access control', 'incorrect authorization',\n 'default credentials', 'hardcoded credentials', 'hardcoded secret', 'hardcoded password', 'default admin',\n 'default password', 'session fixation', 'open redirect', 'path traversal', 'directory traversal',\n 'command injection', 'sql injection', 'code injection', 'template injection', 'xpath injection',\n 'ldap injection', 'log injection', 'header injection', 'csv injection', 'prompt injection',\n 'deserialization', 'ssrf', 'xss', 'csrf', 'xxe', 'race condition', 'toctou', 'information disclosure',\n 'insecure direct object reference', 'idor', 'bola', 'bfla', 'cross-tenant', 'cross-project', 'tenant bypass',\n]\n\nconst SEVERITY_TO_LEVEL: Readonly<Record<string, string>> = {\n critical: 'error', high: 'error', medium: 'warning', low: 'note', info: 'note', informational: 'note',\n}\n\nconst SEVERITY_TO_SCORE: Readonly<Record<string, string>> = {\n critical: '9.5', high: '8.0', medium: '5.5', low: '3.0', info: '1.0', informational: '1.0',\n}\n\ntype Json = string | number | boolean | null | Json[] | { [key: string]: Json }\n\nfunction stringValue(value: unknown): string | null {\n if (typeof value === 'string') {\n const stripped = value.trim()\n return stripped === '' ? null : stripped\n }\n return null\n}\n\nfunction sha256(text: string): string {\n return createHash('sha256').update(text, 'utf8').digest('hex')\n}\n\n/** CWE variants (`CWE-89` / `cwe: 89` / `89`) → `CWE-89`. */\nfunction normalizeCwe(value: string): string | null {\n const digits = value.replace(/\\D/g, '')\n return digits === '' ? null : `CWE-${digits}`\n}\n\n/** Stable rule id: CWE → CVE → finding id → slug → sharpkit-finding. */\nexport function ruleIdOf(report: VulnerabilityReport): string {\n const cwe = stringValue(report.cwe)\n if (cwe !== null) {\n const normalized = normalizeCwe(cwe)\n if (normalized !== null) return normalized\n }\n const cve = stringValue(report.cve)\n if (cve !== null) return cve\n const id = stringValue(report.id)\n if (id !== null) return id\n const title = stringValue(report.title)\n return title === null ? 'sharpkit-finding' : slugify(title)\n}\n\n/** Lowercase slug joined by dashes (sarif.py `_slugify`). */\nexport function slugify(value: string): string {\n const chars = [...value.toLowerCase()].map(char => (/[a-z0-9]/.test(char) ? char : '-')).join('')\n const slug = chars.split('-').filter(part => part !== '').join('-')\n return slug === '' ? 'sharpkit-finding' : slug\n}\n\n/** STRIDE legs for a CWE, default legs when unmapped (every finding gets ≥1). */\nexport function strideLegsForCwe(cwe: unknown): readonly string[] {\n if (typeof cwe !== 'string' || cwe === '') return DEFAULT_STRIDE_LEGS\n const digits = cwe.replace(/\\D/g, '')\n if (digits === '') return DEFAULT_STRIDE_LEGS\n return CWE_TO_STRIDE[digits] ?? DEFAULT_STRIDE_LEGS\n}\n\n/** First curated keyword in the title, else the first 5 alphanumeric words. */\nexport function classKeyword(title: string): string {\n const lower = title.toLowerCase()\n for (const keyword of VULN_CLASS_KEYWORDS) {\n if (lower.includes(keyword)) return keyword\n }\n const words = lower.match(/[a-z0-9]+/g)?.slice(0, 5) ?? []\n return words.join(' ')\n}\n\n/** SARIF level mapping. */\nexport function sarifLevel(severity: unknown): string {\n const normalized = (typeof severity === 'string' ? severity : '').toLowerCase()\n return SEVERITY_TO_LEVEL[normalized] ?? 'note'\n}\n\n/** GitHub security-severity: \"%.1f\" CVSS else the label score. */\nexport function securitySeverity(report: VulnerabilityReport): string {\n if (report.cvss !== null && report.cvss !== undefined) {\n const score = Number(report.cvss)\n if (!Number.isNaN(score)) return score.toFixed(1)\n }\n const normalized = (typeof report.severity === 'string' ? report.severity : 'info').toLowerCase()\n return SEVERITY_TO_SCORE[normalized] ?? '1.0'\n}\n\n/** Reject unsafe SARIF artifact URIs; normalize backslashes (sarif.py `_sarif_uri`). */\nexport function sarifUri(file: string): string | null {\n const uri = file.replace(/\\\\/g, '/')\n if (uri.startsWith('/')) return null\n const first = uri.split('/')[0] ?? ''\n if (/^[A-Za-z]:$/.test(first)) return null\n if (uri.split('/').some(part => part === '..')) return null\n return uri\n}\n\n/** Help text: description + impact + remediation joined by blank lines. */\nfunction helpText(report: VulnerabilityReport, fallback: string): string {\n const sections = [report.description, report.impact, report.remediation_steps]\n .filter((value): value is string => typeof value === 'string' && value.trim() !== '')\n return sections.length > 0 ? sections.join('\\n\\n') : fallback\n}\n\ninterface PhysicalLocationInput {\n readonly file: unknown\n readonly start_line: unknown\n readonly end_line?: unknown\n readonly snippet?: unknown\n readonly label?: unknown\n}\n\n/** Validated physical locations + dropped count (sarif.py `_build_physical_locations`). */\nfunction buildPhysicalLocations(rawLocations: unknown): { readonly locations: Json[]; readonly dropped: number } {\n const locations: Json[] = []\n let dropped = 0\n if (!Array.isArray(rawLocations)) return { locations, dropped }\n for (const raw of rawLocations) {\n if (typeof raw !== 'object' || raw === null) continue\n const location = raw as PhysicalLocationInput\n const file = stringValue(location.file)\n const startLine = location.start_line\n if (file === null || typeof startLine !== 'number' || !Number.isInteger(startLine) || startLine < 1) {\n dropped++\n continue\n }\n const uri = sarifUri(file)\n if (uri === null) {\n dropped++\n continue\n }\n const physical: { [key: string]: Json } = {\n artifactLocation: { uri },\n }\n const region: { [key: string]: Json } = { startLine }\n const endLine = location.end_line\n if (typeof endLine === 'number' && Number.isInteger(endLine) && endLine >= startLine) region['endLine'] = endLine\n const snippet = stringValue(location.snippet)\n if (snippet !== null) region['snippet'] = { text: snippet }\n physical['region'] = region\n const entry: { [key: string]: Json } = { physicalLocation: physical }\n const label = stringValue(location.label)\n if (label !== null) entry['message'] = { text: label }\n locations.push(entry)\n }\n return { locations, dropped }\n}\n\n/** Locations with the synthetic anchor and endpoint/resource logical entries. */\nfunction buildLocations(report: VulnerabilityReport): { readonly locations: Json[]; readonly isSynthetic: boolean; readonly dropped: number } {\n const physical = buildPhysicalLocations(report.code_locations)\n const isSynthetic = physical.locations.length === 0\n const locations: Json[] = isSynthetic ? [{ physicalLocation: { artifactLocation: { uri: SYNTHETIC_LOCATION_URI } } }] : [...physical.locations]\n const endpoint = stringValue(report.endpoint)\n if (endpoint !== null) {\n locations.push({ logicalLocations: [{ fullyQualifiedName: endpoint, kind: 'endpoint' }] })\n } else if (isSynthetic) {\n const resource = stringValue(report.target) ?? stringValue(report.title)\n if (resource !== null) locations.push({ logicalLocations: [{ fullyQualifiedName: resource, kind: 'resource' }] })\n }\n return { locations, isSynthetic, dropped: physical.dropped }\n}\n\n/** Deterministic per-finding fingerprint (sarif.py `_primary_fingerprint`). */\nfunction primaryFingerprint(ruleId: string, report: VulnerabilityReport, locations: readonly Json[], isSynthetic: boolean): string | null {\n let uri = ''\n let startLine: number | null = null\n const first = locations.find(location => typeof location === 'object' && location !== null && 'physicalLocation' in location) as { physicalLocation?: { artifactLocation?: { uri?: unknown }; region?: { startLine?: unknown } } } | undefined\n if (first?.physicalLocation !== undefined) {\n uri = typeof first.physicalLocation.artifactLocation?.uri === 'string' ? first.physicalLocation.artifactLocation.uri : ''\n const line = first.physicalLocation.region?.startLine\n if (typeof line === 'number' && Number.isInteger(line) && line >= 1) startLine = line\n }\n const method = stringValue(report.method) ?? ''\n const endpoint = stringValue(report.endpoint) ?? ''\n const route = method !== '' || endpoint !== '' ? `${method.toUpperCase()} ${endpoint}`.trim() : ''\n if (uri === '' && route === '') return null\n const parts: string[] = [`rule:${ruleId}`]\n if (uri !== '') {\n parts.push(`uri:${uri}`)\n if (startLine !== null) parts.push(`line:${String(startLine)}`)\n }\n if (route !== '') parts.push(`route:${route}`)\n if (isSynthetic) {\n const title = stringValue(report.title)\n if (title !== null) parts.push(`synth_class:${classKeyword(title)}`)\n }\n return sha256(parts.join('|'))\n}\n\n/** File-independent class fingerprint (sarif.py `_class_fingerprint`). */\nfunction classFingerprint(ruleId: string, report: VulnerabilityReport): string | null {\n const title = stringValue(report.title)\n if (title === null) return null\n const keyword = classKeyword(title)\n if (keyword === '') return null\n return sha256(`rule:${ruleId}|class:${keyword}`)\n}\n\n/** PR-suggestion fixes from fix-bearing code locations (sarif.py `_build_fixes`). */\nfunction buildFixes(report: VulnerabilityReport): Json[] | null {\n const artifactChanges: Json[] = []\n if (!Array.isArray(report.code_locations)) return null\n for (const raw of report.code_locations) {\n if (typeof raw !== 'object' || raw === null) continue\n const location = raw as Record<string, unknown>\n const file = stringValue(location['file'])\n const fixBefore = stringValue(location['fix_before'])\n const fixAfter = stringValue(location['fix_after'])\n const startLine = location['start_line']\n if (file === null || fixBefore === null || fixAfter === null) continue\n if (typeof startLine !== 'number' || !Number.isInteger(startLine) || startLine < 1) continue\n const uri = sarifUri(file)\n if (uri === null) continue\n const deletedRegion: { [key: string]: Json } = { startLine }\n const endLine = location['end_line']\n if (typeof endLine === 'number' && Number.isInteger(endLine) && endLine >= startLine) deletedRegion['endLine'] = endLine\n artifactChanges.push({\n artifactLocation: { uri },\n replacements: [{ deletedRegion, insertedContent: { text: fixAfter } }],\n })\n }\n if (artifactChanges.length === 0) return null\n const fix: { [key: string]: Json } = { artifactChanges }\n const remediation = stringValue(report.remediation_steps)\n if (remediation !== null) fix['description'] = { text: remediation, markdown: remediation }\n return [fix]\n}\n\n/** Result properties (security-severity, class hash, synthetic flag, strix tree). */\nfunction resultProperties(report: VulnerabilityReport, classFp: string | null, isSynthetic: boolean): { [key: string]: Json } {\n const properties: { [key: string]: Json } = { 'security-severity': securitySeverity(report) }\n if (classFp !== null) properties['sharpkit_vuln_class_hash'] = classFp\n if (isSynthetic) properties['synthetic_location'] = true\n const sharpkitProps: { [key: string]: Json } = {}\n for (const key of [\n 'id', 'severity', 'cvss', 'timestamp', 'target', 'endpoint', 'method', 'cve', 'cwe', 'impact',\n 'technical_analysis', 'remediation_steps', 'counterevidence', 'confidence', 'confidence_rationale',\n 'severity_change_conditions', 'fix_verification',\n ]) {\n const value = (report as unknown as Record<string, unknown>)[key]\n if (value !== null && value !== undefined && value !== '') sharpkitProps[key] = value as Json\n }\n const metadata = (report as unknown as Record<string, unknown>)['dependency_metadata']\n if (typeof metadata === 'object' && metadata !== null && Object.keys(metadata).length > 0) sharpkitProps['dependency_metadata'] = metadata as Json\n const pocDescription = stringValue(report.poc_description)\n const pocScript = stringValue(report.poc_script_code)\n if (pocDescription !== null || pocScript !== null) {\n const poc: { [key: string]: Json } = {}\n if (pocDescription !== null) poc['description'] = pocDescription\n if (pocScript !== null) poc['script_available'] = true\n sharpkitProps['poc'] = poc\n }\n if (Object.keys(sharpkitProps).length > 0) properties['sharpkit'] = sharpkitProps\n return properties\n}\n\n/** Build one rule descriptor (sarif.py `_build_rule` key order). */\nfunction buildRule(ruleId: string, report: VulnerabilityReport): { [key: string]: Json } {\n const title = stringValue(report.title) ?? ruleId\n const fullDescription = stringValue(report.description) ?? title\n const help = helpText(report, fullDescription)\n const rule: { [key: string]: Json } = {\n id: ruleId,\n name: title !== '' ? title : ruleId.replace(/-/g, '_'),\n shortDescription: { text: title },\n fullDescription: { text: fullDescription },\n defaultConfiguration: { level: sarifLevel(report.severity) },\n help: { text: help, markdown: help },\n }\n const properties: { [key: string]: Json } = { 'security-severity': securitySeverity(report) }\n const tags: string[] = ['security']\n if (ruleId.startsWith('CWE-')) tags.push(ruleId)\n const cve = stringValue(report.cve)\n if (cve !== null && !tags.includes(cve)) tags.push(cve)\n for (const leg of strideLegsForCwe(report.cwe)) {\n const tag = `stride:${leg}`\n if (!tags.includes(tag)) tags.push(tag)\n }\n properties['tags'] = tags\n rule['properties'] = properties\n if (ruleId.startsWith('CWE-')) rule['helpUri'] = `https://cwe.mitre.org/data/definitions/${ruleId.slice('CWE-'.length)}.html`\n return rule\n}\n\n/** Build one result (sarif.py `_build_result` key order). */\nfunction buildResult(ruleId: string, ruleIndex: number, report: VulnerabilityReport): { readonly result: { [key: string]: Json }; readonly synthetic: boolean; readonly dropped: number } {\n const title = stringValue(report.title) ?? ruleId\n const description = stringValue(report.description)\n const messageText = description !== null ? `${title}\\n\\n${description}` : title\n const { locations, isSynthetic, dropped } = buildLocations(report)\n const result: { [key: string]: Json } = {\n ruleId,\n ruleIndex,\n level: sarifLevel(report.severity),\n message: { text: messageText },\n }\n if (locations.length > 0) result['locations'] = locations\n const fixes = buildFixes(report)\n if (fixes !== null) result['fixes'] = fixes\n const fingerprint = primaryFingerprint(ruleId, report, locations, isSynthetic)\n if (fingerprint !== null) result['partialFingerprints'] = { primaryLocationLineHash: fingerprint }\n result['properties'] = resultProperties(report, classFingerprint(ruleId, report), isSynthetic)\n return { result, synthetic: isSynthetic, dropped }\n}\n\n/** One coverage entry projected into SARIF (strix coverage.py shape). */\nexport interface SarifCoverageEntry {\n readonly risk_area: string\n readonly surface: string\n readonly outcome: string\n readonly evidence?: unknown\n readonly recorded_by?: unknown\n}\n\n/** The coverage document subset the SARIF bridge consumes. */\nexport interface SarifCoverage {\n readonly entries: readonly SarifCoverageEntry[]\n readonly completeness?: { readonly complete?: boolean; readonly caveats?: readonly string[] } | undefined\n}\n\n/** Coverage outcome → SARIF result kind (`reported` deliberately absent). */\nconst OUTCOME_TO_KIND: Readonly<Record<string, string>> = {\n no_issue_found: 'pass',\n ruled_out: 'pass',\n not_applicable: 'notApplicable',\n needs_follow_up: 'open',\n}\n\nconst OUTCOME_LABELS: Readonly<Record<string, string>> = {\n reported: 'Finding reported',\n no_issue_found: 'No issue identified',\n ruled_out: 'Ruled out',\n not_applicable: 'Not applicable',\n needs_follow_up: 'Requires further review',\n}\n\nexport interface SarifOptions {\n readonly toolVersion: string\n readonly coverage?: SarifCoverage | undefined\n /** Exactly-one-repository provenance (strix passes None in our port for now). */\n readonly repositoryContext?: {\n readonly repositoryUri?: string\n readonly repositoryFullName?: string\n readonly commitSha?: string\n readonly branch?: string\n readonly ref?: string\n } | undefined\n}\n\n/**\n * Build the full SARIF document (top-level key order and run properties).\n * Coverage results and invocations join when the coverage tool lands (批 4).\n * @param reports - all stored reports.\n * @param options - tool version and optional repository provenance.\n */\nexport function buildSarif(reports: readonly VulnerabilityReport[], options: SarifOptions): { [key: string]: Json } {\n const rules: { [key: string]: Json }[] = []\n const ruleIndex = new Map<string, number>()\n const results: Json[] = []\n let syntheticCount = 0\n const droppedFindings: { [key: string]: Json }[] = []\n let droppedLocationCount = 0\n for (const report of reports) {\n const id = ruleIdOf(report)\n let index = ruleIndex.get(id)\n if (index === undefined) {\n index = rules.length\n ruleIndex.set(id, index)\n rules.push(buildRule(id, report))\n }\n const { result, synthetic, dropped } = buildResult(id, index, report)\n if (synthetic) syntheticCount++\n if (dropped > 0) {\n droppedLocationCount += dropped\n droppedFindings.push({ droppedLocationCount: dropped, id: report.id, title: report.title })\n }\n results.push(result)\n }\n const driver: { [key: string]: Json } = {\n name: TOOL_NAME,\n informationUri: TOOL_INFORMATION_URI,\n rules,\n version: options.toolVersion,\n }\n const run: { [key: string]: Json } = { tool: { driver }, results }\n if (options.coverage !== undefined) appendCoverage(run, options.coverage, ruleIndex, rules)\n const runProperties: { [key: string]: Json } = {}\n if (syntheticCount > 0) runProperties['syntheticLocationCount'] = syntheticCount\n if (droppedLocationCount > 0) {\n runProperties['droppedUnsafeLocationCount'] = droppedLocationCount\n runProperties['droppedUnsafeLocationFindings'] = droppedFindings\n }\n const repo = options.repositoryContext\n if (repo !== undefined) {\n const provenance: { [key: string]: Json } = {}\n if (repo.repositoryUri !== undefined) provenance['repositoryUri'] = repo.repositoryUri\n if (repo.commitSha !== undefined) provenance['revisionId'] = repo.commitSha\n if (repo.branch !== undefined) provenance['branch'] = repo.branch\n if (Object.keys(provenance).length > 0) run['versionControlProvenance'] = [provenance]\n if (repo.repositoryFullName !== undefined) runProperties['repository'] = repo.repositoryFullName\n if (repo.ref !== undefined) runProperties['ref'] = repo.ref\n if (repo.commitSha !== undefined) runProperties['commit_sha'] = repo.commitSha\n }\n if (Object.keys(runProperties).length > 0) run['properties'] = runProperties\n return { version: SARIF_VERSION, $schema: SARIF_SCHEMA, runs: [run] }\n}\n\n/** Coverage rule + result builders and the run invocation (sarif.py :641-747). */\nfunction appendCoverage(run: { [key: string]: Json }, coverage: SarifCoverage, ruleIndex: Map<string, number>, rules: { [key: string]: Json }[]): void {\n const coverageResults: Json[] = []\n for (const entry of coverage.entries) {\n const outcome = typeof entry.outcome === 'string' ? entry.outcome : ''\n const kind = OUTCOME_TO_KIND[outcome]\n if (kind === undefined) continue\n const riskArea = typeof entry.risk_area === 'string' ? entry.risk_area : ''\n const ruleId = `sharpkit-coverage/${riskArea === '' ? 'unspecified' : slugify(riskArea)}`\n let index = ruleIndex.get(ruleId)\n if (index === undefined) {\n index = rules.length\n ruleIndex.set(ruleId, index)\n const name = riskArea !== '' ? riskArea : ruleId.replaceAll('-', '_')\n const description = `Coverage: ${riskArea}`\n rules.push({\n id: ruleId,\n name,\n shortDescription: { text: description },\n fullDescription: { text: description },\n defaultConfiguration: { level: 'none' },\n help: { text: description, markdown: description },\n properties: { tags: ['coverage'] },\n })\n }\n const label = OUTCOME_LABELS[outcome] ?? outcome\n const surface = typeof entry.surface === 'string' ? entry.surface : ''\n let messageText = `${riskArea} — ${label}: ${surface}`\n const evidence = typeof entry.evidence === 'string' && entry.evidence !== '' ? entry.evidence : null\n if (evidence !== null) messageText += `\\n\\n${evidence}`\n const sharpkitProps: { [key: string]: Json } = { coverage_outcome: outcome, risk_area: riskArea, surface }\n if (entry.recorded_by !== undefined && entry.recorded_by !== null) sharpkitProps['recorded_by'] = entry.recorded_by as Json\n sharpkitProps['source'] = 'agent_reported'\n coverageResults.push({\n ruleId,\n ruleIndex: index,\n kind,\n level: 'none',\n message: { text: messageText },\n locations: [{ logicalLocations: [{ fullyQualifiedName: surface }] }],\n properties: { sharpkit: sharpkitProps },\n })\n }\n if (coverageResults.length > 0) {\n const existing = run['results']\n run['results'] = [...(Array.isArray(existing) ? existing : []), ...coverageResults]\n }\n const invocation: { [key: string]: Json } = { executionSuccessful: coverage.completeness?.complete ?? true }\n const caveats = coverage.completeness?.caveats?.filter(caveat => caveat !== '')\n if (caveats !== undefined && caveats.length > 0) {\n invocation['toolExecutionNotifications'] = caveats.map(caveat => ({ level: 'warning', message: { text: caveat } }))\n }\n run['invocations'] = [invocation]\n}\n\n/**\n * Write findings.sarif (temp sibling + rename, trailing newline; sarif.py\n * `write_sarif_report`). Always emitted, even with zero findings, so a fresh\n * empty doc overwrites stale results.\n * @param runDir - the run directory.\n * @param reports - all stored reports.\n * @param options - tool version and provenance.\n */\nexport async function writeSarif(runDir: string, reports: readonly VulnerabilityReport[], options: SarifOptions): Promise<void> {\n const output = join(runDir, 'findings.sarif')\n const temp = `${output}.${process.pid}.tmp`\n try {\n await writeFile(temp, `${dumpsIndent(buildSarif(reports, options))}\\n`, 'utf8')\n await rename(temp, output)\n } finally {\n await rm(temp, { force: true }).catch(() => {})\n }\n}\n\n/** Reproduce a fingerprint for tests (exposed for golden diagnostics). */\nexport const internals = { primaryFingerprint, classFingerprint }\n","/**\n * Vulnerability / dependency reporting tools — port of strix\n * tools/reporting/tool.py: create_vulnerability_report,\n * create_dependency_report, update_vulnerability_report, list_reports,\n * get_report. Validation parity (runtime-validated value sets, CVSS\n * computation, cross-class update guards), strix's exact response JSON\n * shapes, and the artifacts fan-out on every mutation (md/csv/json/sarif +\n * run.json last, atomic writes; SARIF always emitted even when empty).\n * The dedupe LLM judge is a Config callback (deterministic dependency fast\n * path runs regardless; judge failures default to not-duplicate).\n * @module @gpzhang2001/sharpkit-reporting\n */\n\nimport { existsSync } from 'node:fs'\nimport { mkdir, readFile } from 'node:fs/promises'\nimport { isAbsolute, join, resolve } from 'node:path'\nimport type { Context } from '@deepseek-ai/cordis'\nimport type Schema from '@deepseek-ai/schemastery'\nimport z from '@deepseek-ai/schemastery'\nimport { defineTool } from '@deepseek-ai/dsh-tools'\nimport { calculateCvss, dependencySeverity, validateCvssBreakdown, type CvssMetricName } from './cvss.ts'\nimport { checkDuplicate, type DedupeJudge } from './dedupe.ts'\nimport { ReportState, formatTimestamp, severityRank, type VulnerabilityReport } from './state.ts'\nimport { renderVulnerabilityMd, writeCoverage, writeExecutiveReport, writeRunRecord, writeVulnerabilities } from './writers.ts'\nimport { writeSarif, type SarifCoverage } from './sarif.ts'\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context {\n pentestReporting: ReportingHandle\n }\n}\n\nexport { renderVulnerabilityMd }\nexport { ReportState, cleanTitle, severityRank } from './state.ts'\nexport { calculateCvss, cvssBaseScore, cvssSeverity, validateCvssBreakdown, dependencySeverity, buildCvssVector } from './cvss.ts'\nexport { checkDuplicate, dependencyIdentity } from './dedupe.ts'\nexport { buildSarif, sarifUri, ruleIdOf, classKeyword } from './sarif.ts'\n\n/** Deployment-tunable configuration. */\nexport interface Config {\n /** Run-name slug basis (strix derives it from the target label). */\n readonly runName?: string\n /** Runs root directory (sharpkit_runs; configurable back to strix_runs for legacy compat). */\n readonly runsRoot?: string\n /** Sandbox image version stamped into SARIF (tool.driver.version). */\n readonly toolVersion?: string\n /** Scan mode recorded into run.json. */\n readonly scanMode?: string\n /** Targets recorded into run.json. */\n readonly targetsInfo?: readonly Record<string, unknown>[]\n /** Pluggable dedupe LLM judge (dynamic findings; failures = not duplicate). */\n readonly dedupeJudge?: DedupeJudge\n /** File the CVSS-broad-CWE ban borrows from strix's guidance. */\n readonly strictCwe?: boolean\n /** Coverage document source (the analysis package wires itself in). */\n readonly coverageSource?: CoverageSource\n /** Auth mode recorded into run.json (strix codex.auth_mode; default \"none\"). */\n readonly authMode?: string\n /** Scan instruction recorded into run.json (strix set_scan_config). */\n readonly instruction?: string\n /** Diff scope recorded into run.json (diff-scope scans). */\n readonly diffScope?: string\n /** Non-interactive flag recorded into run.json. */\n readonly nonInteractive?: boolean\n /** Local source trees recorded into run.json. */\n readonly localSources?: readonly Record<string, unknown>[]\n /** Scope mode recorded into run.json (strix default \"auto\"). */\n readonly scopeMode?: string\n /** Diff base ref recorded into run.json (diff-scope scans). */\n readonly diffBase?: string\n /** MCP connection names recorded into run.json (strix record_mcp_connections). */\n readonly mcpConnections?: readonly string[]\n}\n\nexport const name = 'pentest-tool-reporting'\n\nexport const inject = ['tools']\n\nexport const Config: Schema<Config> = z.object({\n runName: z.string(),\n runsRoot: z.string().default('sharpkit_runs'),\n toolVersion: z.string().default('0.1.0'),\n scanMode: z.string().default('quick'),\n targetsInfo: z.array(z.object({})),\n strictCwe: z.boolean().default(true),\n authMode: z.string().default('none'),\n instruction: z.string(),\n diffScope: z.string(),\n nonInteractive: z.boolean(),\n localSources: z.array(z.object({})),\n scopeMode: z.string().default('auto'),\n diffBase: z.string(),\n mcpConnections: z.array(z.string()),\n}) as unknown as Schema<Config>\n\n/** strix-clean an optional string: literal null-words and empties → undefined. */\nfunction cleanOptional(value: string | undefined): string | undefined {\n if (value === undefined) return undefined\n const trimmed = value.trim()\n if (trimmed === '' || /^(null|none|nil|undefined)$/i.test(trimmed)) return undefined\n return trimmed\n}\n\n/** CVSS metric enum value sets (schema-level, matching strix runtime validation). */\nconst CVSS_METRIC_SCHEMAS = {\n attack_vector: { type: 'string' as const, required: true as const, enum: ['N', 'A', 'L', 'P'] } as const,\n attack_complexity: { type: 'string' as const, required: true as const, enum: ['L', 'H'] },\n privileges_required: { type: 'string' as const, required: true as const, enum: ['N', 'L', 'H'] },\n user_interaction: { type: 'string' as const, required: true as const, enum: ['N', 'R'] },\n scope: { type: 'string' as const, required: true as const, enum: ['U', 'C'] },\n confidentiality: { type: 'string' as const, required: true as const, enum: ['N', 'L', 'H'] },\n integrity: { type: 'string' as const, required: true as const, enum: ['N', 'L', 'H'] },\n availability: { type: 'string' as const, required: true as const, enum: ['N', 'L', 'H'] },\n}\n\nconst CODE_LOCATION_SCHEMA = {\n type: 'object' as const,\n properties: {\n file: { type: 'string' as const, required: true as const },\n start_line: { type: 'integer' as const, required: true as const },\n end_line: { type: 'integer' as const, required: true as const },\n snippet: { type: 'string' as const },\n label: { type: 'string' as const },\n fix_before: { type: 'string' as const },\n fix_after: { type: 'string' as const },\n },\n additionalProperties: false,\n} as const\n\n/** Normalize + validate code_locations (tool.py `_normalize_code_locations`). */\nexport function normalizeCodeLocations(raw: unknown): { readonly locations?: Record<string, unknown>[]; readonly errors: string[] } {\n if (!Array.isArray(raw) || raw.length === 0) return { errors: [] }\n const errors: string[] = []\n const locations: Record<string, unknown>[] = []\n for (const [index, item] of raw.entries()) {\n if (typeof item !== 'object' || item === null) continue\n const entry = item as Record<string, unknown>\n const normalized: Record<string, unknown> = {}\n const file = entry['file']\n if (typeof file === 'string' && file !== '') normalized['file'] = file.trim()\n const startLine = entry['start_line']\n if (typeof startLine === 'number' && Number.isInteger(startLine)) normalized['start_line'] = startLine\n else if (typeof startLine === 'string' && startLine !== '' && Number.isInteger(Number(startLine))) normalized['start_line'] = Number(startLine)\n const endLine = entry['end_line']\n if (typeof endLine === 'number' && Number.isInteger(endLine)) normalized['end_line'] = endLine\n else if (typeof endLine === 'string' && endLine !== '' && Number.isInteger(Number(endLine))) normalized['end_line'] = Number(endLine)\n for (const field of ['snippet', 'fix_before', 'fix_after'] as const) {\n const value = entry[field]\n if (typeof value === 'string' && value.trim() !== '') normalized[field] = value.replace(/^\\n+|\\n+$/g, '')\n }\n for (const field of ['label'] as const) {\n const value = entry[field]\n if (typeof value === 'string' && value.trim() !== '') normalized[field] = value.trim()\n }\n if (normalized['file'] === undefined || normalized['start_line'] === undefined) continue\n if (typeof normalized['file'] === 'string' && (normalized['file'] as string).startsWith('/')) {\n errors.push(`code_locations[${String(index)}]: file must be a repo-relative path (no leading '/')`)\n }\n if (typeof normalized['start_line'] !== 'number' || (normalized['start_line'] as number) < 1) {\n errors.push(`code_locations[${String(index)}]: start_line must be an integer >= 1`)\n }\n if (normalized['end_line'] === undefined) {\n errors.push(`code_locations[${String(index)}]: end_line is required`)\n } else {\n const start = normalized['start_line'] as number\n const end = normalized['end_line'] as number\n if (typeof end !== 'number' || end < 1) errors.push(`code_locations[${String(index)}]: end_line must be an integer >= 1`)\n else if (end < start) errors.push(`code_locations[${String(index)}]: end_line (${String(end)}) must be >= start_line (${String(start)})`)\n }\n locations.push(normalized)\n }\n return { ...(locations.length > 0 ? { locations } : {}), errors }\n}\n\n/** CVE normalization (tool.py `_extract_cve` + `_validate_cve`). */\nexport function normalizeCve(value: string | undefined): string | undefined {\n const cleaned = cleanOptional(value)\n if (cleaned === undefined) return undefined\n const match = /CVE-\\d{4}-\\d{4,}/.exec(cleaned)\n if (match === null) return undefined\n return match[0]\n}\n\n/** CWE normalization (tool.py `_extract_cwe`). */\nexport function normalizeCwe(value: string | undefined): string | undefined {\n const cleaned = cleanOptional(value)\n if (cleaned === undefined) return undefined\n const match = /CWE-\\d+/.exec(cleaned)\n if (match === null) return undefined\n return match[0]\n}\n\n/** Dependency metadata builder (tool.py `_build_dependency_metadata` order). */\nexport function buildDependencyMetadata(fields: {\n readonly packageName: string\n readonly installedVersion: string\n readonly advisoryCvss?: number | undefined\n readonly packageEcosystem: string\n readonly manifestPath: string\n readonly fixedVersion?: string | undefined\n readonly introducedBy?: string | undefined\n readonly dependencyPath?: string | undefined\n readonly reachability: string\n readonly reachabilityEvidence?: string | undefined\n readonly contextual?: {\n readonly breakdown: Record<string, string>\n readonly score: number\n readonly vector: string\n readonly reasoning: string\n } | undefined\n}): Record<string, unknown> {\n const metadata: Record<string, unknown> = {\n package_name: fields.packageName,\n installed_version: fields.installedVersion,\n }\n if (fields.advisoryCvss !== undefined) metadata['advisory_cvss'] = fields.advisoryCvss\n metadata['package_ecosystem'] = fields.packageEcosystem\n metadata['manifest_path'] = fields.manifestPath\n if (fields.fixedVersion !== undefined) metadata['fixed_version'] = fields.fixedVersion\n if (fields.introducedBy !== undefined) metadata['introduced_by'] = fields.introducedBy\n if (fields.dependencyPath !== undefined) metadata['dependency_path'] = fields.dependencyPath\n metadata['reachability'] = fields.reachability\n if (fields.reachabilityEvidence !== undefined) metadata['reachability_evidence'] = fields.reachabilityEvidence\n if (fields.contextual !== undefined) {\n metadata['contextual_cvss_breakdown'] = fields.contextual.breakdown\n metadata['contextual_cvss_score'] = fields.contextual.score\n metadata['contextual_cvss_vector'] = fields.contextual.vector\n metadata['contextual_cvss_reasoning'] = fields.contextual.reasoning.slice(0, 2000)\n }\n return metadata\n}\n\n/** Valid severities (strix `_VALID_SEVERITIES`). */\nconst VALID_SEVERITIES = new Set(['critical', 'high', 'medium', 'low', 'info', 'none'])\nconst VALID_FIX_EFFORT = new Set(['trivial', 'low', 'medium', 'high'])\nconst VALID_CONFIDENCE = new Set(['high', 'medium', 'low'])\nconst VALID_FINDING_CLASSES = new Set(['dynamic', 'dependency_cve'])\nconst VALID_REACHABILITY = new Set(['not_imported', 'imported', 'vulnerable_symbol_used', 'reachable_call_path', 'unknown'])\n\n/** Broad CWEs strix's guidance forbids (tool.py docstring; enforced lightly). */\nconst BROADCWES = new Set(['CWE-74', 'CWE-20', 'CWE-200', 'CWE-284', 'CWE-693'])\n\n/** Fields only a dynamic finding may carry on update (strix `_DYNAMIC_ONLY_UPDATE_FIELDS` inverse). */\nconst DEPENDENCY_ONLY_UPDATE_FIELDS = new Set(['contextual_cvss_reasoning'])\nconst DYNAMIC_ONLY_UPDATE_FIELDS = new Set(['endpoint', 'method', 'poc_description', 'poc_script_code'])\n\nexport interface ReportingHandle {\n readonly state: ReportState\n /** Directory of the most recently resolved run (sync view; resolve via {@link runDirFor} for accuracy). */\n readonly runDir: string\n /** Resolve (memoize per scan) this session's run directory — see apply() for the rules. */\n runDirFor(session: unknown): Promise<string>\n finishScan(sections: { readonly executiveSummary: string; readonly methodology: string; readonly technicalAnalysis: string; readonly recommendations: string }, status?: string, extras?: Readonly<Record<string, unknown>>): Promise<void>\n writeNow(): Promise<void>\n readRaw(relative: string): Promise<string>\n}\n\n/** Coverage document provider the analysis package supplies at wiring time. */\nexport interface CoverageSource {\n entries(): Array<Record<string, unknown>>\n outcomeCounts(): Record<string, number>\n}\n\n/**\n * Tool bodies are written with concrete arg/result types and bridged onto\n * the DSL at registration (`as never`); the registry re-validates every\n * call against the declared schema at the boundary.\n */\ntype ToolExecute = (args: never, exec: never) => Promise<never>\n\ninterface ToolRunContextLike {\n readonly signal: AbortSignal\n}\n\ninterface CvssBreakdownArgs extends Record<CvssMetricName, string> {}\n\ninterface CreateVulnArgs {\n title: string\n description: string\n impact: string\n target: string\n technical_analysis: string\n poc_description: string\n poc_script_code: string\n remediation_steps: string\n evidence: string\n assumptions: string\n counterevidence: string\n confidence: string\n confidence_rationale?: string\n severity_change_conditions: string\n fix_effort: string\n cvss_breakdown: CvssBreakdownArgs\n endpoint?: string\n method?: string\n cve?: string\n cwe?: string\n code_locations?: Record<string, unknown>[]\n fix_verification?: string\n fix_pr_body?: string\n}\n\ninterface UpdateArgs {\n report_id: string\n update_reason: string\n title?: string\n description?: string\n impact?: string\n target?: string\n technical_analysis?: string\n poc_description?: string\n poc_script_code?: string\n remediation_steps?: string\n evidence?: string\n assumptions?: string\n counterevidence?: string\n confidence?: string\n confidence_rationale?: string\n severity_change_conditions?: string\n fix_effort?: string\n cvss_breakdown?: CvssBreakdownArgs\n endpoint?: string\n method?: string\n cve?: string\n cwe?: string\n code_locations?: Record<string, unknown>[]\n fix_verification?: string\n fix_pr_body?: string\n contextual_cvss_reasoning?: string\n}\n\ninterface CreateDepArgs {\n title: string\n description: string\n target: string\n cve: string\n package_name: string\n installed_version: string\n advisory_cvss: number\n impact: string\n remediation_steps: string\n assumptions: string\n package_ecosystem: string\n manifest_path?: string\n fixed_version?: string\n cwe?: string\n technical_analysis?: string\n fix_effort?: string\n introduced_by?: string\n dependency_path?: string\n reachability?: string\n reachability_evidence?: string\n contextual_cvss_breakdown?: CvssBreakdownArgs\n contextual_cvss_reasoning?: string\n}\n\ninterface ListArgs {\n severity?: string\n finding_class?: string\n target?: string\n search?: string\n include_details?: boolean\n}\n\ninterface GetArgs {\n report_id: string\n}\n\nexport function apply(ctx: Context, config: Config = {}): ReportingHandle {\n const runsRoot = config.runsRoot ?? 'sharpkit_runs'\n const fallbackRunName = config.runName ?? `pentest-${Math.random().toString(16).slice(2, 6)}`\n const state = new ReportState({ runName: fallbackRunName })\n const toolVersion = config.toolVersion ?? '0.1.0'\n /** scan_results block, set by finishScan and appended to run.json. */\n let scanResults: Record<string, unknown> | undefined\n\n // ---- Run-directory resolution: artifacts follow the dsh working directory ----\n\n /**\n * Structural view of the dsh Session behind a tool execution: `agent.session`\n * (the same seam the approval gates use) carries a `header` with the session\n * id, its absolute working directory, and — for subagent children — the\n * owning root session. A scan's identity is the ROOT session id, so the\n * whole subagent tree shares one run directory; the header cwd is the base\n * a user's own writes would land in, which is where they expect artifacts.\n */\n interface SessionLike { header?: { id?: unknown; cwd?: unknown; parentSession?: unknown } }\n const scanFactsOf = (session: unknown): { id: string; key: string; cwd: string } => {\n const header = (session as SessionLike | undefined)?.header\n const id = typeof header?.id === 'string' ? header.id : ''\n const parent = typeof header?.parentSession === 'string' ? header.parentSession : ''\n const cwd = typeof header?.cwd === 'string' && header.cwd !== '' ? header.cwd : ''\n return { id, key: parent !== '' ? parent : id, cwd }\n }\n const sessionOf = (exec: unknown): unknown => (exec as { agent?: { session?: unknown } } | undefined)?.agent?.session\n const AGENTLESS = ':agentless'\n /** Per-scan memo: resolved run dir by scan key (root session id). */\n const resolvedRunDirs = new Map<string, string>()\n /** The session noted by the most recent tool execute (one scan per host at a time). */\n let activeSession: unknown\n /** sessionId → scan key: lets the usage ledger attribute assistant messages to the owning scan. */\n const scanKeyOfSession = new Map<string, string>()\n const noteScanKey = (session: unknown): void => {\n const facts = scanFactsOf(session)\n if (facts.id === '') return\n const previous = scanKeyOfSession.get(facts.id)\n scanKeyOfSession.set(facts.id, facts.key)\n // First sighting of a subagent: fold any orphan usage account accumulated\n // under its own id (messages that predate its first tool execute) into the\n // root scan's account, so a scan's llm_usage stays whole.\n if (previous !== facts.key && facts.key !== facts.id) {\n const orphan = usageByScan.get(facts.id)\n if (orphan !== undefined) {\n const root = usageAccountOf(facts.key)\n root.requests += orphan.requests\n root.inputTokens += orphan.inputTokens\n root.outputTokens += orphan.outputTokens\n root.totalTokens += orphan.totalTokens\n usageByScan.delete(facts.id)\n }\n }\n }\n const noteExec = (rawExec: never): void => {\n const session = sessionOf(rawExec)\n if (session !== undefined) {\n activeSession = session\n noteScanKey(session)\n }\n }\n\n /** Occupancy facts of an existing run dir (best-effort read of its run.json). */\n const runInfoOf = async (dir: string): Promise<{ completed: boolean; scanKey: string | null }> => {\n try {\n const raw = JSON.parse(await readFile(join(dir, 'run.json'), 'utf8')) as {\n status?: unknown\n session_id?: unknown\n scan_results?: { scan_completed?: unknown } | undefined\n }\n const completed = raw['status'] === 'completed' || raw['scan_results']?.['scan_completed'] === true\n const scanKey = typeof raw['session_id'] === 'string' ? raw['session_id'] : null\n return { completed, scanKey }\n } catch {\n return { completed: false, scanKey: null }\n }\n }\n\n /**\n * Resolve this scan's run directory, memoized per scan key:\n * - an absolute `runsRoot` pins the base (tests, explicit configs — unchanged);\n * - the default relative root resolves against the session header cwd,\n * falling back to process.cwd() for agentless calls;\n * - the name is the configured `runName`, else `pentest-<scan key short>`\n * (unique per scan, stable across restarts);\n * - a fresh scan NEVER overwrites a completed or foreign run: the name gains\n * a -2/-3… suffix; the same scan resuming its own incomplete run reuses\n * its directory (crash resume).\n */\n const runDirFor = async (session: unknown): Promise<string> => {\n if (session !== undefined) {\n activeSession = session\n noteScanKey(session)\n }\n const facts = scanFactsOf(session)\n const key = facts.key !== '' ? facts.key : AGENTLESS\n const memo = resolvedRunDirs.get(key)\n if (memo !== undefined) return memo\n const base = isAbsolute(runsRoot) ? resolve(runsRoot) : resolve(facts.cwd !== '' ? facts.cwd : process.cwd(), runsRoot)\n const nameBase = config.runName ?? (facts.key !== '' ? `pentest-${facts.key.replace(/[^a-zA-Z0-9]/g, '').slice(0, 8)}` : fallbackRunName)\n let name = nameBase\n let dir = resolve(join(base, name))\n for (let suffix = 2; existsSync(dir); suffix++) {\n const info = await runInfoOf(dir)\n // Same scan resuming its own incomplete run reuses the directory;\n // anything else (a completed run, a stale residue, a foreign scan) is kept.\n if (!info.completed && info.scanKey === key && key !== AGENTLESS) break\n if (suffix === 2) {\n ctx.logger.warn(`pentest-reporting: run dir '${name}' already holds ${info.completed ? 'a completed run' : 'another run'}; the new run goes to '${nameBase}-<n>'`)\n }\n name = `${nameBase}-${suffix}`\n dir = resolve(join(base, name))\n }\n resolvedRunDirs.set(key, dir)\n if (state.runName !== name) state.runName = name\n // Each newly resolved run dir gets a fresh run id: the state is shared for\n // multi-round continuation, but two rounds' run.json must not show the\n // same run_id (2026-09-22: both read run-22f45fc7).\n state.reseatRunId()\n return dir\n }\n\n /** Resolve the directory for the last-noted session (tools set it at execute start). */\n const currentRunDir = (): Promise<string> => runDirFor(activeSession)\n\n // llm_usage ledger, accounted PER SCAN KEY (root session): session\n // assistant/message usage events are the only host-side token source (dsh\n // emits no cost events). A second scan in the same host process starts its\n // own account instead of inheriting the previous scan's tokens\n // (2026-09-22: round 2's run.json carried round 1's whole 78M ledger).\n interface UsageAccount { requests: number; inputTokens: number; outputTokens: number; totalTokens: number }\n const usageByScan = new Map<string, UsageAccount>()\n const usageAccountOf = (key: string): UsageAccount => {\n let account = usageByScan.get(key)\n if (account === undefined) {\n account = { requests: 0, inputTokens: 0, outputTokens: 0, totalTokens: 0 }\n usageByScan.set(key, account)\n }\n return account\n }\n void ctx.on('session/event', (session: { id?: unknown } | undefined, event: unknown) => {\n const record = event as { type?: string; data?: { usage?: { inputTokens?: number; outputTokens?: number; totalTokens?: number } } }\n if (record.type !== 'assistant/message') return\n const usage = record.data?.usage\n if (usage === undefined || usage === null) return\n const sessionId = typeof session?.id === 'string' ? session.id : ''\n if (sessionId === '') return\n // Sessions the tools have not seen yet account under their own id; a\n // subagent's account folds into its root scan at its first noteExec.\n const account = usageAccountOf(scanKeyOfSession.get(sessionId) ?? sessionId)\n account.requests += 1\n account.inputTokens += usage.inputTokens ?? 0\n account.outputTokens += usage.outputTokens ?? 0\n account.totalTokens += usage.totalTokens ?? (usage.inputTokens ?? 0) + (usage.outputTokens ?? 0)\n })\n const llmUsageRecord = (): Record<string, unknown> => {\n const facts = activeSession !== undefined ? scanFactsOf(activeSession) : { id: '', key: '', cwd: '' }\n const account = usageAccountOf(facts.key !== '' ? facts.key : AGENTLESS)\n return {\n requests: account.requests,\n input_tokens: account.inputTokens,\n output_tokens: account.outputTokens,\n total_tokens: account.totalTokens,\n // dsh session events carry tokens only; cost stays null (parity deviation\n // recorded in the manual — strix estimates cost via LiteLLM callbacks).\n cost: null,\n agents: [],\n }\n }\n\n const ensureRunDir = async (): Promise<string> => {\n const dir = await currentRunDir()\n await mkdir(dir, { recursive: true })\n return dir\n }\n\n /** Resolve the coverage source: Config hook first, else the analysis package's service. */\n const coverageSource = (): CoverageSource | undefined => {\n if (config.coverageSource !== undefined) return config.coverageSource\n const analysis = ctx.get('pentestAnalysis') as\n | { coverageEntries(): Array<Record<string, unknown>>; outcomeCounts(): Record<string, number> }\n | undefined\n return analysis === undefined ? undefined : { entries: () => analysis.coverageEntries(), outcomeCounts: () => analysis.outcomeCounts() }\n }\n\n /** Assemble the coverage document (state.py `_coverage_document`, minus agent-graph gaps). */\n const coverageDocument = (): Record<string, unknown> => {\n const source = coverageSource()\n const entries = source?.entries() ?? []\n const outcomes = source?.outcomeCounts() ?? {}\n return {\n schema_version: 1,\n generated_at: formatTimestamp(new Date()),\n run_id: state.runId,\n run_name: state.runName,\n scope: { targets: config.targetsInfo ?? [], scan_mode: config.scanMode ?? null, scope_mode: null, diff_scope: null, instruction: '' },\n summary: {\n surfaces_reviewed: entries.length,\n outcomes,\n findings_filed: state.vulnerabilityReports.length,\n gaps: entries.filter(entry => entry['outcome'] === 'needs_follow_up').length,\n },\n completeness: { complete: state.status === 'completed', scan_status: state.status, exit_reason: null, caveats: state.status === 'running' ? ['scan still running'] : [] },\n entries: entries.map(entry => ({\n surface: entry['surface'],\n risk_area: entry['risk_area'],\n outcome: entry['outcome'],\n outcome_label: { reported: 'Finding reported', no_issue_found: 'No issue identified', ruled_out: 'Ruled out', not_applicable: 'Not applicable', needs_follow_up: 'Requires further review' }[String(entry['outcome'])] ?? String(entry['outcome']),\n ...(entry['evidence'] !== undefined ? { evidence: entry['evidence'] } : {}),\n recorded_by: entry['agent_name'] ?? null,\n recorded_at: entry['created_at'],\n ...(entry['updated_at'] !== undefined ? { updated_at: entry['updated_at'] } : {}),\n previous_outcomes: (entry['history'] as Array<Record<string, unknown>> | undefined)?.map(item => item['outcome']) ?? [],\n source: 'agent_reported',\n })),\n gaps: entries.filter(entry => entry['outcome'] === 'needs_follow_up').map(entry => ({\n kind: 'needs_follow_up',\n surface: entry['surface'],\n risk_area: entry['risk_area'],\n detail: `'${String(entry['surface'])}' (${String(entry['risk_area'])}) still needs follow-up.`,\n })),\n }\n }\n\n /** Full artifacts fan-out (state.py `_save_artifacts` order; run.json LAST). */\n const saveArtifacts = async (): Promise<void> => {\n try {\n const dir = await ensureRunDir()\n const coverage = coverageDocument()\n await writeCoverage(dir, coverage)\n await writeVulnerabilities(dir, state.vulnerabilityReports, state.savedVulnIds)\n const source = coverageSource()\n const sarifCoverage: SarifCoverage | undefined = source === undefined ? undefined : { entries: coverage['entries'] as unknown as SarifCoverage['entries'], completeness: coverage['completeness'] as unknown as SarifCoverage['completeness'] }\n await writeSarif(dir, state.vulnerabilityReports, { toolVersion, coverage: sarifCoverage })\n // Key order follows strix's run_record construction (state.py :207-216\n // initial fields, :612-631 set_scan_config appends, :560-582 scan_results).\n const runRecord: Record<string, unknown> = {\n run_id: state.runId,\n run_name: state.runName,\n session_id: (() => {\n const key = scanFactsOf(activeSession).key\n return key !== '' ? key : null\n })(),\n start_time: state.startTime,\n end_time: state.endTime,\n status: state.status,\n auth_mode: config.authMode ?? 'none',\n targets_info: config.targetsInfo ?? [],\n llm_usage: llmUsageRecord(),\n instruction: config.instruction ?? null,\n scan_mode: config.scanMode ?? 'quick',\n diff_scope: config.diffScope ?? null,\n non_interactive: config.nonInteractive ?? false,\n local_sources: config.localSources ?? [],\n scope_mode: config.scopeMode ?? 'auto',\n diff_base: config.diffBase ?? null,\n }\n if (config.mcpConnections !== undefined && config.mcpConnections.length > 0) {\n runRecord['mcp_connections'] = config.mcpConnections\n }\n if (scanResults !== undefined) runRecord['scan_results'] = scanResults\n await writeRunRecord(dir, runRecord)\n } catch (error) {\n // Best-effort persistence surface (strix swallows OSError/RuntimeError)\n // but said out loud: a silent artifact failure hides lost findings.\n ctx.logger.warn(`pentest-reporting: artifact save failed: ${String(error instanceof Error ? error.message : error)}`)\n }\n }\n\n /** The create-side validation + dedupe + persistence shared by both create tools. */\n const persistCreate = async (\n input: { readonly title: string; readonly severity: string; readonly findingClass: string; readonly dependencyMetadata?: Record<string, unknown>; readonly fields: Record<string, unknown> },\n dedupeCandidate: Record<string, unknown>,\n ): Promise<Record<string, unknown>> => {\n const verdict = await checkDuplicate(dedupeCandidate, input.dependencyMetadata, state.vulnerabilityReports, config.dedupeJudge)\n if (verdict.isDuplicate) {\n const existing = state.vulnerabilityReports.find(report => report.id === verdict.duplicateId)\n const title = existing?.title ?? ''\n return {\n success: false,\n error: `Potential duplicate of '${title}' (id=${verdict.duplicateId.slice(0, 8)}...) — do not re-report the same vulnerability`,\n duplicate_of: verdict.duplicateId,\n confidence: verdict.confidence,\n reason: verdict.reason,\n }\n }\n try {\n const report = state.addVulnerabilityReport(input)\n await saveArtifacts()\n return {\n success: true,\n message: `${input.findingClass === 'dependency_cve' ? 'Dependency finding' : 'Vulnerability report'} '${input.title}' created successfully`,\n report_id: report.id,\n severity: report.severity,\n ...(report.cvss !== undefined ? { cvss_score: report.cvss } : {}),\n ...(input.findingClass === 'dependency_cve' && report.cve !== undefined ? { cve: report.cve } : {}),\n }\n } catch (error) {\n return { success: false, error: `Failed to create ${input.findingClass === 'dependency_cve' ? 'dependency' : 'vulnerability'} report: ${String(error instanceof Error ? error.message : error)}` }\n }\n }\n\n ctx.tools.register(defineTool({\n name: 'create_vulnerability_report',\n description: \"File a vulnerability report — one report per fully-verified finding, with a working PoC. Severity and CVSS are computed from the 8-metric cvss_breakdown you provide. Validation contract (checked before filing, get these right the first time): cvss_breakdown must carry all 8 CVSS v3.1 metrics (attack_vector, attack_complexity, privileges_required, user_interaction, scope, confidentiality, integrity, availability) with their exact enum values; confidence != high requires confidence_rationale; any code_locations entry with fix_after requires fix_verification; cve must match CVE-YYYY-NNNNN and cwe must be a specific CWE-NNN child. On a duplicate verdict, revise the existing report via update_vulnerability_report instead of retrying. Never for known-CVE dependency findings — use create_dependency_report.\",\n parameters: {\n title: { type: 'string', required: true, description: 'Specific finding title (e.g. \"SQL Injection in /api/users login parameter\").' },\n description: { type: 'string', required: true, description: 'Concise, non-technical TL;DR (1-3 sentences).' },\n impact: { type: 'string', required: true, description: 'The unauthorized result demonstrated by the PoC and its scope.' },\n target: { type: 'string', required: true, description: 'Affected URL / domain / repository.' },\n technical_analysis: { type: 'string', required: true, description: 'The mechanism and root cause.' },\n poc_description: { type: 'string', required: true, description: 'Step-by-step reproduction (steps only, no code).' },\n poc_script_code: { type: 'string', required: true, description: 'Working PoC (Python preferred).' },\n remediation_steps: { type: 'string', required: true, description: 'Specific, actionable fix (prose, no code).' },\n evidence: { type: 'string', required: true, description: 'Concrete proof: request/response excerpts, observed behavior, tool output.' },\n assumptions: { type: 'string', required: true, description: 'Assumptions/prerequisites that make this finding impactful.' },\n counterevidence: { type: 'string', required: true, description: 'REQUIRED: the strongest case against this finding, after actively looking for it.' },\n confidence: { type: 'string', required: true, enum: ['high', 'medium', 'low'], description: 'Calibrated confidence.' },\n confidence_rationale: { type: 'string', description: 'Required when confidence is not high: name the specific gap.' },\n severity_change_conditions: { type: 'string', required: true, description: 'One concrete sentence on what evidence would raise or lower severity.' },\n fix_effort: { type: 'string', required: true, enum: ['trivial', 'low', 'medium', 'high'], description: 'Estimated fix effort.' },\n cvss_breakdown: { type: 'object', required: true, properties: CVSS_METRIC_SCHEMAS, additionalProperties: false, description: 'All 8 CVSS v3.1 metrics; score and severity are computed from it.' },\n endpoint: { type: 'string', description: 'API path / Git path (e.g. /api/login).' },\n method: { type: 'string', description: 'HTTP method when relevant.' },\n cve: { type: 'string', description: 'CVE-YYYY-NNNNN if certain, else omit.' },\n cwe: { type: 'string', description: 'CWE-NNN (most specific child) if certain, else omit.' },\n code_locations: { type: 'array', items: CODE_LOCATION_SCHEMA, description: 'White-box findings: file/start_line/end_line/snippet/label/fix_before/fix_after.' },\n fix_verification: { type: 'string', description: 'Required whenever any code_locations entry carries fix_after: the 4 ordered verification gates.' },\n fix_pr_body: { type: 'string', description: 'Optional markdown PR-description body proposing the fix.' },\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean', required: true },\n message: { type: 'string' },\n report_id: { type: 'string' },\n severity: { type: 'string' },\n cvss_score: { type: 'number' },\n error: { type: 'string' },\n errors: { type: 'array', items: { type: 'string' } },\n duplicate_of: { type: 'string' },\n confidence: { type: 'number' },\n reason: { type: 'string' },\n warning: { type: 'string' },\n },\n additionalProperties: false,\n },\n render: (_args, value) => {\n const result = value as { success: boolean; report_id?: string; severity?: string; cvss_score?: number; error?: string }\n if (!result.success) return [{ type: 'text', text: `create_vulnerability_report failed: ${result.error ?? 'unknown'}` }]\n return [{ type: 'text', text: `filed ${result.report_id} (${String(result.severity)}, CVSS ${String(result.cvss_score)})` }]\n },\n presentationMeta: (args: unknown, value: unknown) => findingPresentationMeta(args, value),\n },\n execute: (async (rawArgs: never, rawExec: never) => {\n noteExec(rawExec)\n const args = rawArgs as never as CreateVulnArgs\n const exec = rawExec as never as ToolRunContextLike\n void exec\n const errors: string[] = []\n const breakdown = args.cvss_breakdown as unknown as Record<CvssMetricName, string>\n errors.push(...validateCvssBreakdown(breakdown))\n const confidence = args.confidence.toLowerCase()\n if (!VALID_CONFIDENCE.has(confidence)) errors.push(`Invalid confidence: ${args.confidence}. Must be one of: [high, low, medium]`)\n const fixEffort = args.fix_effort.toLowerCase()\n if (!VALID_FIX_EFFORT.has(fixEffort)) errors.push(`Invalid fix_effort: ${args.fix_effort}. Must be one of: [high, low, medium, trivial]`)\n const cve = normalizeCve(args.cve)\n if (args.cve !== undefined && cve === undefined) errors.push(`Invalid cve: ${args.cve}. Must match CVE-YYYY-NNNNN`)\n const cwe = normalizeCwe(args.cwe)\n if (args.cwe !== undefined && cwe === undefined) errors.push(`Invalid cwe: ${args.cwe}. Must match CWE-NNN`)\n if (cwe !== undefined && config.strictCwe === true && BROADCWES.has(cwe)) errors.push(`${cwe} is too broad — file the most specific child CWE`)\n const locations = normalizeCodeLocations(args.code_locations)\n errors.push(...locations.errors)\n const hasFixAfter = locations.locations?.some(location => typeof location['fix_after'] === 'string' && location['fix_after'] !== '') ?? false\n if (hasFixAfter && cleanOptional(args.fix_verification) === undefined) errors.push('fix_verification is required when any code_locations entry carries fix_after')\n if (args.confidence !== 'high' && cleanOptional(args.confidence_rationale) === undefined) errors.push('confidence_rationale is required when confidence is not high')\n if (errors.length > 0) return { success: false, error: 'Validation failed', errors }\n let cvssScore: number | undefined\n let severity: string | undefined\n try {\n const computed = calculateCvss(breakdown)\n cvssScore = computed.score\n severity = computed.severity\n } catch (error) {\n return { success: false, error: 'Validation failed', errors: [String(error instanceof Error ? error.message : error)] }\n }\n const fields: Record<string, unknown> = {\n description: args.description, impact: args.impact, target: args.target,\n technical_analysis: args.technical_analysis, poc_description: args.poc_description,\n poc_script_code: args.poc_script_code, remediation_steps: args.remediation_steps,\n evidence: args.evidence, assumptions: args.assumptions, counterevidence: args.counterevidence,\n confidence, confidence_rationale: args.confidence_rationale,\n severity_change_conditions: args.severity_change_conditions, fix_effort: fixEffort,\n cvss: cvssScore, cvss_breakdown: breakdown,\n endpoint: args.endpoint, method: args.method, cve, cwe,\n code_locations: locations.locations, fix_verification: args.fix_verification, fix_pr_body: args.fix_pr_body,\n }\n return persistCreate({ title: args.title, severity, findingClass: 'dynamic', fields }, {\n title: args.title, description: args.description, impact: args.impact, target: args.target,\n technical_analysis: args.technical_analysis, poc_description: args.poc_description,\n poc_script_code: args.poc_script_code, endpoint: args.endpoint, method: args.method,\n })\n }) as unknown as ToolExecute,\n }))\n\n ctx.tools.register(defineTool({\n name: 'update_vulnerability_report',\n description: \"Revise a vulnerability report that is already filed, keeping its id. Pass only the fields to replace; create's reporting rules apply. cvss_breakdown replaces the whole vector (score + severity recomputed). Reports keep their id, author, and filing time; the revision is recorded as update history.\",\n parameters: {\n report_id: { type: 'string', required: true, description: 'Id of the report to revise (format vuln-NNNN).' },\n update_reason: { type: 'string', required: true, description: 'What you learned that the report does not yet carry (1-2 sentences).' },\n title: { type: 'string' }, description: { type: 'string' }, impact: { type: 'string' },\n target: { type: 'string' }, technical_analysis: { type: 'string' }, poc_description: { type: 'string' },\n poc_script_code: { type: 'string' }, remediation_steps: { type: 'string' }, evidence: { type: 'string' },\n assumptions: { type: 'string' }, counterevidence: { type: 'string' },\n confidence: { type: 'string', enum: ['high', 'medium', 'low'] },\n confidence_rationale: { type: 'string' }, severity_change_conditions: { type: 'string' },\n fix_effort: { type: 'string', enum: ['trivial', 'low', 'medium', 'high'] },\n cvss_breakdown: { type: 'object', properties: CVSS_METRIC_SCHEMAS, additionalProperties: false },\n endpoint: { type: 'string' }, method: { type: 'string' }, cve: { type: 'string' }, cwe: { type: 'string' },\n code_locations: { type: 'array', items: CODE_LOCATION_SCHEMA },\n fix_verification: { type: 'string' }, fix_pr_body: { type: 'string' },\n contextual_cvss_reasoning: { type: 'string', description: 'Dependency findings only: what you observed in this codebase justifying the contextual cvss_breakdown.' },\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean', required: true },\n action: { type: 'string' },\n message: { type: 'string' },\n report_id: { type: 'string' },\n updated_fields: { type: 'array', items: { type: 'string' } },\n severity: { type: 'string' },\n cvss_score: { type: 'number' },\n error: { type: 'string' },\n errors: { type: 'array', items: { type: 'string' } },\n finding_class: { type: 'string' },\n rejected_fields: { type: 'array', items: { type: 'string' } },\n },\n additionalProperties: false,\n },\n render: (_args, value) => {\n const result = value as { success: boolean; report_id?: string; error?: string }\n if (!result.success) return [{ type: 'text', text: `update_vulnerability_report failed: ${result.error ?? 'unknown'}` }]\n return [{ type: 'text', text: `revised ${result.report_id}` }]\n },\n presentationMeta: (args: unknown, value: unknown) => findingPresentationMeta(args, value),\n },\n execute: (async (rawArgs: never, rawExec: never) => {\n noteExec(rawExec)\n const args = rawArgs as never as UpdateArgs\n const exec = rawExec as never as ToolRunContextLike\n void exec\n const reportId = cleanOptional(args.report_id)\n const reason = cleanOptional(args.update_reason)\n if (reportId === undefined || reason === undefined) {\n return { success: false, error: `${reportId === undefined ? 'report_id' : 'update_reason'} cannot be empty - name the report you are revising and state what you learned that it does not yet carry` }\n }\n const report = state.vulnerabilityReports.find(entry => entry.id === reportId)\n if (report === undefined) return { success: false, error: `Report with id '${reportId}' not found`, report_id: reportId }\n const changes: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(args)) {\n if (key === 'report_id' || key === 'update_reason') continue\n const cleaned = typeof value === 'string' ? cleanOptional(value) : value\n if (cleaned === undefined) continue\n changes[key] = cleaned\n }\n if (Object.keys(changes).length === 0) {\n return { success: false, error: 'No fields to update - pass at least one field you want to replace', report_id: reportId }\n }\n // Cross-class guard (tool.py `_fit_revision_to_class`).\n const findingClass = (typeof report.finding_class === 'string' ? report.finding_class : (report.dependency_metadata !== undefined ? 'dependency_cve' : 'dynamic')) as string\n const rejected: string[] = []\n if (findingClass === 'dependency_cve') {\n for (const field of DYNAMIC_ONLY_UPDATE_FIELDS) {\n if (changes[field] !== undefined) rejected.push(field)\n }\n } else {\n for (const field of DEPENDENCY_ONLY_UPDATE_FIELDS) {\n if (changes[field] !== undefined) rejected.push(field)\n }\n }\n if (rejected.length > 0) {\n return {\n success: false,\n error: `Report '${reportId}' is a ${findingClass} finding, so it cannot carry ${rejected.join(', ')}. File your proof as its own vulnerability report instead of writing it onto this one.`,\n report_id: reportId,\n finding_class: findingClass,\n rejected_fields: rejected,\n }\n }\n // Dependency re-rating: breakdown must carry contextual reasoning.\n if (changes['cvss_breakdown'] !== undefined && findingClass === 'dependency_cve') {\n if (changes['contextual_cvss_reasoning'] === undefined && report.dependency_metadata === undefined) {\n return { success: false, error: 'Validation failed', errors: ['contextual_cvss_reasoning is required when re-rating a dependency finding'], report_id: reportId }\n }\n const errors = validateCvssBreakdown(changes['cvss_breakdown'] as Record<string, unknown>)\n if (errors.length > 0) return { success: false, error: 'Validation failed', errors, report_id: reportId }\n const computed = calculateCvss(changes['cvss_breakdown'] as Record<CvssMetricName, string>)\n changes['cvss'] = computed.score\n changes['severity'] = computed.severity\n } else if (changes['cvss_breakdown'] !== undefined) {\n const errors = validateCvssBreakdown(changes['cvss_breakdown'] as Record<string, unknown>)\n if (errors.length > 0) return { success: false, error: 'Validation failed', errors, report_id: reportId }\n const computed = calculateCvss(changes['cvss_breakdown'] as Record<CvssMetricName, string>)\n changes['cvss'] = computed.score\n changes['severity'] = computed.severity\n }\n const outcome = state.updateVulnerabilityReport(reportId, changes, reason)\n if ('noop' in outcome) {\n return { success: false, error: `Report '${reportId}' already says this - nothing in your update changes it`, report_id: reportId }\n }\n await saveArtifacts()\n const updated = outcome.report\n return {\n success: true,\n action: 'updated',\n message: `Report '${reportId}' now carries your revision. Do not file it again.`,\n report_id: reportId,\n updated_fields: (updated['update_history'] as { fields: string[] }[] | undefined)?.at(-1)?.fields ?? [],\n severity: updated.severity,\n ...(updated.cvss !== undefined ? { cvss_score: updated.cvss as number } : {}),\n }\n }) as unknown as ToolExecute,\n }))\n\n ctx.tools.register(defineTool({\n name: 'create_dependency_report',\n description: \"File a known-CVE dependency (SCA) finding — one report per CVE x package. For vulnerable third-party package versions pinned in a lockfile/manifest/SBOM; no live PoC needed. Severity comes from the contextual_cvss_breakdown when provided, else the advisory score. Validation contract: besides the marked-required fields, manifest_path, reachability_evidence, contextual_cvss_breakdown AND contextual_cvss_reasoning are all required and must be non-empty (the '(required)' hints in their descriptions are enforced at execution time). Never for dynamically-proven vulnerabilities — use create_vulnerability_report.\",\n parameters: {\n title: { type: 'string', required: true, description: 'e.g. \"CVE-2024-1234 in lodash 4.17.20 (prototype pollution)\".' },\n description: { type: 'string', required: true, description: 'What the CVE is and why the pinned version is affected.' },\n target: { type: 'string', required: true, description: 'Affected repository / project / manifest.' },\n cve: { type: 'string', required: true, description: 'CVE-YYYY-NNNNN — required and verified.' },\n package_name: { type: 'string', required: true, description: 'Affected package name (e.g. lodash).' },\n installed_version: { type: 'string', required: true, description: 'The version currently pinned/installed.' },\n advisory_cvss: { type: 'number', required: true, description: 'Published advisory base score (0.0-10.0).' },\n impact: { type: 'string', required: true, description: 'What the CVE enables; business risk in this context.' },\n remediation_steps: { type: 'string', required: true, description: 'How to fix (usually upgrade to a fixed version).' },\n assumptions: { type: 'string', required: true, description: 'Exploitability/reachability assumptions & confidence.' },\n package_ecosystem: { type: 'string', required: true, description: 'e.g. npm / pypi / maven / go.' },\n manifest_path: { type: 'string', description: 'Repo-relative lockfile/manifest path (required).' },\n fixed_version: { type: 'string', description: 'First non-vulnerable version, if known.' },\n cwe: { type: 'string', description: 'CWE-NNN (most specific) if certain.' },\n technical_analysis: { type: 'string', description: 'Optional deeper mechanism/root-cause detail.' },\n fix_effort: { type: 'string', enum: ['trivial', 'low', 'medium', 'high'], description: 'Default low.' },\n introduced_by: { type: 'string', description: 'For a transitive dep, the direct dependency pulling it in (name@version).' },\n dependency_path: { type: 'string', description: 'Resolution chain joined with \" > \".' },\n reachability: { type: 'string', enum: ['not_imported', 'imported', 'vulnerable_symbol_used', 'reachable_call_path', 'unknown'], description: 'Usage-evidence level (default unknown).' },\n reachability_evidence: { type: 'string', description: 'Concrete proof for the level (required).' },\n contextual_cvss_breakdown: { type: 'object', properties: CVSS_METRIC_SCHEMAS, additionalProperties: false, description: 'Full CVSS v3.1 rating of this CVE in this codebase (required).' },\n contextual_cvss_reasoning: { type: 'string', description: '2-4 verifiable sentences with file:line hops (required).' },\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean', required: true },\n message: { type: 'string' },\n report_id: { type: 'string' },\n severity: { type: 'string' },\n cve: { type: 'string' },\n error: { type: 'string' },\n errors: { type: 'array', items: { type: 'string' } },\n duplicate_of: { type: 'string' },\n confidence: { type: 'number' },\n reason: { type: 'string' },\n warning: { type: 'string' },\n // persistCreate returns this whenever the filed report carries a\n // cvss (always, for dependency findings) — omitted from the schema\n // it made dsh reject the output AFTER persisting: the model saw a\n // phantom failure, re-filed 3 duplicates, and retracted them\n // (2026-09-22 live test, vuln-0037..0039).\n cvss_score: { type: 'number' },\n },\n additionalProperties: false,\n },\n render: (_args, value) => {\n const result = value as { success: boolean; report_id?: string; severity?: string; cve?: string; error?: string }\n if (!result.success) return [{ type: 'text', text: `create_dependency_report failed: ${result.error ?? 'unknown'}` }]\n return [{ type: 'text', text: `filed ${result.report_id} (${String(result.severity)}) for ${result.cve ?? 'CVE'}` }]\n },\n presentationMeta: (args: unknown, value: unknown) => findingPresentationMeta(args, value),\n },\n execute: (async (rawArgs: never, _rawExec: never) => {\n noteExec(_rawExec)\n const args = rawArgs as never as CreateDepArgs\n const errors: string[] = []\n const requireText = (value: string | undefined, name: string): string | undefined => {\n const cleaned = cleanOptional(value)\n if (cleaned === undefined) errors.push(`${name} cannot be empty`)\n return cleaned\n }\n const packageName = requireText(args.package_name, 'package_name')\n const installedVersion = requireText(args.installed_version, 'installed_version')\n const packageEcosystem = requireText(args.package_ecosystem, 'package_ecosystem')\n const manifestPath = requireText(args.manifest_path, 'manifest_path')\n const reachabilityEvidence = requireText(args.reachability_evidence, 'reachability_evidence')\n const contextualReasoning = requireText(args.contextual_cvss_reasoning, 'contextual_cvss_reasoning')\n const cve = normalizeCve(args.cve)\n if (cve === undefined) errors.push(`Invalid cve: ${String(args.cve)}. Must match CVE-YYYY-NNNNN`)\n const cwe = normalizeCwe(args.cwe)\n if (args.cwe !== undefined && cwe === undefined) errors.push(`Invalid cwe: ${args.cwe}. Must match CWE-NNN`)\n const advisory = args.advisory_cvss\n if (typeof advisory !== 'number' || Number.isNaN(advisory) || advisory < 0 || advisory > 10) errors.push(`Invalid advisory_cvss: ${String(advisory)}. Must be between 0.0 and 10.0`)\n const reachability = (args.reachability ?? 'unknown').toLowerCase()\n if (!VALID_REACHABILITY.has(reachability)) errors.push(`Invalid reachability: ${String(args.reachability)}. Must be one of: [imported, not_imported, reachable_call_path, unknown, vulnerable_symbol_used]`)\n const fixEffort = (args.fix_effort ?? 'low').toLowerCase()\n if (!VALID_FIX_EFFORT.has(fixEffort)) errors.push(`Invalid fix_effort: ${String(args.fix_effort)}. Must be one of: [high, low, medium, trivial]`)\n if (manifestPath !== undefined && (manifestPath.startsWith('/') || manifestPath.includes('\\\\') || manifestPath.split('/').some(part => part === '' || part === '.' || part === '..'))) {\n errors.push(`Invalid manifest_path: ${manifestPath}. Must be a repo-relative path without absolute or traversal segments`)\n }\n let contextual: Parameters<typeof buildDependencyMetadata>[0]['contextual'] | undefined\n const hasContextualBreakdown = args.contextual_cvss_breakdown !== undefined\n if (hasContextualBreakdown || contextualReasoning !== undefined) {\n if (!hasContextualBreakdown) errors.push('contextual_cvss_breakdown is required when contextual_cvss_reasoning is given')\n if (contextualReasoning === undefined) errors.push('contextual_cvss_reasoning is required when contextual_cvss_breakdown is given')\n if (hasContextualBreakdown && contextualReasoning !== undefined) {\n const breakdown = args.contextual_cvss_breakdown as unknown as Record<CvssMetricName, string>\n errors.push(...validateCvssBreakdown(breakdown))\n const computed = calculateCvss(breakdown)\n contextual = { breakdown, score: computed.score, vector: computed.vector, reasoning: contextualReasoning }\n }\n }\n if (errors.length > 0) return { success: false, error: 'Validation failed', errors }\n const severity = contextual !== undefined\n ? calculateCvss(contextual.breakdown as CvssBreakdownArgs).severity\n : dependencySeverity(advisory)\n const metadata = buildDependencyMetadata({\n packageName: packageName as string,\n installedVersion: installedVersion as string,\n advisoryCvss: advisory,\n packageEcosystem: packageEcosystem as string,\n manifestPath: manifestPath as string,\n fixedVersion: cleanOptional(args.fixed_version),\n introducedBy: cleanOptional(args.introduced_by),\n dependencyPath: cleanOptional(args.dependency_path),\n reachability,\n reachabilityEvidence,\n contextual,\n })\n const fields: Record<string, unknown> = {\n description: args.description, impact: args.impact, target: args.target,\n technical_analysis: args.technical_analysis, remediation_steps: args.remediation_steps,\n assumptions: args.assumptions, fix_effort: fixEffort,\n cve, cwe,\n cvss: contextual !== undefined ? contextual.score : advisory,\n }\n return persistCreate({ title: args.title, severity, findingClass: 'dependency_cve', dependencyMetadata: metadata, fields }, {\n title: args.title, description: args.description, target: args.target, cve,\n dependency_metadata: metadata, technical_analysis: args.technical_analysis,\n })\n }) as unknown as ToolExecute,\n }))\n\n ctx.tools.register(defineTool({\n name: 'list_reports',\n description: \"List vulnerability reports filed so far in this scan — metadata-first. Read-only and shared across all agents. Filters compose (AND); compact entries by default, full bodies with include_details.\",\n parameters: {\n severity: { type: 'string', enum: ['critical', 'high', 'medium', 'low', 'info', 'none'], description: 'Filter to one severity.' },\n finding_class: { type: 'string', enum: ['dynamic', 'dependency_cve'], description: 'dynamic or dependency_cve.' },\n target: { type: 'string', description: 'Substring match against target/endpoint.' },\n search: { type: 'string', description: 'Substring match against title and description.' },\n include_details: { type: 'boolean', description: 'Full report bodies instead of compact entries (default false).' },\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean', required: true },\n reports: { type: 'array', items: { type: 'object', properties: {}, additionalProperties: true } },\n filtered_count: { type: 'integer', required: true },\n total_count: { type: 'integer', required: true },\n severity_counts: { type: 'object', properties: {}, additionalProperties: true, required: true },\n warning: { type: 'string' },\n error: { type: 'string' },\n },\n additionalProperties: false,\n },\n render: (_args, value) => {\n const result = value as { reports: unknown[]; total_count: number }\n return [{ type: 'text', text: `${String(result.reports.length)} of ${String(result.total_count)} report(s)` }]\n },\n },\n execute: (async (rawArgs: never, rawExec: never) => {\n noteExec(rawExec)\n const args = rawArgs as never as ListArgs\n const exec = rawExec as never as ToolRunContextLike\n void exec\n const severityFilter = cleanOptional(args.severity)?.toLowerCase()\n const classFilter = cleanOptional(args.finding_class)?.toLowerCase()\n const targetFilter = cleanOptional(args.target)?.toLowerCase()\n const searchFilter = cleanOptional(args.search)?.toLowerCase()\n if (severityFilter !== undefined && !VALID_SEVERITIES.has(severityFilter)) {\n return { success: false, reports: [], filtered_count: 0, total_count: 0, severity_counts: {}, error: `Invalid severity: ${severityFilter}. Must be one of: [critical, high, info, low, medium, none]` }\n }\n if (classFilter !== undefined && !VALID_FINDING_CLASSES.has(classFilter)) {\n return { success: false, reports: [], filtered_count: 0, total_count: 0, severity_counts: {}, error: `Invalid finding_class: ${classFilter}. Must be one of: [dependency_cve, dynamic]` }\n }\n const severityCounts: Record<string, number> = {}\n for (const report of state.vulnerabilityReports) {\n const key = String(report.severity)\n severityCounts[key] = (severityCounts[key] ?? 0) + 1\n }\n const filtered = state.vulnerabilityReports.filter(report => {\n if (severityFilter !== undefined && report.severity !== severityFilter) return false\n if (classFilter !== undefined && String(report.finding_class) !== classFilter) return false\n if (targetFilter !== undefined) {\n const target = String(report.target ?? '').toLowerCase()\n const endpoint = String(report.endpoint ?? '').toLowerCase()\n if (!target.includes(targetFilter) && !endpoint.includes(targetFilter)) return false\n }\n if (searchFilter !== undefined) {\n const title = String(report.title ?? '').toLowerCase()\n const description = String(report.description ?? '').toLowerCase()\n if (!title.includes(searchFilter) && !description.includes(searchFilter)) return false\n }\n return true\n })\n filtered.sort((a, b) => severityRank(a.severity) - severityRank(b.severity) || a.id.localeCompare(b.id))\n const entries = filtered.map(report => args.include_details === true ? { ...report as unknown as Record<string, unknown> } : summarize(report))\n return {\n success: true,\n reports: entries,\n filtered_count: filtered.length,\n total_count: state.vulnerabilityReports.length,\n severity_counts: severityCounts,\n }\n }) as unknown as ToolExecute,\n }))\n\n ctx.tools.register(defineTool({\n name: 'get_report',\n description: 'Fetch one vulnerability report by its id (e.g. vuln-0001). Read-only; use list_reports to find ids.',\n parameters: {\n report_id: { type: 'string', required: true, description: \"Report id from list_reports or a create response (format 'vuln-NNNN').\" },\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n success: { type: 'boolean', required: true },\n report: { type: 'object', properties: {}, additionalProperties: true },\n error: { type: 'string' },\n },\n additionalProperties: false,\n },\n render: (_args, value) => {\n const result = value as { success: boolean; report?: { id?: string } | null; error?: string }\n if (!result.success) return [{ type: 'text', text: `get_report failed: ${result.error ?? 'unknown'}` }]\n return [{ type: 'text', text: `report ${String(result.report?.id)}` }]\n },\n },\n execute: (async (rawArgs: never, rawExec: never) => {\n noteExec(rawExec)\n const args = rawArgs as never as GetArgs\n const exec = rawExec as never as ToolRunContextLike\n void exec\n const reportId = cleanOptional(args.report_id)\n if (reportId === undefined) return { success: false, error: 'report_id cannot be empty' }\n const report = state.vulnerabilityReports.find(entry => entry.id === reportId)\n if (report === undefined) return { success: false, error: `Report with id '${reportId}' not found` }\n return { success: true, report: { ...report as unknown as Record<string, unknown> } }\n }) as unknown as ToolExecute,\n }))\n\n /** Compact summary entry (tool.py `_to_report_summary_entry` field order). */\n function summarize(report: VulnerabilityReport): Record<string, unknown> {\n const record = report as unknown as Record<string, unknown>\n const summary: Record<string, unknown> = {}\n for (const field of ['id', 'title', 'severity', 'cvss', 'confidence', 'finding_class', 'cve', 'cwe', 'target', 'endpoint', 'method', 'fix_effort', 'agent_name', 'timestamp']) {\n const value = record[field]\n if (value !== null && value !== undefined && value !== '') summary[field] = value\n }\n const description = record['description']\n if (typeof description === 'string' && description !== '') {\n summary['description_preview'] = description.length > 280 ? `${description.slice(0, 280)}...` : description\n }\n return summary\n }\n\n /**\n * Replay-safe toolview meta for finding cards (ui FindingRow consumes\n * severity/report_id/title from `result.meta`). Pure over (args, value);\n * undefined keys are omitted so the snapshot stays lossless JSON.\n */\n function findingPresentationMeta(args: unknown, value: unknown): Record<string, string> {\n const meta: Record<string, string> = {}\n const title = (args as { title?: string }).title\n if (title !== undefined) meta['title'] = title\n const severity = (value as { severity?: string }).severity\n if (severity !== undefined) meta['severity'] = severity\n const reportId = (value as { report_id?: string }).report_id\n if (reportId !== undefined) meta['report_id'] = reportId\n return meta\n }\n\n const composeFinalReport = (sections: { readonly executiveSummary: string; readonly methodology: string; readonly technicalAnalysis: string; readonly recommendations: string }): string =>\n ['# Executive Summary', sections.executiveSummary, '', '# Methodology', sections.methodology, '', '# Technical Analysis', sections.technicalAnalysis, '', '# Recommendations', sections.recommendations].join('\\n')\n\n const handle: ReportingHandle = {\n state,\n /**\n * Sync view of the run directory: the resolved dir of the last-noted\n * session when one exists, else the unguarded default (no occupancy\n * check). Accuracy for a fresh session comes from runDirFor().\n */\n get runDir(): string {\n const facts = scanFactsOf(activeSession)\n const key = facts.key !== '' ? facts.key : ':agentless'\n const memo = resolvedRunDirs.get(key)\n if (memo !== undefined) return memo\n const base = isAbsolute(runsRoot) ? resolve(runsRoot) : resolve(facts.cwd !== '' ? facts.cwd : process.cwd(), runsRoot)\n return resolve(join(base, config.runName ?? (facts.key !== '' ? `pentest-${facts.key.replace(/[^a-zA-Z0-9]/g, '').slice(0, 8)}` : fallbackRunName)))\n },\n runDirFor: (session: unknown) => runDirFor(session),\n /** Mark the scan complete and write the final report + artifacts. */\n async finishScan(sections: { readonly executiveSummary: string; readonly methodology: string; readonly technicalAnalysis: string; readonly recommendations: string }, status = 'completed', extras?: Readonly<Record<string, unknown>>): Promise<void> {\n state.finalScanResult = composeFinalReport(sections)\n state.complete(status)\n // strix `update_scan_final_fields` (finish tool → state.py :560-582).\n // `extras` carries reconciliation facts the caller measured at close\n // time (e.g. proxy-captured request count) into the persisted run.json.\n scanResults = {\n scan_completed: true,\n executive_summary: sections.executiveSummary,\n methodology: sections.methodology,\n technical_analysis: sections.technicalAnalysis,\n recommendations: sections.recommendations,\n success: status === 'completed',\n ...extras,\n }\n const dir = await ensureRunDir()\n await writeExecutiveReport(dir, state.finalScanResult, formatTimestamp(new Date()))\n await saveArtifacts()\n },\n /** Dump the current run.json record (golden/test helper). */\n async writeNow(): Promise<void> {\n await saveArtifacts()\n },\n readRaw: async (relative: string): Promise<string> => readFile(join(await currentRunDir(), relative), 'utf8'),\n }\n ctx.provide('pentestReporting', handle)\n return handle\n}\n\n"],"mappings":"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"}
|