0sec-cli 0.22.4 → 0.24.0
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/0.js +73 -68
- package/README.md +95 -61
- package/chunks/{adapt-loop-3CCOWE43.js → adapt-loop-TEJPXWFG.js} +4 -4
- package/chunks/{artifact-scraper-Z4UUIOH3.js → artifact-scraper-AJZ3LOQY.js} +2 -2
- package/chunks/{assumption-mining-2UAKQB6V.js → assumption-mining-EATDC4BB.js} +18 -18
- package/chunks/backend-connections-QE4NASAK.js +23 -0
- package/chunks/chunk-3XLEDCFX.js +566 -0
- package/chunks/{chunk-BGX53365.js → chunk-3XLFB46W.js} +5 -3
- package/chunks/{chunk-IXAHQICR.js → chunk-4TUR47H5.js} +8 -3
- package/chunks/{chunk-5WAJGLCW.js → chunk-4YRXIVPZ.js} +3 -3
- package/chunks/{chunk-4ZYYX5GY.js → chunk-52AWIBCT.js} +1 -1
- package/chunks/{chunk-TO35Y326.js → chunk-554D4AYM.js} +5 -2
- package/chunks/{chunk-GQ3DGHWE.js → chunk-5FHFG5P2.js} +174 -710
- package/chunks/chunk-5POT5OYF.js +733 -0
- package/chunks/chunk-62PGWN7Y.js +700 -0
- package/chunks/{chunk-H6Q2QAIY.js → chunk-A3EKBUEM.js} +1424 -859
- package/chunks/{chunk-6WQDXWQC.js → chunk-A6AZZ6XX.js} +2 -2
- package/chunks/{chunk-6YZE552K.js → chunk-AV5BF4V7.js} +1281 -2580
- package/chunks/{chunk-2WWAPKAW.js → chunk-BIJPMYFA.js} +6 -6
- package/chunks/{chunk-SCWWLABR.js → chunk-CIMN2AO6.js} +1 -1
- package/chunks/{chunk-H4DH7COV.js → chunk-CSPF47S3.js} +30 -20
- package/chunks/{chunk-RCRTSKQN.js → chunk-DNV3ZMPX.js} +1 -1
- package/chunks/{chunk-GVY3S5E5.js → chunk-E42XEJTK.js} +2 -2
- package/chunks/{chunk-VDOWARMJ.js → chunk-ESM447R6.js} +15 -1
- package/chunks/{chunk-WBRGXCU2.js → chunk-EXTN4SQV.js} +1 -1
- package/chunks/{chunk-QVIRWJ45.js → chunk-EYBMTELO.js} +108 -24
- package/chunks/chunk-FEOPHBMY.js +56 -0
- package/chunks/{chunk-IHPTOTLL.js → chunk-FKGFHLLS.js} +1 -1
- package/chunks/chunk-G2EJ3R5I.js +5198 -0
- package/chunks/chunk-GHEBZKUS.js +5417 -0
- package/chunks/chunk-GNR3APR6.js +295 -0
- package/chunks/{chunk-ELI3BVIK.js → chunk-H76JYUPE.js} +3 -3
- package/chunks/{chunk-E74LXQFY.js → chunk-HRBOZBMC.js} +1 -1
- package/chunks/{chunk-TM74SSHC.js → chunk-IIBNQTOK.js} +3 -2
- package/chunks/{chunk-UELXHK2Y.js → chunk-IK27KMVV.js} +16 -5
- package/chunks/{chunk-WHUAUFSX.js → chunk-J6G73WYF.js} +1 -1
- package/chunks/chunk-JSTLXPJS.js +284 -0
- package/chunks/{chunk-G2BE2FC7.js → chunk-O3ADFN2A.js} +1 -1
- package/chunks/chunk-O7Q2G2KW.js +117 -0
- package/chunks/{chunk-XODDLNBI.js → chunk-QEA2VHBD.js} +284 -33
- package/chunks/{chunk-C6JPA32H.js → chunk-RBOMXUYL.js} +3 -111
- package/chunks/{chunk-L2CCO4KE.js → chunk-RCHAFSWS.js} +838 -39
- package/chunks/{chunk-3BPX75OR.js → chunk-RD4FKFWR.js} +1 -1
- package/chunks/{chunk-DPUXXMJW.js → chunk-RPTO5FY2.js} +1 -1
- package/chunks/{chunk-6KFB6AYN.js → chunk-RZR2XXAK.js} +531 -17
- package/chunks/chunk-SGILXLR3.js +289 -0
- package/chunks/{chunk-E3OOBVOK.js → chunk-TOAAYJVN.js} +2 -2
- package/chunks/chunk-TOFIGQ63.js +83 -0
- package/chunks/{chunk-QWK4R3DB.js → chunk-TTDFBFNZ.js} +6 -6
- package/chunks/chunk-TZRHWP7R.js +736 -0
- package/chunks/chunk-UHUW45S3.js +164 -0
- package/chunks/{chunk-5JNTMWPK.js → chunk-V4BD7GSP.js} +2 -2
- package/chunks/{chunk-OAS5SAVZ.js → chunk-V5I5GAQH.js} +3226 -1683
- package/chunks/{chunk-PS5E7LUQ.js → chunk-W6IYTSZH.js} +79 -9
- package/chunks/{chunk-RTBZ36BD.js → chunk-WUPN3D37.js} +22 -248
- package/chunks/{chunk-CF3MNS3O.js → chunk-Y7KV7WV6.js} +2 -2
- package/chunks/{chunk-2OQOQ2FZ.js → chunk-YERUDEXT.js} +763 -688
- package/chunks/{chunk-CPCHLL6A.js → chunk-YJU7QACE.js} +1 -1
- package/chunks/{chunk-YED25PA4.js → chunk-YORL5S5V.js} +1 -1
- package/chunks/{chunk-YAZARMJY.js → chunk-YYOQADBB.js} +4 -3
- package/chunks/chunk-ZPFBQ3SD.js +127 -0
- package/chunks/{codex-models-Z43V3427.js → codex-models-FQPCWRPC.js} +7 -7
- package/chunks/{commands-EUGF4FUZ.js → commands-I5L3VD2A.js} +6187 -12196
- package/chunks/dashboard-B2AEGCFM.js +76 -0
- package/chunks/{db-NVAW4WWR.js → db-P5EIKMLP.js} +3 -3
- package/chunks/deep-review-I7RD5QSS.js +82 -0
- package/chunks/{disclose-LDNKAVRH.js → disclose-PFBWESVJ.js} +4 -2
- package/chunks/{dist-7RUOKPRJ.js → dist-3SWWY5FZ.js} +18 -2
- package/chunks/{dist-27BNG6WD.js → dist-AJU25UXA.js} +112 -63
- package/chunks/{dist-NG2HT5XU.js → dist-VK2M4HNW.js} +85 -1
- package/chunks/eval-runner-XVRX3R2Y.js +31 -0
- package/chunks/{exploit-agent-FCCR2HYX.js → exploit-agent-A4RTIJ4J.js} +1 -1
- package/chunks/{exploit-autoclimb-X5ZS5FAO.js → exploit-autoclimb-ABMMBC3M.js} +1 -1
- package/chunks/{exploit-climb-3JHGEO36.js → exploit-climb-BQ2SVU63.js} +2 -2
- package/chunks/{fix-NSNPU33B.js → fix-4YCLHFDT.js} +7 -7
- package/chunks/{harness-KXQOVIDQ.js → harness-DHWULEIZ.js} +3 -3
- package/chunks/{hunt-scan-ELTKGKC4.js → hunt-scan-DXV5H6YN.js} +16 -16
- package/chunks/{kernel-primitive-MT7YZSIG.js → kernel-primitive-SF4NALVR.js} +2 -2
- package/chunks/{kernel-vm-runner-YFRHYC6G.js → kernel-vm-runner-WEBEZEIC.js} +2 -2
- package/chunks/local-engine-XUG7XRKM.js +21 -0
- package/chunks/managed-operation-SQFMBWHG.js +60 -0
- package/chunks/{memsafety-scan-FCPAXIZE.js → memsafety-scan-L2Z7E7TE.js} +2 -2
- package/chunks/{native-loop-OFJDRHPI.js → native-loop-ZNAELJGB.js} +14 -13
- package/chunks/orchestrate-YHFJXGID.js +63 -0
- package/chunks/{prepare-72GWTRVI.js → prepare-SODWQN6O.js} +5 -5
- package/chunks/provider-model-discovery-QGUGL3XW.js +277 -0
- package/chunks/remote-workflow-runtime-XNNGI2PG.js +12 -0
- package/chunks/{run-WTJCZZHV.js → run-5T4Z3Q2D.js} +924 -327
- package/chunks/{runtime-LCJ4XSKE.js → runtime-HFFRUOPL.js} +4 -2
- package/chunks/{runtime-FCKOUB7V.js → runtime-MB4GEFBY.js} +7 -7
- package/chunks/{scan-stream-GT6GKQ3U.js → scan-stream-GXBJHCDF.js} +3 -2
- package/chunks/{scope-E5QZUOOH.js → scope-M7L3CD6X.js} +2 -2
- package/chunks/service-plugins-BGS6QKSZ.js +64 -0
- package/chunks/{session-store-H3Q7KCYG.js → session-store-K7I4GLNH.js} +2 -2
- package/chunks/{variant-candidates-SZKDCOLK.js → variant-candidates-2KSP5EHH.js} +7 -7
- package/chunks/{web-recon-prepass-IO3GXQMW.js → web-recon-prepass-RAXXTEWH.js} +5 -5
- package/chunks/workflow-runtime-V26HIJO3.js +178 -0
- package/dashboard/assets/abnfDiagram-VCTEODGH-CGCueOp5.js +1 -0
- package/dashboard/assets/arc-BjZaQcCc.js +1 -0
- package/dashboard/assets/architecture-7GRP2DOG-hcbO-9zX.js +1 -0
- package/dashboard/assets/architectureDiagram-5GKGNRK7-DReOXTSq.js +36 -0
- package/dashboard/assets/array-BifhSqXX.js +1 -0
- package/dashboard/assets/blockDiagram-I7D4REHJ-C-byT12_.js +129 -0
- package/dashboard/assets/c4Diagram-7LVT6UL2-DoYjz-Uv.js +38 -0
- package/dashboard/assets/channel-CUURBnpZ.js +1 -0
- package/dashboard/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
- package/dashboard/assets/chunk-4HAMMTFA-NBNp2zdt.js +62 -0
- package/dashboard/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
- package/dashboard/assets/chunk-75Z2AOVW-BHmkuP0B.js +2 -0
- package/dashboard/assets/chunk-DU6HZSFF-DgfLNaL2.js +127 -0
- package/dashboard/assets/chunk-F27PBJKO-3wwNFUgZ.js +1 -0
- package/dashboard/assets/chunk-FOHPRMQF-DHwB1DNv.js +161 -0
- package/dashboard/assets/chunk-GMAD6QVW-Btg7huZW.js +72 -0
- package/dashboard/assets/chunk-GVQU2GXP-ihCURK5O.js +1 -0
- package/dashboard/assets/chunk-IMKFNOWR-FsXj7slg.js +231 -0
- package/dashboard/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
- package/dashboard/assets/chunk-L3NEJ4N5-DorFIxJY.js +1 -0
- package/dashboard/assets/chunk-OSK3NFVY-DKun_KfC.js +10 -0
- package/dashboard/assets/chunk-P2QGCYS3-XGgiU1Bz.js +1 -0
- package/dashboard/assets/chunk-POPQ4Y6H-BTXEnGhJ.js +1 -0
- package/dashboard/assets/chunk-PWAF6VOD-DYZcGkTL.js +1 -0
- package/dashboard/assets/chunk-SHT3W25Y-C4WQfwf8.js +168 -0
- package/dashboard/assets/chunk-SVP7TREG-C4nCh0-1.js +88 -0
- package/dashboard/assets/chunk-TICWLB2K-DSB-IiGc.js +206 -0
- package/dashboard/assets/chunk-XXDRQBXY-CS6fjUcj.js +1 -0
- package/dashboard/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
- package/dashboard/assets/classDiagram-ZZMXUADV-CD1Buc26.js +1 -0
- package/dashboard/assets/classDiagram-v2-VYDZK3BY-CD1Buc26.js +1 -0
- package/dashboard/assets/common-BMdQBwfR.js +5 -0
- package/dashboard/assets/cose-bilkent-JH36ORCC-CUjQHTML.js +1 -0
- package/dashboard/assets/cynefin-OW5HDTMX-BC7zCtFq.js +1 -0
- package/dashboard/assets/cynefinDiagram-5FMLGOSQ-CgDOOY67.js +62 -0
- package/dashboard/assets/cytoscape.esm-CGd-uY3x.js +321 -0
- package/dashboard/assets/dagre-GXQ25YYZ-Dqc8FS9x.js +4 -0
- package/dashboard/assets/dagre-PrKaheQc.js +1 -0
- package/dashboard/assets/defaultLocale-BFoDCU3G.js +1 -0
- package/dashboard/assets/diagram-S7CK7UJ4-CrKqRXZb.js +30 -0
- package/dashboard/assets/diagram-UQ7AKVKN-Cu6Es0-v.js +41 -0
- package/dashboard/assets/diagram-VSXAHHWV-eK4d8FwS.js +3 -0
- package/dashboard/assets/diagram-VX7I27RA-bFxeFKOc.js +24 -0
- package/dashboard/assets/diagram-Z3DM3KII-C0ClmnhC.js +24 -0
- package/dashboard/assets/dist-BZh8Kb3O.js +1 -0
- package/dashboard/assets/ebnfDiagram-PWID7BFC-CUqxFPzf.js +1 -0
- package/dashboard/assets/erDiagram-RLTQ6QDP-CcYM7pLi.js +99 -0
- package/dashboard/assets/eventmodeling-NTZA5JFV-D8ZNnPkV.js +1 -0
- package/dashboard/assets/flowDiagram-HODETNUW-pDb1AYm8.js +1 -0
- package/dashboard/assets/ganttDiagram-EL5Y4UJY-UmZfbMyD.js +292 -0
- package/dashboard/assets/gitGraph-4MIJSDKK-mvNUo0ZA.js +1 -0
- package/dashboard/assets/gitGraphDiagram-WWUBYQGX-CvzeCxVy.js +106 -0
- package/dashboard/assets/graphlib-DS17s2tU.js +1 -0
- package/dashboard/assets/info-A6RAGUB7-DChKqZMi.js +1 -0
- package/dashboard/assets/infoDiagram-27XIBGKW-DjkpNtVW.js +2 -0
- package/dashboard/assets/init-C-OQMol4.js +1 -0
- package/dashboard/assets/ishikawaDiagram-5VMMS53U-8FhjJaWT.js +70 -0
- package/dashboard/assets/journeyDiagram-3NMN7TZE-DyNJ755f.js +139 -0
- package/dashboard/assets/kanban-definition-UXKFOSKX-_jCmtaY1.js +89 -0
- package/dashboard/assets/katex-BdBmVSus.js +257 -0
- package/dashboard/assets/line-Bf0nxyWf.js +1 -0
- package/dashboard/assets/linear-Bl6JKbf4.js +1 -0
- package/dashboard/assets/mermaid-parser.core-Cc6sgCzs.js +7 -0
- package/dashboard/assets/mermaid.core-B4yCwiN-.js +44 -0
- package/dashboard/assets/mindmap-definition-YA3MSWOX-D5DjWyXj.js +96 -0
- package/dashboard/assets/operations-B7JAWOi6.js +130 -0
- package/dashboard/assets/operations-QjKT0Hwi.css +1 -0
- package/dashboard/assets/ordinal-BDEzSJ7C.js +1 -0
- package/dashboard/assets/packet-AYTQ26CC-bQXLDhQC.js +1 -0
- package/dashboard/assets/path-fybaL0A-.js +1 -0
- package/dashboard/assets/pegDiagram-XKGWAZYB-Bf6a1vaf.js +1 -0
- package/dashboard/assets/pie-WAS4IAKB-DfzoABIi.js +1 -0
- package/dashboard/assets/pieDiagram-E7YTZNPT-D0L1qbch.js +39 -0
- package/dashboard/assets/quadrantDiagram-AXDQQJYC-CbFyy2Pe.js +7 -0
- package/dashboard/assets/radar-RG4KPBEZ-CZ2pyeUT.js +1 -0
- package/dashboard/assets/railroad-74A4TZTK-CP4Jazfd.js +1 -0
- package/dashboard/assets/railroad-abnf-HS5TGJTU-3MvEiHwD.js +1 -0
- package/dashboard/assets/railroad-ebnf-LZEXJU2U-BWto6cXE.js +1 -0
- package/dashboard/assets/railroad-peg-WCYAUIDC-DasEjbyf.js +1 -0
- package/dashboard/assets/railroadDiagram-O6MQD6OU-t7Gp9g2R.js +1 -0
- package/dashboard/assets/requirementDiagram-BXWQKSXE-LYmqeBXi.js +84 -0
- package/dashboard/assets/rough.esm-Dy-Kn_BL.js +1 -0
- package/dashboard/assets/sankeyDiagram-P5KCCOFB-DnpfA_94.js +40 -0
- package/dashboard/assets/sequenceDiagram-WJ2MYXX4-C8s3pTUE.js +162 -0
- package/dashboard/assets/sizeCapture-INFHLROL-B0uUizjq.js +1 -0
- package/dashboard/assets/src-CaNUT1AQ.js +1 -0
- package/dashboard/assets/stateDiagram-D77RDMKH-BMzm6fK1.js +1 -0
- package/dashboard/assets/stateDiagram-v2-MP3YSRHH-B3REMjpY.js +1 -0
- package/dashboard/assets/swimlanes-42K2YHIH-uJE05Tt_.js +1 -0
- package/dashboard/assets/swimlanesDiagram-VR7AAH4N-CIaVMZEy.js +8 -0
- package/dashboard/assets/timeline-definition-24CTP7MA-BfLJMVeG.js +120 -0
- package/dashboard/assets/treeView-Q6P3EWNA-ZOE2enu2.js +1 -0
- package/dashboard/assets/treemap-WGGIJYW6-yIZoPBF5.js +1 -0
- package/dashboard/assets/vennDiagram-4TSXK5OY-BYJRHEaL.js +34 -0
- package/dashboard/assets/wardley-WFR3VGLG-D5V-jLbB.js +1 -0
- package/dashboard/assets/wardleyDiagram-VM6X3IG4-DgPN4nSe.js +78 -0
- package/dashboard/assets/xychartDiagram-S5SC5T6Z-BhkAMAOT.js +7 -0
- package/dashboard/index.html +3 -3
- package/package.json +3 -2
- package/worker-assets/demo-target/README.md +15 -0
- package/worker-assets/demo-target/include/decoder.h +27 -0
- package/worker-assets/demo-target/patched-decoder.c +40 -0
- package/worker-assets/demo-target/src/decoder.c +50 -0
- package/worker-assets/demo-target/witness-65537x1.bin +0 -0
- package/chunks/chunk-FFHRANYC.js +0 -547
- package/chunks/eval-runner-6Q3H52SP.js +0 -30
- package/chunks/orchestrate-DRZ2SVCP.js +0 -62
- package/chunks/service-plugins-MSK2EQP6.js +0 -62
- package/dashboard/assets/operations-BvB5Qpmk.css +0 -1
- package/dashboard/assets/operations-D8Ii01SV.js +0 -114
- package/dashboard/assets/zero-peek-Dzm3MT3X.png +0 -0
|
@@ -0,0 +1,566 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire as __0CreateRequire } from "node:module";
|
|
3
|
+
const require = __0CreateRequire(import.meta.url);
|
|
4
|
+
import {
|
|
5
|
+
source_default
|
|
6
|
+
} from "./chunk-HLFS6WV2.js";
|
|
7
|
+
import {
|
|
8
|
+
formatHtml,
|
|
9
|
+
formatMarkdown,
|
|
10
|
+
formatSarif
|
|
11
|
+
} from "./chunk-5FHFG5P2.js";
|
|
12
|
+
import {
|
|
13
|
+
compareFindingsByBusinessPriority,
|
|
14
|
+
createAuditReportDocument,
|
|
15
|
+
createReviewReportDocument,
|
|
16
|
+
createScanReportDocument,
|
|
17
|
+
getFindingPriority
|
|
18
|
+
} from "./chunk-RZR2XXAK.js";
|
|
19
|
+
|
|
20
|
+
// packages/cli/src/utils.ts
|
|
21
|
+
import { gzipSync } from "zlib";
|
|
22
|
+
async function getRuntimeAvailability() {
|
|
23
|
+
const { detectAvailableRuntimes, LlmApiRuntime } = await import("./dist-AJU25UXA.js");
|
|
24
|
+
const apiRuntimeDiagnostics = new LlmApiRuntime({ type: "api", timeout: 5e3 }).getConfigurationDiagnostics();
|
|
25
|
+
const hasApiKey = apiRuntimeDiagnostics.valid;
|
|
26
|
+
const availableRuntimes = [...await detectAvailableRuntimes()];
|
|
27
|
+
return {
|
|
28
|
+
hasApiKey,
|
|
29
|
+
availableRuntimes,
|
|
30
|
+
apiRuntime: {
|
|
31
|
+
configured: apiRuntimeDiagnostics.reason !== "missing_key",
|
|
32
|
+
valid: apiRuntimeDiagnostics.valid,
|
|
33
|
+
providerLabel: apiRuntimeDiagnostics.providerLabel,
|
|
34
|
+
error: apiRuntimeDiagnostics.fatalError
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
async function checkRuntimeAvailability(runtime) {
|
|
39
|
+
const availability = await getRuntimeAvailability();
|
|
40
|
+
const { hasApiKey, availableRuntimes, apiRuntime } = availability;
|
|
41
|
+
if (hasApiKey) return;
|
|
42
|
+
console.log("");
|
|
43
|
+
if ((runtime === "api" || runtime === "auto") && apiRuntime.configured && apiRuntime.error) {
|
|
44
|
+
console.log(source_default.red(` ${apiRuntime.providerLabel} config error: ${apiRuntime.error.split("\n")[0]}`));
|
|
45
|
+
}
|
|
46
|
+
if (runtime === "api") {
|
|
47
|
+
console.log(source_default.yellow(
|
|
48
|
+
apiRuntime.configured ? " Warning: `--runtime api` needs a valid provider configuration. AI analysis will fail until this is fixed." : " Warning: `--runtime api` needs provider credentials. AI analysis may be skipped."
|
|
49
|
+
));
|
|
50
|
+
} else if (availableRuntimes.length > 0) {
|
|
51
|
+
console.log(source_default.cyan(` Using local runtime(s): ${availableRuntimes.join(", ")}`));
|
|
52
|
+
} else {
|
|
53
|
+
console.log(source_default.yellow(" Warning: No API key or local agent runtime detected. AI analysis will be skipped."));
|
|
54
|
+
}
|
|
55
|
+
console.log(source_default.gray(" Provider credentials: ZERO_CHATGPT_ACCESS_TOKEN | ZERO_CHATGPT_OAUTH_REFRESH_TOKEN, OPENROUTER_API_KEY, ANTHROPIC_API_KEY, AZURE_OPENAI_API_KEY, OPENAI_API_KEY"));
|
|
56
|
+
console.log("");
|
|
57
|
+
}
|
|
58
|
+
function buildShareUrl(report) {
|
|
59
|
+
const json = JSON.stringify(report);
|
|
60
|
+
const compressed = gzipSync(Buffer.from(json, "utf-8"));
|
|
61
|
+
const b64 = compressed.toString("base64url");
|
|
62
|
+
return `https://0.security/r#${b64}`;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// packages/cli/src/formatters/terminal.ts
|
|
66
|
+
var SEVERITY_COUNT_COLOR = {
|
|
67
|
+
critical: source_default.red.bold,
|
|
68
|
+
high: source_default.redBright.bold,
|
|
69
|
+
medium: source_default.yellow.bold,
|
|
70
|
+
low: source_default.blue,
|
|
71
|
+
info: source_default.gray
|
|
72
|
+
};
|
|
73
|
+
function formatTerminal(report) {
|
|
74
|
+
const W = 60;
|
|
75
|
+
const lines = [];
|
|
76
|
+
lines.push("");
|
|
77
|
+
if (report.warnings.length > 0) {
|
|
78
|
+
lines.push(` ${source_default.yellow.bold("WARNINGS")}`);
|
|
79
|
+
lines.push("");
|
|
80
|
+
for (const warning of report.warnings) {
|
|
81
|
+
lines.push(
|
|
82
|
+
` ${source_default.yellow.bold("!")} ${source_default.yellow(`[${warning.stage}] ${warning.message}`)}`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
lines.push("");
|
|
86
|
+
}
|
|
87
|
+
if (report.findings.length === 0) {
|
|
88
|
+
lines.push("");
|
|
89
|
+
if (report.warnings.length > 0 || report.executionSuccessful === false) {
|
|
90
|
+
lines.push(
|
|
91
|
+
` ${source_default.yellow.bold("!")} ${source_default.yellow("No vulnerabilities confirmed. Scan finished with warnings.")}`
|
|
92
|
+
);
|
|
93
|
+
} else if (report.reviewChecks?.some((check) => check.status !== "pass")) {
|
|
94
|
+
lines.push(` ${source_default.yellow.bold("!")} ${source_default.yellow("No security vulnerabilities found. Advisory review checks need attention.")}`);
|
|
95
|
+
} else {
|
|
96
|
+
lines.push(` ${source_default.green.bold("\u2713")} ${source_default.green("No vulnerabilities found.")}`);
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
lines.push(` ${source_default.bold.white("FINDINGS")}`);
|
|
100
|
+
lines.push("");
|
|
101
|
+
const sorted = [...report.findings].sort(compareFindingsByBusinessPriority);
|
|
102
|
+
for (const finding of sorted) {
|
|
103
|
+
lines.push(formatFinding(finding));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (report.reviewChecks?.length) {
|
|
107
|
+
lines.push("", ` ${source_default.bold.white("REVIEW CHECKS (advisory)")}`, "");
|
|
108
|
+
for (const check of report.reviewChecks) {
|
|
109
|
+
const color = check.status === "pass" ? source_default.green : source_default.yellow;
|
|
110
|
+
lines.push(` ${color(check.status.toUpperCase())} ${check.name} (${check.id})`);
|
|
111
|
+
lines.push(` Reason: ${check.reason}`);
|
|
112
|
+
if (check.fix) lines.push(` Suggested fix: ${check.fix}`);
|
|
113
|
+
lines.push("");
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
lines.push("");
|
|
117
|
+
lines.push(` ${source_default.gray("\u2500".repeat(50))}`);
|
|
118
|
+
lines.push("");
|
|
119
|
+
const { summary } = report;
|
|
120
|
+
const sev = [
|
|
121
|
+
summary.critical > 0 ? source_default.red.bold(`${summary.critical} critical`) : source_default.gray(`${summary.critical} critical`),
|
|
122
|
+
summary.high > 0 ? source_default.hex("#f97316").bold(`${summary.high} high`) : source_default.gray(`${summary.high} high`),
|
|
123
|
+
summary.medium > 0 ? source_default.yellow.bold(`${summary.medium} medium`) : source_default.gray(`${summary.medium} medium`),
|
|
124
|
+
source_default.gray(`${summary.low} low`),
|
|
125
|
+
source_default.gray(`${summary.info} info`)
|
|
126
|
+
].join(source_default.gray(" "));
|
|
127
|
+
for (const label of ["Urgent", "High", "Moderate", "Low", "Not assessed"]) {
|
|
128
|
+
const count = report.findings.filter((finding) => getFindingPriority(finding).label === label).length;
|
|
129
|
+
if (count) lines.push(` Business priority ${label}: ${count}`);
|
|
130
|
+
}
|
|
131
|
+
lines.push(` ${source_default.gray("Technical severity:")} ${sev}`);
|
|
132
|
+
lines.push(` ${source_default.white.bold(String(summary.totalFindings))} findings ${source_default.gray("in")} ${source_default.white(formatDuration(report.durationMs))}`);
|
|
133
|
+
lines.push(` ${source_default.gray("Share:")} ${source_default.cyan(buildShareUrl(report))}`);
|
|
134
|
+
lines.push("");
|
|
135
|
+
return lines.join("\n");
|
|
136
|
+
}
|
|
137
|
+
function formatFinding(finding) {
|
|
138
|
+
const priority = getFindingPriority(finding);
|
|
139
|
+
const lines = [];
|
|
140
|
+
lines.push(` ${source_default.bold(`Business priority: ${priority.label}`)} ${source_default.bold.white(finding.title)}`);
|
|
141
|
+
lines.push(` ${source_default.gray("Business impact rationale:")} ${priority.rationale}`);
|
|
142
|
+
lines.push(` ${source_default.gray("Technical severity:")} ${finding.severity}${finding.cvssScore !== void 0 ? ` CVSS: ${finding.cvssScore}` : ""}${finding.cvssVector ? ` CVSS vector: ${finding.cvssVector}` : ""}`);
|
|
143
|
+
const meta = [];
|
|
144
|
+
meta.push(`${source_default.gray("Category:")} ${formatCategory(finding.category)}`);
|
|
145
|
+
if (finding.status === "confirmed") {
|
|
146
|
+
meta.push(source_default.green("\u2713 Confirmed"));
|
|
147
|
+
}
|
|
148
|
+
lines.push(` ${" ".repeat(11)}${meta.join(source_default.gray(" \xB7 "))}`);
|
|
149
|
+
if (finding.description) {
|
|
150
|
+
const desc = finding.description.length > 100 ? finding.description.slice(0, 97) + "..." : finding.description;
|
|
151
|
+
lines.push(` ${" ".repeat(11)}${source_default.gray(desc)}`);
|
|
152
|
+
}
|
|
153
|
+
if (finding.evidence.analysis) {
|
|
154
|
+
const ev = finding.evidence.analysis.length > 100 ? finding.evidence.analysis.slice(0, 97) + "..." : finding.evidence.analysis;
|
|
155
|
+
lines.push(` ${" ".repeat(11)}${source_default.gray.italic("\u21B3 " + ev)}`);
|
|
156
|
+
}
|
|
157
|
+
lines.push("");
|
|
158
|
+
return lines.join("\n");
|
|
159
|
+
}
|
|
160
|
+
function formatCategory(cat) {
|
|
161
|
+
return cat.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
162
|
+
}
|
|
163
|
+
function formatDuration(ms) {
|
|
164
|
+
if (ms < 1e3) return `${ms}ms`;
|
|
165
|
+
return `${(ms / 1e3).toFixed(1)}s`;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// packages/cli/src/formatters/json.ts
|
|
169
|
+
function formatJson(report) {
|
|
170
|
+
return JSON.stringify(report, null, 2);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// packages/cli/src/formatters/replay.ts
|
|
174
|
+
function sleep(ms) {
|
|
175
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
176
|
+
}
|
|
177
|
+
function stripAnsi(s) {
|
|
178
|
+
return s.replace(/\x1b\[[0-9;]*m/g, "");
|
|
179
|
+
}
|
|
180
|
+
var BOX_WIDTH = 55;
|
|
181
|
+
function boxTop(label) {
|
|
182
|
+
const inner = ` ${label} `;
|
|
183
|
+
const remaining = BOX_WIDTH - inner.length - 1;
|
|
184
|
+
return source_default.dim("\u250C\u2500 ") + source_default.bold.white(label) + source_default.dim(" " + "\u2500".repeat(Math.max(0, remaining)) + "\u2510");
|
|
185
|
+
}
|
|
186
|
+
function boxRow(content) {
|
|
187
|
+
const visible = stripAnsi(content);
|
|
188
|
+
const pad = Math.max(0, BOX_WIDTH - visible.length - 2);
|
|
189
|
+
return source_default.dim("\u2502") + " " + content + " ".repeat(pad) + source_default.dim("\u2502");
|
|
190
|
+
}
|
|
191
|
+
function boxBottom(withArrow) {
|
|
192
|
+
if (withArrow) {
|
|
193
|
+
const half = Math.floor((BOX_WIDTH - 1) / 2);
|
|
194
|
+
const rest = BOX_WIDTH - half - 1;
|
|
195
|
+
return source_default.dim("\u2514" + "\u2500".repeat(half) + "\u2534" + "\u2500".repeat(rest) + "\u2518");
|
|
196
|
+
}
|
|
197
|
+
return source_default.dim("\u2514" + "\u2500".repeat(BOX_WIDTH) + "\u2518");
|
|
198
|
+
}
|
|
199
|
+
function connector() {
|
|
200
|
+
const half = Math.floor((BOX_WIDTH + 1) / 2);
|
|
201
|
+
return " ".repeat(half) + source_default.dim("\u25BC");
|
|
202
|
+
}
|
|
203
|
+
function outcomeLabel(outcome) {
|
|
204
|
+
switch (outcome) {
|
|
205
|
+
case "vulnerable":
|
|
206
|
+
return source_default.red.bold("VULNERABLE");
|
|
207
|
+
case "leaked":
|
|
208
|
+
return source_default.red.bold("LEAKED");
|
|
209
|
+
case "bypassed":
|
|
210
|
+
return source_default.red.bold("BYPASSED");
|
|
211
|
+
case "safe":
|
|
212
|
+
return source_default.green("SAFE");
|
|
213
|
+
case "error":
|
|
214
|
+
return source_default.yellow("ERROR");
|
|
215
|
+
default:
|
|
216
|
+
return source_default.gray(outcome.toUpperCase());
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
function buildReplayLines(data) {
|
|
220
|
+
const lines = [];
|
|
221
|
+
const FAST = 50;
|
|
222
|
+
const MED = 75;
|
|
223
|
+
const SLOW = 100;
|
|
224
|
+
const PAUSE = 200;
|
|
225
|
+
lines.push({ text: boxTop("DISCOVER"), delay: PAUSE });
|
|
226
|
+
if (data.targetInfo) {
|
|
227
|
+
const t = data.targetInfo;
|
|
228
|
+
const truncUrl = t.url.length > 30 ? t.url.slice(0, 27) + "..." : t.url;
|
|
229
|
+
lines.push({
|
|
230
|
+
text: boxRow(
|
|
231
|
+
source_default.dim("\u25B8") + " " + source_default.white(`GET ${truncUrl}`) + source_default.dim(" \u2192 ") + source_default.white(`200`) + source_default.gray(` (${t.type} endpoint detected)`)
|
|
232
|
+
),
|
|
233
|
+
delay: MED
|
|
234
|
+
});
|
|
235
|
+
if (t.systemPrompt) {
|
|
236
|
+
lines.push({
|
|
237
|
+
text: boxRow(
|
|
238
|
+
source_default.dim("\u25B8") + " " + source_default.white(`System prompt extracted`) + source_default.gray(` (${t.systemPrompt.length} chars)`)
|
|
239
|
+
),
|
|
240
|
+
delay: MED
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
if (t.detectedFeatures && t.detectedFeatures.length > 0) {
|
|
244
|
+
lines.push({
|
|
245
|
+
text: boxRow(
|
|
246
|
+
source_default.dim("\u25B8") + " " + source_default.white(`${t.detectedFeatures.length} features detected: `) + source_default.gray(t.detectedFeatures.slice(0, 3).join(", "))
|
|
247
|
+
),
|
|
248
|
+
delay: MED
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
if (t.endpoints && t.endpoints.length > 0) {
|
|
252
|
+
lines.push({
|
|
253
|
+
text: boxRow(
|
|
254
|
+
source_default.dim("\u25B8") + " " + source_default.white(`${t.endpoints.length} endpoints found`)
|
|
255
|
+
),
|
|
256
|
+
delay: MED
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
} else {
|
|
260
|
+
const truncTarget = data.target.length > 30 ? data.target.slice(0, 27) + "..." : data.target;
|
|
261
|
+
lines.push({
|
|
262
|
+
text: boxRow(
|
|
263
|
+
source_default.dim("\u25B8") + " " + source_default.white(`GET ${truncTarget}`) + source_default.dim(" \u2192 ") + source_default.white("200") + source_default.gray(" (LLM API detected)")
|
|
264
|
+
),
|
|
265
|
+
delay: MED
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
lines.push({ text: boxBottom(true), delay: FAST });
|
|
269
|
+
lines.push({ text: connector(), delay: PAUSE });
|
|
270
|
+
lines.push({ text: boxTop("ATTACK"), delay: PAUSE });
|
|
271
|
+
const vulnerableFindings = data.findings.filter(
|
|
272
|
+
(f) => f.status !== "false-positive"
|
|
273
|
+
);
|
|
274
|
+
if (vulnerableFindings.length > 0) {
|
|
275
|
+
for (const finding of vulnerableFindings.slice(0, 8)) {
|
|
276
|
+
const truncTitle = finding.title.length > 30 ? finding.title.slice(0, 27) + "..." : finding.title;
|
|
277
|
+
let outcome = "VULNERABLE";
|
|
278
|
+
const cat = finding.category;
|
|
279
|
+
if (cat === "system-prompt-extraction") outcome = "LEAKED";
|
|
280
|
+
if (cat === "jailbreak") outcome = "BYPASSED";
|
|
281
|
+
lines.push({
|
|
282
|
+
text: boxRow(
|
|
283
|
+
source_default.dim("\u25B8") + " " + source_default.white(truncTitle) + source_default.dim(" \u2192 ") + " " + outcomeLabel(outcome.toLowerCase())
|
|
284
|
+
),
|
|
285
|
+
delay: MED
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
if (vulnerableFindings.length > 8) {
|
|
289
|
+
lines.push({
|
|
290
|
+
text: boxRow(
|
|
291
|
+
source_default.gray(
|
|
292
|
+
` ... and ${vulnerableFindings.length - 8} more attacks`
|
|
293
|
+
)
|
|
294
|
+
),
|
|
295
|
+
delay: FAST
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
} else {
|
|
299
|
+
lines.push({
|
|
300
|
+
text: boxRow(
|
|
301
|
+
source_default.dim("\u25B8") + " " + source_default.white(`${data.summary.totalAttacks} probes executed`) + source_default.dim(" \u2192 ") + source_default.green("ALL SAFE")
|
|
302
|
+
),
|
|
303
|
+
delay: MED
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
lines.push({ text: boxBottom(true), delay: FAST });
|
|
307
|
+
lines.push({ text: connector(), delay: PAUSE });
|
|
308
|
+
lines.push({ text: boxTop("VERIFY"), delay: PAUSE });
|
|
309
|
+
const confirmed = data.findings.filter(
|
|
310
|
+
(f) => f.status === "confirmed" || f.status === "verified" || f.status === "scored" || f.status === "reported"
|
|
311
|
+
);
|
|
312
|
+
const falsePositives = data.findings.filter(
|
|
313
|
+
(f) => f.status === "false-positive"
|
|
314
|
+
);
|
|
315
|
+
if (confirmed.length > 0 || data.findings.length > 0) {
|
|
316
|
+
const reproduced = confirmed.length > 0 ? confirmed.length : data.findings.length;
|
|
317
|
+
lines.push({
|
|
318
|
+
text: boxRow(
|
|
319
|
+
source_default.green("\u2713") + " " + source_default.white(`Reproduced ${reproduced}/${reproduced} findings`)
|
|
320
|
+
),
|
|
321
|
+
delay: MED
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
if (falsePositives.length > 0) {
|
|
325
|
+
lines.push({
|
|
326
|
+
text: boxRow(
|
|
327
|
+
source_default.red("\u2717") + " " + source_default.white(`Eliminated ${falsePositives.length} false positives`)
|
|
328
|
+
),
|
|
329
|
+
delay: MED
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
if (confirmed.length === 0 && falsePositives.length === 0 && data.findings.length === 0) {
|
|
333
|
+
lines.push({
|
|
334
|
+
text: boxRow(source_default.green("\u2713") + " " + source_default.white("No findings to verify")),
|
|
335
|
+
delay: MED
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
lines.push({ text: boxBottom(true), delay: FAST });
|
|
339
|
+
lines.push({ text: connector(), delay: PAUSE });
|
|
340
|
+
lines.push({ text: boxTop("REPORT"), delay: PAUSE });
|
|
341
|
+
const totalFindings = data.summary.totalFindings;
|
|
342
|
+
if (totalFindings > 0) {
|
|
343
|
+
const parts = [];
|
|
344
|
+
if (data.summary.critical > 0) parts.push(source_default.red.bold(`${data.summary.critical} CRITICAL`));
|
|
345
|
+
if (data.summary.high > 0) parts.push(source_default.redBright(`${data.summary.high} HIGH`));
|
|
346
|
+
if (data.summary.medium > 0) parts.push(source_default.yellow(`${data.summary.medium} MEDIUM`));
|
|
347
|
+
if (data.summary.low > 0) parts.push(source_default.blue(`${data.summary.low} LOW`));
|
|
348
|
+
if (data.summary.info > 0) parts.push(source_default.gray(`${data.summary.info} INFO`));
|
|
349
|
+
lines.push({
|
|
350
|
+
text: boxRow(
|
|
351
|
+
source_default.white(`${totalFindings} verified findings: `) + parts.join(source_default.dim(", "))
|
|
352
|
+
),
|
|
353
|
+
delay: MED
|
|
354
|
+
});
|
|
355
|
+
} else {
|
|
356
|
+
lines.push({
|
|
357
|
+
text: boxRow(source_default.green.bold("0 findings") + source_default.white(" - target appears secure")),
|
|
358
|
+
delay: MED
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
const duration = data.durationMs < 1e3 ? `${data.durationMs}ms` : `${(data.durationMs / 1e3).toFixed(1)}s`;
|
|
362
|
+
lines.push({
|
|
363
|
+
text: boxRow(
|
|
364
|
+
source_default.white(`Completed in ${duration}`) + source_default.dim(" \u2192 ") + source_default.gray("./0-report.json")
|
|
365
|
+
),
|
|
366
|
+
delay: MED
|
|
367
|
+
});
|
|
368
|
+
lines.push({ text: boxBottom(false), delay: FAST });
|
|
369
|
+
return lines;
|
|
370
|
+
}
|
|
371
|
+
async function renderReplay(data) {
|
|
372
|
+
const lines = buildReplayLines(data);
|
|
373
|
+
process.stdout.write("\n");
|
|
374
|
+
process.stdout.write(
|
|
375
|
+
source_default.red.bold(" \u25C6 0") + source_default.gray(" attack replay") + "\n"
|
|
376
|
+
);
|
|
377
|
+
process.stdout.write(
|
|
378
|
+
source_default.dim(" " + "\u2500".repeat(BOX_WIDTH + 1)) + "\n"
|
|
379
|
+
);
|
|
380
|
+
process.stdout.write("\n");
|
|
381
|
+
await sleep(200);
|
|
382
|
+
for (const line of lines) {
|
|
383
|
+
await sleep(line.delay);
|
|
384
|
+
process.stdout.write(" " + line.text + "\n");
|
|
385
|
+
}
|
|
386
|
+
process.stdout.write("\n");
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// packages/cli/src/formatters/timeline.ts
|
|
390
|
+
var TIMELINE_FORMATS = ["json", "csv", "markdown"];
|
|
391
|
+
function isTimelineFormat(value) {
|
|
392
|
+
return TIMELINE_FORMATS.includes(value);
|
|
393
|
+
}
|
|
394
|
+
function formatTimeline(record, format) {
|
|
395
|
+
switch (format) {
|
|
396
|
+
case "json":
|
|
397
|
+
return formatTimelineJson(record);
|
|
398
|
+
case "csv":
|
|
399
|
+
return formatTimelineCsv(record);
|
|
400
|
+
case "markdown":
|
|
401
|
+
return formatTimelineMarkdown(record);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
function formatTimelineJson(record) {
|
|
405
|
+
return JSON.stringify(record, null, 2);
|
|
406
|
+
}
|
|
407
|
+
var CSV_COLUMNS = [
|
|
408
|
+
"timestamp",
|
|
409
|
+
"stage",
|
|
410
|
+
"eventType",
|
|
411
|
+
"agentRole",
|
|
412
|
+
"findingId",
|
|
413
|
+
"action",
|
|
414
|
+
"attackTechniqueIds",
|
|
415
|
+
"attackTactics",
|
|
416
|
+
// Appended, never interleaved with the ATT&CK columns — an importer that
|
|
417
|
+
// only knows the ATT&CK pair keeps working, and the two taxonomies stay
|
|
418
|
+
// visibly distinct in a spreadsheet.
|
|
419
|
+
"atlasTechniqueIds",
|
|
420
|
+
"atlasTactics"
|
|
421
|
+
];
|
|
422
|
+
function formatTimelineCsv(record) {
|
|
423
|
+
const lines = [CSV_COLUMNS.join(",")];
|
|
424
|
+
for (const entry of record.entries) {
|
|
425
|
+
lines.push(
|
|
426
|
+
[
|
|
427
|
+
entry.timestamp,
|
|
428
|
+
entry.stage,
|
|
429
|
+
entry.eventType,
|
|
430
|
+
entry.agentRole ?? "",
|
|
431
|
+
entry.findingId ?? "",
|
|
432
|
+
entry.action,
|
|
433
|
+
entry.techniques.map((t) => t.id).join(" "),
|
|
434
|
+
uniq(entry.techniques.map((t) => t.tactic)).join(" "),
|
|
435
|
+
entry.atlasTechniques.map((t) => t.id).join(" "),
|
|
436
|
+
uniq(entry.atlasTechniques.map((t) => t.tactic)).join(" ")
|
|
437
|
+
].map(csvCell).join(",")
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
return lines.join("\n") + "\n";
|
|
441
|
+
}
|
|
442
|
+
function csvCell(value) {
|
|
443
|
+
if (!/[",\r\n]/.test(value)) return value;
|
|
444
|
+
return `"${value.replace(/"/g, '""')}"`;
|
|
445
|
+
}
|
|
446
|
+
function formatTimelineMarkdown(record) {
|
|
447
|
+
const out = [];
|
|
448
|
+
out.push(`# Forensic timeline \u2014 scan \`${record.scanId}\``);
|
|
449
|
+
out.push("");
|
|
450
|
+
if (record.target) out.push(`- **Target:** ${record.target}`);
|
|
451
|
+
out.push(`- **Generated:** ${record.generatedAt}`);
|
|
452
|
+
out.push(`- **Events:** ${record.eventCount} of ${record.totalEventCount} recorded`);
|
|
453
|
+
if (record.filters.since) out.push(`- **Since:** ${record.filters.since}`);
|
|
454
|
+
if (record.filters.until) out.push(`- **Until:** ${record.filters.until}`);
|
|
455
|
+
if (record.filters.attackOnly) {
|
|
456
|
+
out.push(`- **Filter:** technique-mapped events only (pipeline lifecycle events omitted)`);
|
|
457
|
+
}
|
|
458
|
+
out.push("");
|
|
459
|
+
out.push("All timestamps are UTC (ISO-8601).");
|
|
460
|
+
out.push("");
|
|
461
|
+
out.push(
|
|
462
|
+
"ATT&CK (Enterprise) and ATLAS (AI systems) are separate matrices; a row may carry either, both, or neither."
|
|
463
|
+
);
|
|
464
|
+
out.push("");
|
|
465
|
+
if (record.entries.length === 0) {
|
|
466
|
+
out.push("_No pipeline events recorded for this scan in the selected window._");
|
|
467
|
+
out.push("");
|
|
468
|
+
return out.join("\n");
|
|
469
|
+
}
|
|
470
|
+
out.push("| # | Timestamp (UTC) | Stage | Event | Agent | Finding | Action | ATT&CK | ATLAS |");
|
|
471
|
+
out.push("| --- | --- | --- | --- | --- | --- | --- | --- | --- |");
|
|
472
|
+
record.entries.forEach((entry, i) => {
|
|
473
|
+
out.push(
|
|
474
|
+
"| " + [
|
|
475
|
+
String(i + 1),
|
|
476
|
+
entry.timestamp,
|
|
477
|
+
mdCell(entry.stage),
|
|
478
|
+
mdCell(entry.eventType),
|
|
479
|
+
mdCell(entry.agentRole ?? "\u2014"),
|
|
480
|
+
mdCell(entry.findingId ?? "\u2014"),
|
|
481
|
+
mdCell(entry.action),
|
|
482
|
+
mdTechniques(entry.techniques),
|
|
483
|
+
mdTechniques(entry.atlasTechniques)
|
|
484
|
+
].join(" | ") + " |"
|
|
485
|
+
);
|
|
486
|
+
});
|
|
487
|
+
out.push("");
|
|
488
|
+
return out.join("\n");
|
|
489
|
+
}
|
|
490
|
+
function mdTechniques(techniques) {
|
|
491
|
+
return techniques.length > 0 ? techniques.map(mdTechnique).join(", ") : "\u2014";
|
|
492
|
+
}
|
|
493
|
+
function mdTechnique(technique) {
|
|
494
|
+
const label = mdCell(`${technique.id} ${technique.name}`);
|
|
495
|
+
return technique.url ? `[${label}](${technique.url})` : label;
|
|
496
|
+
}
|
|
497
|
+
function mdCell(value) {
|
|
498
|
+
return value.replace(/\s+/g, " ").replace(/\|/g, "\\|").trim();
|
|
499
|
+
}
|
|
500
|
+
function uniq(values) {
|
|
501
|
+
return [...new Set(values.filter((v) => v.length > 0))];
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// packages/cli/src/formatters/index.ts
|
|
505
|
+
function formatPresentationDocument(document, format) {
|
|
506
|
+
if (format === "json" && document.documentType !== "scan-report") {
|
|
507
|
+
return JSON.stringify(document.report, null, 2);
|
|
508
|
+
}
|
|
509
|
+
const report = document.documentType === "scan-report" ? document.report : document.documentType === "audit-report" ? {
|
|
510
|
+
target: `${document.report.package}@${document.report.version}`,
|
|
511
|
+
scanDepth: "deep",
|
|
512
|
+
startedAt: document.report.startedAt,
|
|
513
|
+
completedAt: document.report.completedAt,
|
|
514
|
+
durationMs: document.report.durationMs,
|
|
515
|
+
summary: document.report.summary,
|
|
516
|
+
findings: document.report.findings,
|
|
517
|
+
warnings: []
|
|
518
|
+
} : {
|
|
519
|
+
target: document.report.repo,
|
|
520
|
+
scanDepth: "deep",
|
|
521
|
+
startedAt: document.report.startedAt,
|
|
522
|
+
completedAt: document.report.completedAt,
|
|
523
|
+
durationMs: document.report.durationMs,
|
|
524
|
+
summary: document.report.summary,
|
|
525
|
+
findings: document.report.findings,
|
|
526
|
+
warnings: document.report.warnings?.map((warning) => ({ stage: "report", message: `[${warning.stage}] ${warning.message}` })) ?? [],
|
|
527
|
+
executionSuccessful: document.report.researchFailed ? false : void 0,
|
|
528
|
+
reviewChecks: document.report.reviewChecks
|
|
529
|
+
};
|
|
530
|
+
switch (format) {
|
|
531
|
+
case "terminal":
|
|
532
|
+
return formatTerminal(report);
|
|
533
|
+
case "json":
|
|
534
|
+
return formatJson(report);
|
|
535
|
+
case "markdown":
|
|
536
|
+
return formatMarkdown(report);
|
|
537
|
+
case "html":
|
|
538
|
+
return formatHtml(report);
|
|
539
|
+
case "sarif":
|
|
540
|
+
return formatSarif(report);
|
|
541
|
+
case "pdf":
|
|
542
|
+
return "[PDF output requires generatePdfReport()]";
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
function formatReport(report, format) {
|
|
546
|
+
return formatPresentationDocument(createScanReportDocument(report), format);
|
|
547
|
+
}
|
|
548
|
+
function formatAuditReport(report, format) {
|
|
549
|
+
return formatPresentationDocument(createAuditReportDocument(report), format);
|
|
550
|
+
}
|
|
551
|
+
function formatReviewReport(report, format) {
|
|
552
|
+
return formatPresentationDocument(createReviewReportDocument(report), format);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
export {
|
|
556
|
+
renderReplay,
|
|
557
|
+
getRuntimeAvailability,
|
|
558
|
+
checkRuntimeAvailability,
|
|
559
|
+
buildShareUrl,
|
|
560
|
+
TIMELINE_FORMATS,
|
|
561
|
+
isTimelineFormat,
|
|
562
|
+
formatTimeline,
|
|
563
|
+
formatReport,
|
|
564
|
+
formatAuditReport,
|
|
565
|
+
formatReviewReport
|
|
566
|
+
};
|
|
@@ -3,7 +3,7 @@ import { createRequire as __0CreateRequire } from "node:module";
|
|
|
3
3
|
const require = __0CreateRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
homeStateDir
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-RZR2XXAK.js";
|
|
7
7
|
import {
|
|
8
8
|
external_exports
|
|
9
9
|
} from "./chunk-VIT5ALXF.js";
|
|
@@ -89,6 +89,7 @@ var workerTurnSchema = external_exports.object({
|
|
|
89
89
|
partial: external_exports.boolean().optional(),
|
|
90
90
|
tools: external_exports.array(external_exports.object({ callIndex: finite, call: toolCallSchema, result: jsonValueSchema, running: external_exports.boolean().optional() }).strict()).max(1e3).optional()
|
|
91
91
|
}).strict();
|
|
92
|
+
var messageAuthorSchema = external_exports.object({ userId: external_exports.string().min(1).max(256), displayName: external_exports.string().min(1).max(256), proposalId: external_exports.string().min(1).max(256).optional() }).strict();
|
|
92
93
|
var workerSchema = external_exports.object({
|
|
93
94
|
id: external_exports.string().max(256),
|
|
94
95
|
parentId: external_exports.string().max(256),
|
|
@@ -97,7 +98,7 @@ var workerSchema = external_exports.object({
|
|
|
97
98
|
task: boundedString,
|
|
98
99
|
transcript: external_exports.array(workerTurnSchema).max(1e4),
|
|
99
100
|
telemetry: external_exports.record(jsonValueSchema).optional(),
|
|
100
|
-
operatorMessages: external_exports.array(external_exports.object({ id: external_exports.string().max(256), text: boundedString, createdAt: external_exports.string().max(64) }).strict()).max(1e4).optional(),
|
|
101
|
+
operatorMessages: external_exports.array(external_exports.object({ id: external_exports.string().max(256), text: boundedString, createdAt: external_exports.string().max(64), author: messageAuthorSchema.optional() }).strict()).max(1e4).optional(),
|
|
101
102
|
summary: boundedString.optional(),
|
|
102
103
|
error: boundedString.optional(),
|
|
103
104
|
model: external_exports.string().max(256).optional(),
|
|
@@ -145,7 +146,8 @@ var consoleStateSchema = external_exports.object({
|
|
|
145
146
|
}).strict().nullable(),
|
|
146
147
|
workers: external_exports.array(workerSchema).max(1e3),
|
|
147
148
|
compaction: jsonValueSchema.nullable(),
|
|
148
|
-
queuedMessages: external_exports.array(external_exports.object({ id: external_exports.string().max(256), text: boundedString, createdAt: external_exports.string().max(64) }).strict()).max(20),
|
|
149
|
+
queuedMessages: external_exports.array(external_exports.object({ id: external_exports.string().max(256), text: boundedString, createdAt: external_exports.string().max(64), author: messageAuthorSchema.optional() }).strict()).max(20),
|
|
150
|
+
userAttributions: external_exports.array(external_exports.object({ text: boundedString, author: messageAuthorSchema.optional() }).strict()).max(1e4).optional(),
|
|
149
151
|
focusedFindingId: external_exports.string().max(256).optional(),
|
|
150
152
|
stagedPrompt: boundedString.optional()
|
|
151
153
|
}).strict();
|
|
@@ -3,14 +3,18 @@ import { createRequire as __0CreateRequire } from "node:module";
|
|
|
3
3
|
const require = __0CreateRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
VERSION
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-RZR2XXAK.js";
|
|
7
7
|
|
|
8
8
|
// packages/cli/src/tui/runtime.ts
|
|
9
|
+
function getReleaseChannel(env = process.env) {
|
|
10
|
+
if (env["ZERO_DEV_SOURCE_ROOT"]?.trim() || env["NODE_ENV"] === "development") return "dev";
|
|
11
|
+
return true ? "beta" : "dev";
|
|
12
|
+
}
|
|
9
13
|
function getRuntimeMetadata() {
|
|
10
14
|
const bun = isBunRuntime();
|
|
11
15
|
return {
|
|
12
16
|
cliVersion: VERSION,
|
|
13
|
-
releaseChannel:
|
|
17
|
+
releaseChannel: getReleaseChannel(),
|
|
14
18
|
engine: bun ? "Bun" : "Node.js",
|
|
15
19
|
engineVersion: bun ? process.versions.bun ?? "unknown" : process.version,
|
|
16
20
|
platform: process.platform,
|
|
@@ -21,10 +25,11 @@ function isBunRuntime() {
|
|
|
21
25
|
return typeof globalThis === "object" && globalThis !== null && "Bun" in globalThis;
|
|
22
26
|
}
|
|
23
27
|
function canUseOpenTui() {
|
|
24
|
-
return
|
|
28
|
+
return false;
|
|
25
29
|
}
|
|
26
30
|
|
|
27
31
|
export {
|
|
32
|
+
getReleaseChannel,
|
|
28
33
|
getRuntimeMetadata,
|
|
29
34
|
isBunRuntime,
|
|
30
35
|
canUseOpenTui
|
|
@@ -3,13 +3,13 @@ import { createRequire as __0CreateRequire } from "node:module";
|
|
|
3
3
|
const require = __0CreateRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
createJournalWriter
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-YORL5S5V.js";
|
|
7
7
|
import {
|
|
8
8
|
verifyKernelFinding
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-DNV3ZMPX.js";
|
|
10
10
|
import {
|
|
11
11
|
homeStateDir
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-RZR2XXAK.js";
|
|
13
13
|
|
|
14
14
|
// packages/core/dist/cve/adapt-loop.js
|
|
15
15
|
import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
@@ -3,7 +3,7 @@ import { createRequire as __0CreateRequire } from "node:module";
|
|
|
3
3
|
const require = __0CreateRequire(import.meta.url);
|
|
4
4
|
import {
|
|
5
5
|
createPresentationEvent
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-RZR2XXAK.js";
|
|
7
7
|
|
|
8
8
|
// packages/core/dist/events/bus.js
|
|
9
9
|
function presentationEventSink(sink, options = {}) {
|
|
@@ -9,7 +9,10 @@ import {
|
|
|
9
9
|
import {
|
|
10
10
|
extractFileRefs,
|
|
11
11
|
redactSensitiveHeaders
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-IK27KMVV.js";
|
|
13
|
+
import {
|
|
14
|
+
getFindingPriority
|
|
15
|
+
} from "./chunk-RZR2XXAK.js";
|
|
13
16
|
import {
|
|
14
17
|
__toESM
|
|
15
18
|
} from "./chunk-VCSFCHAJ.js";
|
|
@@ -906,7 +909,7 @@ function impactForSeverity(severity) {
|
|
|
906
909
|
function impactLine(finding) {
|
|
907
910
|
const base = impactForSeverity(finding.severity);
|
|
908
911
|
const a = finding.impactAssessment;
|
|
909
|
-
if (!a)
|
|
912
|
+
if (!a || !getFindingPriority(finding).assessed)
|
|
910
913
|
return base;
|
|
911
914
|
const gain = {
|
|
912
915
|
rce: "remote code execution",
|