pwnkit-cli 0.3.1 → 0.3.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.
Files changed (91) hide show
  1. package/dist/commands/audit.d.ts +3 -0
  2. package/dist/commands/audit.d.ts.map +1 -0
  3. package/dist/commands/audit.js +32 -0
  4. package/dist/commands/audit.js.map +1 -0
  5. package/dist/commands/findings.d.ts +3 -0
  6. package/dist/commands/findings.d.ts.map +1 -0
  7. package/dist/commands/findings.js +110 -0
  8. package/dist/commands/findings.js.map +1 -0
  9. package/dist/commands/history.d.ts +3 -0
  10. package/dist/commands/history.d.ts.map +1 -0
  11. package/dist/commands/history.js +34 -0
  12. package/dist/commands/history.js.map +1 -0
  13. package/dist/commands/index.d.ts +7 -0
  14. package/dist/commands/index.d.ts.map +1 -0
  15. package/dist/commands/index.js +7 -0
  16. package/dist/commands/index.js.map +1 -0
  17. package/dist/commands/replay.d.ts +3 -0
  18. package/dist/commands/replay.d.ts.map +1 -0
  19. package/dist/commands/replay.js +83 -0
  20. package/dist/commands/replay.js.map +1 -0
  21. package/dist/commands/review.d.ts +3 -0
  22. package/dist/commands/review.d.ts.map +1 -0
  23. package/dist/commands/review.js +30 -0
  24. package/dist/commands/review.js.map +1 -0
  25. package/dist/commands/run.d.ts +16 -0
  26. package/dist/commands/run.d.ts.map +1 -0
  27. package/dist/commands/run.js +83 -0
  28. package/dist/commands/run.js.map +1 -0
  29. package/dist/commands/scan.d.ts +3 -0
  30. package/dist/commands/scan.d.ts.map +1 -0
  31. package/dist/commands/scan.js +187 -0
  32. package/dist/commands/scan.js.map +1 -0
  33. package/dist/event-handler.d.ts +19 -0
  34. package/dist/event-handler.d.ts.map +1 -0
  35. package/dist/event-handler.js +63 -0
  36. package/dist/event-handler.js.map +1 -0
  37. package/dist/formatters/index.d.ts +14 -0
  38. package/dist/formatters/index.d.ts.map +1 -0
  39. package/dist/formatters/index.js +56 -0
  40. package/dist/formatters/index.js.map +1 -0
  41. package/dist/formatters/json.d.ts +3 -0
  42. package/dist/formatters/json.d.ts.map +1 -0
  43. package/dist/formatters/json.js +4 -0
  44. package/dist/formatters/json.js.map +1 -0
  45. package/dist/formatters/markdown.d.ts +3 -0
  46. package/dist/formatters/markdown.d.ts.map +1 -0
  47. package/dist/formatters/markdown.js +90 -0
  48. package/dist/formatters/markdown.js.map +1 -0
  49. package/dist/formatters/replay.d.ts +24 -0
  50. package/dist/formatters/replay.d.ts.map +1 -0
  51. package/dist/formatters/replay.js +357 -0
  52. package/dist/formatters/replay.js.map +1 -0
  53. package/dist/formatters/terminal.d.ts +4 -0
  54. package/dist/formatters/terminal.d.ts.map +1 -0
  55. package/dist/formatters/terminal.js +190 -0
  56. package/dist/formatters/terminal.js.map +1 -0
  57. package/dist/index.d.ts +3 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +128 -60851
  60. package/dist/index.js.map +1 -0
  61. package/dist/spinner.d.ts +16 -0
  62. package/dist/spinner.d.ts.map +1 -0
  63. package/dist/spinner.js +97 -0
  64. package/dist/spinner.js.map +1 -0
  65. package/dist/ui/ScanUI.d.ts +37 -0
  66. package/dist/ui/ScanUI.d.ts.map +1 -0
  67. package/dist/ui/ScanUI.js +58 -0
  68. package/dist/ui/ScanUI.js.map +1 -0
  69. package/dist/ui/renderScan.d.ts +21 -0
  70. package/dist/ui/renderScan.d.ts.map +1 -0
  71. package/dist/ui/renderScan.js +191 -0
  72. package/dist/ui/renderScan.js.map +1 -0
  73. package/dist/utils.d.ts +12 -0
  74. package/dist/utils.d.ts.map +1 -0
  75. package/dist/utils.js +40 -0
  76. package/dist/utils.js.map +1 -0
  77. package/package.json +20 -50
  78. package/LICENSE +0 -188
  79. package/README.md +0 -324
  80. package/dist/attacks/data-exfiltration/pii-leakage.yaml +0 -27
  81. package/dist/attacks/encoding-bypass/base64-encoding.yaml +0 -24
  82. package/dist/attacks/jailbreak/dan-roleplay.yaml +0 -27
  83. package/dist/attacks/jailbreak/hypothetical-scenario.yaml +0 -25
  84. package/dist/attacks/jailbreak/multilingual-bypass.yaml +0 -22
  85. package/dist/attacks/output-manipulation/harmful-content.yaml +0 -25
  86. package/dist/attacks/prompt-injection/context-manipulation.yaml +0 -32
  87. package/dist/attacks/prompt-injection/direct-injection.yaml +0 -28
  88. package/dist/attacks/prompt-injection/indirect-injection.yaml +0 -33
  89. package/dist/attacks/system-prompt-extraction/direct-ask.yaml +0 -30
  90. package/dist/attacks/system-prompt-extraction/markdown-exfil.yaml +0 -26
  91. package/dist/attacks/tool-misuse/ssrf-via-tools.yaml +0 -27
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export interface pwnkitSpinner {
2
+ /** Begin the animation. Idempotent — calling twice is safe. */
3
+ start(): pwnkitSpinner;
4
+ /** Freeze the spinner and clear its line. */
5
+ stop(): pwnkitSpinner;
6
+ /** Replace the trailing text without restarting. */
7
+ update(text: string): pwnkitSpinner;
8
+ /** Stop with a success marker. */
9
+ succeed(text?: string): pwnkitSpinner;
10
+ /** Stop with a failure marker. */
11
+ fail(text?: string): pwnkitSpinner;
12
+ /** Stop with a warning marker. */
13
+ warn(text?: string): pwnkitSpinner;
14
+ }
15
+ export declare function createpwnkitSpinner(text: string): pwnkitSpinner;
16
+ //# sourceMappingURL=spinner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../src/spinner.ts"],"names":[],"mappings":"AA0BA,MAAM,WAAW,aAAa;IAC5B,+DAA+D;IAC/D,KAAK,IAAI,aAAa,CAAC;IACvB,6CAA6C;IAC7C,IAAI,IAAI,aAAa,CAAC;IACtB,oDAAoD;IACpD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAAC;IACpC,kCAAkC;IAClC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC;IACtC,kCAAkC;IAClC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC;IACnC,kCAAkC;IAClC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC;CACpC;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CA8E/D"}
@@ -0,0 +1,97 @@
1
+ import chalk from "chalk";
2
+ /**
3
+ * pwnkit branded CLI spinner.
4
+ *
5
+ * Uses the fang diamond motif with eye-blink animation frames,
6
+ * rendered via raw stdout writes for zero-dependency terminal animation.
7
+ */
8
+ // ── Frames ──
9
+ // The fang cycles through diamond variants while the "eyes" blink.
10
+ // Keeps it minimal and on-brand: crimson diamond with subtle state changes.
11
+ const FRAMES = [
12
+ "◆", // solid — eyes open
13
+ "◆", // solid — eyes open (hold)
14
+ "◇", // outline — blink
15
+ "◆", // solid — eyes open
16
+ "◈", // enclosed — pulse
17
+ "◆", // solid — eyes open
18
+ "◆", // solid — eyes open (hold)
19
+ "◇", // outline — blink
20
+ ];
21
+ const INTERVAL_MS = 120;
22
+ export function createpwnkitSpinner(text) {
23
+ let frameIndex = 0;
24
+ let timer = null;
25
+ let currentText = text;
26
+ let lineLength = 0;
27
+ const stream = process.stderr;
28
+ const isInteractive = stream.isTTY !== false;
29
+ function clearLine() {
30
+ if (!isInteractive)
31
+ return;
32
+ stream.write("\r" + " ".repeat(lineLength) + "\r");
33
+ }
34
+ function render() {
35
+ const frame = FRAMES[frameIndex % FRAMES.length];
36
+ const line = ` ${chalk.red(frame)} ${chalk.gray(currentText)}`;
37
+ clearLine();
38
+ stream.write(line);
39
+ // Track raw length (without ANSI codes) for clearing
40
+ lineLength = stripAnsi(line).length;
41
+ frameIndex++;
42
+ }
43
+ function stopTimer() {
44
+ if (timer !== null) {
45
+ clearInterval(timer);
46
+ timer = null;
47
+ }
48
+ }
49
+ function writeFinalLine(icon, msg) {
50
+ stopTimer();
51
+ clearLine();
52
+ stream.write(` ${icon} ${msg}\n`);
53
+ lineLength = 0;
54
+ }
55
+ const spinner = {
56
+ start() {
57
+ if (timer !== null)
58
+ return spinner;
59
+ frameIndex = 0;
60
+ render();
61
+ timer = setInterval(render, INTERVAL_MS);
62
+ return spinner;
63
+ },
64
+ stop() {
65
+ stopTimer();
66
+ clearLine();
67
+ return spinner;
68
+ },
69
+ update(newText) {
70
+ currentText = newText;
71
+ return spinner;
72
+ },
73
+ succeed(msg) {
74
+ const finalText = msg ?? currentText;
75
+ writeFinalLine(chalk.green("✓"), chalk.gray(finalText));
76
+ return spinner;
77
+ },
78
+ fail(msg) {
79
+ const finalText = msg ?? currentText;
80
+ writeFinalLine(chalk.red("✗"), chalk.red(finalText));
81
+ return spinner;
82
+ },
83
+ warn(msg) {
84
+ const finalText = msg ?? currentText;
85
+ writeFinalLine(chalk.yellow("!"), chalk.yellow(finalText));
86
+ return spinner;
87
+ },
88
+ };
89
+ return spinner;
90
+ }
91
+ // ── Helpers ──
92
+ /** Strip ANSI escape codes to get the visible character count. */
93
+ function stripAnsi(str) {
94
+ // eslint-disable-next-line no-control-regex
95
+ return str.replace(/\x1B\[[0-9;]*m/g, "");
96
+ }
97
+ //# sourceMappingURL=spinner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.js","sourceRoot":"","sources":["../src/spinner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ export type StageStatusKind = "pending" | "running" | "done" | "error";
2
+ export interface StageFinding {
3
+ severity: string;
4
+ title: string;
5
+ }
6
+ export interface StageState {
7
+ id: string;
8
+ label: string;
9
+ status: StageStatusKind;
10
+ detail?: string;
11
+ duration?: number;
12
+ actions: string[];
13
+ findings: StageFinding[];
14
+ error?: string;
15
+ }
16
+ export interface ScanSummary {
17
+ critical: number;
18
+ high: number;
19
+ medium: number;
20
+ low: number;
21
+ info?: number;
22
+ duration?: number;
23
+ shareUrl?: string;
24
+ }
25
+ export interface ScanEvent {
26
+ type: string;
27
+ stage?: string;
28
+ message: string;
29
+ data?: unknown;
30
+ }
31
+ export interface ScanUIProps {
32
+ stages: StageState[];
33
+ summary: ScanSummary | null;
34
+ thinking: string | null;
35
+ }
36
+ export declare function ScanUI({ stages, summary, thinking }: ScanUIProps): import("react/jsx-runtime").JSX.Element;
37
+ //# sourceMappingURL=ScanUI.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScanUI.d.ts","sourceRoot":"","sources":["../../src/ui/ScanUI.tsx"],"names":[],"mappings":"AAMA,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;AAEvE,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AA8JD,wBAAgB,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,WAAW,2CAchE"}
@@ -0,0 +1,58 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import Spinner from "ink-spinner";
4
+ // ── Colors ──
5
+ const CRIMSON = "#DC2626";
6
+ const GREEN = "#22C55E";
7
+ const GRAY = "#6B7280";
8
+ const YELLOW = "#EAB308";
9
+ const CYAN = "#06B6D4";
10
+ function severityColor(s) {
11
+ switch (s.toLowerCase()) {
12
+ case "critical":
13
+ case "high": return CRIMSON;
14
+ case "medium": return YELLOW;
15
+ case "low": return CYAN;
16
+ default: return GRAY;
17
+ }
18
+ }
19
+ function formatDuration(ms) {
20
+ return ms < 1000 ? `${ms}ms` : `${(ms / 1000).toFixed(1)}s`;
21
+ }
22
+ // ── Stage Row ──
23
+ function StageRow({ stage }) {
24
+ const icon = stage.status === "done" ? (_jsx(Text, { color: GREEN, children: "✓" })) : stage.status === "running" ? (_jsx(Text, { color: CRIMSON, children: _jsx(Spinner, { type: "dots" }) })) : stage.status === "error" ? (_jsx(Text, { color: CRIMSON, children: "✗" })) : (_jsx(Text, { color: GRAY, children: "◌" }));
25
+ // Compute verify confirmed count
26
+ let verifyCount = "";
27
+ if (stage.id === "verify" && stage.status === "done" && stage.actions.length > 0) {
28
+ const confirmed = stage.actions.filter((a) => a.startsWith("\u2713")).length;
29
+ const total = stage.actions.filter((a) => a.startsWith("\u2713") || a.startsWith("\u2717")).length;
30
+ if (total > 0) {
31
+ verifyCount = `${confirmed}/${total} confirmed`;
32
+ }
33
+ }
34
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { gap: 1, children: [_jsx(Text, { children: " " }), icon, _jsx(Text, { bold: true, color: stage.status === "pending" ? GRAY : undefined, children: stage.label.padEnd(12) }), verifyCount ? (_jsx(Text, { color: GREEN, children: verifyCount })) : stage.detail ? (_jsx(Text, { color: stage.status === "done" ? GRAY : undefined, dimColor: stage.status === "done", children: stage.detail })) : null, stage.duration !== undefined && (_jsxs(Text, { color: GRAY, children: [" ", formatDuration(stage.duration)] }))] }), stage.actions.length > 0 && (_jsx(Box, { flexDirection: "column", marginLeft: 6, children: stage.actions.map((action, i) => {
35
+ // Verify stage: confirmed (✓) green+bold, rejected (✗) dim red+strikethrough
36
+ if (stage.id === "verify") {
37
+ const isConfirmed = action.startsWith("\u2713");
38
+ const isRejected = action.startsWith("\u2717");
39
+ if (isConfirmed) {
40
+ return (_jsxs(Text, { color: GREEN, bold: true, children: ["→ ", action] }, i));
41
+ }
42
+ if (isRejected) {
43
+ return (_jsxs(Text, { color: CRIMSON, dimColor: true, strikethrough: true, children: ["→ ", action] }, i));
44
+ }
45
+ return (_jsxs(Text, { color: CYAN, children: ["→ ", action] }, i));
46
+ }
47
+ return (_jsxs(Text, { color: stage.status === "done" ? GRAY : CYAN, dimColor: stage.status === "done", children: ["→ ", action] }, i));
48
+ }) })), stage.status === "running" && stage.actions.length === 0 && stage.detail && (_jsx(Box, { marginLeft: 6, children: _jsx(Text, { color: GRAY, dimColor: true, children: "" }) })), stage.findings.length > 0 && (_jsx(Box, { flexDirection: "column", marginLeft: 6, children: stage.findings.map((f, i) => (_jsxs(Text, { color: severityColor(f.severity), children: ["⚡ ", _jsxs(Text, { bold: true, children: ["[", f.severity, "]"] }), " ", f.title] }, i))) }))] }));
49
+ }
50
+ // ── Summary ──
51
+ function SummaryBar({ summary }) {
52
+ return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: GRAY, children: " ──────────────────────────────────────" }), _jsxs(Box, { marginLeft: 2, gap: 2, children: [_jsxs(Text, { color: summary.critical > 0 ? CRIMSON : GRAY, bold: summary.critical > 0, children: [summary.critical, " critical"] }), _jsxs(Text, { color: summary.high > 0 ? CRIMSON : GRAY, bold: summary.high > 0, children: [summary.high, " high"] }), _jsxs(Text, { color: summary.medium > 0 ? YELLOW : GRAY, bold: summary.medium > 0, children: [summary.medium, " medium"] }), _jsxs(Text, { color: GRAY, children: [summary.low, " low"] })] }), summary.duration !== undefined && (_jsx(Box, { marginLeft: 2, children: _jsx(Text, { color: GRAY, children: formatDuration(summary.duration) }) })), summary.shareUrl && (_jsxs(Box, { marginTop: 1, marginLeft: 2, children: [_jsx(Text, { color: GRAY, children: "Share: " }), _jsx(Text, { color: CYAN, children: summary.shareUrl })] }))] }));
53
+ }
54
+ // ── Main ──
55
+ export function ScanUI({ stages, summary, thinking }) {
56
+ return (_jsxs(Box, { flexDirection: "column", children: [stages.map((stage) => (_jsx(StageRow, { stage: stage }, stage.id))), thinking && (_jsx(Box, { marginLeft: 6, children: _jsx(Text, { color: GRAY, dimColor: true, wrap: "truncate", children: thinking.slice(-80) }) })), summary && _jsx(SummaryBar, { summary: summary })] }));
57
+ }
58
+ //# sourceMappingURL=ScanUI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScanUI.js","sourceRoot":"","sources":["../../src/ui/ScanUI.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { ScanEvent, ScanSummary } from "./ScanUI.js";
2
+ export type { ScanEvent, ScanSummary };
3
+ export type CommandMode = "audit" | "review" | "scan";
4
+ interface RenderScanOptions {
5
+ version: string;
6
+ target: string;
7
+ depth: string;
8
+ mode: CommandMode;
9
+ }
10
+ interface RenderScanResult {
11
+ onEvent: (event: {
12
+ type: string;
13
+ stage?: string;
14
+ message: string;
15
+ data?: unknown;
16
+ }) => void;
17
+ waitForExit: () => Promise<void>;
18
+ setReport: (report: Record<string, unknown>) => void;
19
+ }
20
+ export declare function renderScanUI(opts: RenderScanOptions): RenderScanResult;
21
+ //# sourceMappingURL=renderScan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderScan.d.ts","sourceRoot":"","sources":["../../src/ui/renderScan.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAA+B,MAAM,aAAa,CAAC;AAEvF,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC;AACvC,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEtD,UAAU,iBAAiB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,WAAW,CAAC;CACnB;AAED,UAAU,gBAAgB;IACxB,OAAO,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC5F,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;CACtD;AAYD,wBAAgB,YAAY,CAAC,IAAI,EAAE,iBAAiB,GAAG,gBAAgB,CAuLtE"}
@@ -0,0 +1,191 @@
1
+ import React, { useState, useEffect } from "react";
2
+ import { render } from "ink";
3
+ import cfonts from "cfonts";
4
+ import { VERSION } from "@pwnkit/shared";
5
+ import { ScanUI } from "./ScanUI.js";
6
+ import { buildShareUrl } from "../utils.js";
7
+ // 4 stages — research (discover+attack+PoC) then blind verify
8
+ function getStages() {
9
+ return [
10
+ { id: "prepare", label: "Prepare", status: "pending", actions: [], findings: [] },
11
+ { id: "analyze", label: "Analyze", status: "pending", actions: [], findings: [] },
12
+ { id: "research", label: "Research", status: "pending", actions: [], findings: [] },
13
+ { id: "verify", label: "Verify", status: "pending", actions: [], findings: [] },
14
+ ];
15
+ }
16
+ export function renderScanUI(opts) {
17
+ let stages = getStages();
18
+ let summary = null;
19
+ let thinking = null;
20
+ let rerender = null;
21
+ // Static banner — printed once before Ink takes over (won't re-render)
22
+ const r = "\x1b[31m"; // red/crimson
23
+ const d = "\x1b[2m"; // dim
24
+ const b = "\x1b[1m"; // bold
25
+ const x = "\x1b[0m"; // reset
26
+ // Banner
27
+ console.log("");
28
+ try {
29
+ cfonts.say(`pwnkit|v${VERSION}`, {
30
+ font: "tiny",
31
+ colors: ["red", "gray"],
32
+ space: false,
33
+ });
34
+ }
35
+ catch {
36
+ console.log(` ${r}${b}pwnkit${x} ${d}v${VERSION}${x}`);
37
+ }
38
+ const modeLabel = opts.mode === "audit" ? "auditing npm package"
39
+ : opts.mode === "review" ? "reviewing source code"
40
+ : "scanning target";
41
+ console.log(` ${d}${modeLabel} ${x}${b}${opts.target}${x}`);
42
+ console.log("");
43
+ function App() {
44
+ const [tick, setTick] = useState(0);
45
+ useEffect(() => {
46
+ rerender = () => setTick((t) => t + 1);
47
+ return () => { rerender = null; };
48
+ }, []);
49
+ return React.createElement(ScanUI, { stages, summary, thinking });
50
+ }
51
+ const instance = render(React.createElement(App));
52
+ function updateStage(id, updater) {
53
+ stages = stages.map((s) => (s.id === id ? updater(s) : s));
54
+ rerender?.();
55
+ }
56
+ // Map event stage names to TUI stage IDs
57
+ function mapStageId(coreStage, msg) {
58
+ // Direct matches
59
+ if (coreStage === "prepare" || coreStage === "analyze" || coreStage === "research" || coreStage === "verify") {
60
+ return coreStage;
61
+ }
62
+ // Old names → research (backwards compat)
63
+ if (coreStage === "discover" || coreStage === "attack") {
64
+ return "research";
65
+ }
66
+ // Legacy "agent" → research
67
+ if (coreStage === "agent") {
68
+ return "research";
69
+ }
70
+ // Old event names (backwards compat)
71
+ if (coreStage === "discovery" || coreStage === "source-analysis") {
72
+ if (msg.toLowerCase().includes("install") || msg.toLowerCase().includes("clone"))
73
+ return "prepare";
74
+ return "analyze";
75
+ }
76
+ if (coreStage === "report")
77
+ return undefined;
78
+ return coreStage;
79
+ }
80
+ function onEvent(event) {
81
+ const msg = event.message ?? "";
82
+ const stageId = mapStageId(event.stage, msg);
83
+ if (event.type === "stage:start") {
84
+ if (!stageId)
85
+ return;
86
+ const current = stages.find((s) => s.id === stageId);
87
+ if (current?.status === "running") {
88
+ // Already running — this is a tool call / sub-action
89
+ updateStage(stageId, (s) => ({
90
+ ...s,
91
+ actions: [...s.actions, msg].slice(-6),
92
+ }));
93
+ }
94
+ else {
95
+ // New stage start
96
+ let detail = msg;
97
+ if (stageId === "agent") {
98
+ // Show which runtime was picked
99
+ const lower = msg.toLowerCase();
100
+ if (lower.includes("claude"))
101
+ detail = "Claude Code (auto-detected)";
102
+ else if (lower.includes("codex"))
103
+ detail = "Codex (auto-detected)";
104
+ else if (lower.includes("gemini"))
105
+ detail = "Gemini (auto-detected)";
106
+ else if (lower.includes("agentic") || lower.includes("api"))
107
+ detail = "API agent (OpenRouter)";
108
+ }
109
+ updateStage(stageId, (s) => ({ ...s, status: "running", detail }));
110
+ }
111
+ return;
112
+ }
113
+ if (event.type === "stage:end") {
114
+ if (!stageId)
115
+ return;
116
+ // Truncate long detail text and clean up
117
+ let detail = msg.length > 60 ? msg.slice(0, 60) + "..." : msg;
118
+ updateStage(stageId, (s) => ({
119
+ ...s,
120
+ status: "done",
121
+ detail,
122
+ actions: stageId === "verify" ? s.actions : s.actions.slice(0, 4),
123
+ duration: event.data?.durationMs ?? s.duration,
124
+ }));
125
+ return;
126
+ }
127
+ if (event.type === "finding") {
128
+ const running = stages.find((s) => s.status === "running") ?? stages.find((s) => s.id === "research");
129
+ if (running) {
130
+ const severity = event.data?.severity ?? "info";
131
+ // Clean up title — remove [severity] prefix if present, truncate
132
+ let title = msg.replace(/^\[[\w]+\]\s*/g, "").trim();
133
+ if (title.length > 60)
134
+ title = title.slice(0, 60) + "...";
135
+ if (!title || title === "Untitled finding")
136
+ title = "Finding from AI analysis";
137
+ updateStage(running.id, (s) => ({
138
+ ...s,
139
+ findings: [...s.findings, { severity, title }],
140
+ }));
141
+ }
142
+ return;
143
+ }
144
+ if (event.type === "verify:result") {
145
+ const data = event.data;
146
+ const confirmed = data?.confirmed;
147
+ const title = data?.title ?? event.message;
148
+ const reason = data?.reason;
149
+ const label = confirmed ? `\u2713 ${title}` : `\u2717 ${title}${reason ? ` \u2014 ${reason}` : ""}`;
150
+ updateStage("verify", (s) => ({
151
+ ...s,
152
+ actions: [...s.actions, label],
153
+ }));
154
+ return;
155
+ }
156
+ if (event.type === "error") {
157
+ const running = stages.find((s) => s.status === "running");
158
+ if (running) {
159
+ updateStage(running.id, (s) => ({ ...s, status: "error", error: msg }));
160
+ }
161
+ return;
162
+ }
163
+ // Thinking tokens
164
+ if (event.type === "thinking") {
165
+ thinking = msg;
166
+ rerender?.();
167
+ }
168
+ }
169
+ function setReport(report) {
170
+ stages = stages.map((s) => s.status === "pending" ? { ...s, status: "done", detail: "—" } :
171
+ s.status === "running" ? { ...s, status: "done" } : s);
172
+ const rep = report;
173
+ summary = {
174
+ critical: rep.summary?.critical ?? 0,
175
+ high: rep.summary?.high ?? 0,
176
+ medium: rep.summary?.medium ?? 0,
177
+ low: rep.summary?.low ?? 0,
178
+ info: rep.summary?.info ?? 0,
179
+ duration: rep.durationMs,
180
+ shareUrl: buildShareUrl(rep),
181
+ };
182
+ rerender?.();
183
+ }
184
+ async function waitForExit() {
185
+ await new Promise((r) => setTimeout(r, 150));
186
+ instance.unmount();
187
+ await instance.waitUntilExit();
188
+ }
189
+ return { onEvent, waitForExit, setReport };
190
+ }
191
+ //# sourceMappingURL=renderScan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderScan.js","sourceRoot":"","sources":["../../src/ui/renderScan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { ScanReport, AuditReport, ReviewReport, ScanDepth } from "@pwnkit/shared";
2
+ /**
3
+ * Check if an API key or CLI runtime is available for AI analysis.
4
+ * Prints a warning if not — the scan will still run but without AI.
5
+ */
6
+ export declare function checkRuntimeAvailability(): void;
7
+ /**
8
+ * Encode a report as a base64url-encoded gzipped JSON string for use in a share URL.
9
+ */
10
+ export declare function buildShareUrl(report: ScanReport | AuditReport | ReviewReport): string;
11
+ export declare function depthLabel(depth: ScanDepth): string;
12
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEvF;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CAgB/C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,YAAY,GAAG,MAAM,CAKrF;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CASnD"}
package/dist/utils.js ADDED
@@ -0,0 +1,40 @@
1
+ import { gzipSync } from "zlib";
2
+ import chalk from "chalk";
3
+ /**
4
+ * Check if an API key or CLI runtime is available for AI analysis.
5
+ * Prints a warning if not — the scan will still run but without AI.
6
+ */
7
+ export function checkRuntimeAvailability() {
8
+ const hasApiKey = !!(process.env.OPENROUTER_API_KEY ||
9
+ process.env.ANTHROPIC_API_KEY ||
10
+ process.env.OPENAI_API_KEY);
11
+ if (!hasApiKey) {
12
+ console.log("");
13
+ console.log(chalk.yellow(" Warning: No API key set. AI agent analysis will be skipped."));
14
+ console.log(chalk.gray(" Set one of:"));
15
+ console.log(chalk.gray(" export OPENROUTER_API_KEY=sk-or-..."));
16
+ console.log(chalk.gray(" export ANTHROPIC_API_KEY=sk-ant-..."));
17
+ console.log(chalk.gray(" export OPENAI_API_KEY=sk-..."));
18
+ console.log("");
19
+ }
20
+ }
21
+ /**
22
+ * Encode a report as a base64url-encoded gzipped JSON string for use in a share URL.
23
+ */
24
+ export function buildShareUrl(report) {
25
+ const json = JSON.stringify(report);
26
+ const compressed = gzipSync(Buffer.from(json, "utf-8"));
27
+ const b64 = compressed.toString("base64url");
28
+ return `https://pwnkit.com/r#${b64}`;
29
+ }
30
+ export function depthLabel(depth) {
31
+ switch (depth) {
32
+ case "quick":
33
+ return "~5 probes";
34
+ case "default":
35
+ return "~50 probes";
36
+ case "deep":
37
+ return "full coverage";
38
+ }
39
+ }
40
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAChC,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B;;;GAGG;AACH,MAAM,UAAU,wBAAwB;IACtC,MAAM,SAAS,GAAG,CAAC,CAAC,CAClB,OAAO,CAAC,GAAG,CAAC,kBAAkB;QAC9B,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAC7B,OAAO,CAAC,GAAG,CAAC,cAAc,CAC3B,CAAC;IAEF,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,+DAA+D,CAAC,CAAC,CAAC;QAC3F,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC,CAAC;QACnE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC,CAAC;QACnE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC,CAAC;QAC5D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,MAA+C;IAC3E,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC7C,OAAO,wBAAwB,GAAG,EAAE,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAgB;IACzC,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,OAAO;YACV,OAAO,WAAW,CAAC;QACrB,KAAK,SAAS;YACZ,OAAO,YAAY,CAAC;QACtB,KAAK,MAAM;YACT,OAAO,eAAe,CAAC;IAC3B,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,65 +1,35 @@
1
1
  {
2
2
  "name": "pwnkit-cli",
3
+ "version": "0.3.2",
3
4
  "type": "module",
4
- "version": "0.3.1",
5
- "description": "AI-powered agentic security scanner. Scan endpoints, audit packages, review source code. Autonomous agents discover, attack, verify, and report.",
6
5
  "bin": {
7
- "pwnkit": "dist/index.js"
6
+ "pwnkit-cli": "dist/index.js"
8
7
  },
9
8
  "files": [
10
- "LICENSE",
11
- "README.md",
12
- "package.json",
13
9
  "dist"
14
10
  ],
15
11
  "scripts": {
16
- "build": "pnpm -r build && pnpm run build:bundle",
17
- "build:bundle": "node ./scripts/bundle-cli.mjs",
18
- "dev": "pnpm -r --parallel dev",
19
- "lint": "pnpm -r exec tsc --noEmit",
20
- "test": "pnpm --filter @pwnkit/test-targets test",
21
- "clean": "pnpm -r clean",
22
- "vulnerable": "PORT=43100 pnpm --filter @pwnkit/test-targets vulnerable",
23
- "safe": "PORT=43101 pnpm --filter @pwnkit/test-targets safe"
24
- },
25
- "keywords": [
26
- "ai",
27
- "application-security",
28
- "mcp",
29
- "owasp",
30
- "security",
31
- "red-team",
32
- "llm",
33
- "prompt-injection"
34
- ],
35
- "author": "Peak Twilight",
36
- "homepage": "https://pwnkit.com",
37
- "bugs": {
38
- "url": "https://github.com/peaktwilight/pwnkit/issues"
39
- },
40
- "repository": {
41
- "type": "git",
42
- "url": "git+https://github.com/peaktwilight/pwnkit.git"
43
- },
44
- "license": "Apache-2.0",
45
- "engines": {
46
- "node": ">=20",
47
- "pnpm": ">=8"
12
+ "build": "tsc",
13
+ "dev": "tsc --watch",
14
+ "clean": "rm -rf dist"
48
15
  },
49
16
  "dependencies": {
50
- "better-sqlite3": "^12.8.0",
51
- "drizzle-orm": "^0.44.0"
52
- },
53
- "optionalDependencies": {
54
- "@clack/prompts": "^1.1.0"
17
+ "@clack/prompts": "^1.1.0",
18
+ "@pwnkit/core": "workspace:*",
19
+ "@pwnkit/db": "workspace:*",
20
+ "@pwnkit/shared": "workspace:*",
21
+ "@pwnkit/templates": "workspace:*",
22
+ "@pwnkit/test-targets": "workspace:*",
23
+ "cfonts": "^3.3.1",
24
+ "chalk": "^5.3.0",
25
+ "commander": "^12.1.0",
26
+ "ink": "^6.8.0",
27
+ "ink-spinner": "^5.0.0",
28
+ "ora": "^8.0.0",
29
+ "react": "^19.2.4"
55
30
  },
56
31
  "devDependencies": {
57
- "@types/node": "^25.5.0",
58
- "esbuild": "^0.27.4"
59
- },
60
- "pnpm": {
61
- "overrides": {
62
- "esbuild": "^0.27.4"
63
- }
32
+ "@types/react": "^19.2.14",
33
+ "typescript": "^5.4.0"
64
34
  }
65
35
  }