pentesting 0.1.5 → 0.1.8

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 (2) hide show
  1. package/dist/index.js +212 -362
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -5,8 +5,9 @@ import { render } from "ink";
5
5
  import { Command } from "commander";
6
6
 
7
7
  // src/cli/app.tsx
8
- import { useState, useEffect, useCallback } from "react";
9
- import { Box, Text, useApp, useInput, Static } from "ink";
8
+ import { useState, useEffect, useCallback, useRef } from "react";
9
+ import { Box, Text, useInput, useApp, Static } from "ink";
10
+ import TextInput from "ink-text-input";
10
11
  import Spinner from "ink-spinner";
11
12
 
12
13
  // src/core/agent/autonomous-agent.ts
@@ -2608,397 +2609,246 @@ var ASCII_BANNER = `
2608
2609
  \u2551 \u25C8 PENTESTING - Autonomous Penetration Testing Agent \u2551
2609
2610
  \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
2610
2611
  `;
2611
- var ICONS = {
2612
- // Status
2613
- success: "\u2713",
2614
- error: "\u2717",
2615
- warning: "\u26A0",
2616
- info: "\u2139",
2617
- running: "\u25C9",
2618
- thinking: "\u25D0",
2619
- // Actions (pentesting-specific)
2620
- target: "\u25C8",
2621
- // Diamond for target
2622
- scan: "\u25CE",
2623
- exploit: "\u26A1",
2624
- shell: "\u276F",
2625
- // Progress
2626
- pending: "\u25CB",
2627
- completed: "\u25CF",
2628
- skipped: "\u25CC",
2629
- // Findings (severity)
2630
- critical: "\u25BC",
2631
- high: "\u25BD",
2632
- medium: "\u25C7",
2633
- low: "\u25E6",
2634
- // Security
2635
- lock: "\u{1F512}",
2636
- unlock: "\u{1F513}",
2637
- key: "\u{1F511}",
2638
- flag: "\u2691",
2639
- // Simple flag
2640
- pwned: "\u25C8"
2641
- // Compromised
2642
- };
2643
2612
 
2644
2613
  // src/cli/app.tsx
2645
2614
  import { jsx, jsxs } from "react/jsx-runtime";
2646
- var App = ({
2647
- apiKey,
2648
- target: initialTarget,
2649
- autoStart = false,
2650
- autoApprove = false,
2651
- objective: initialObjective,
2652
- maxIterations = 200
2653
- }) => {
2615
+ var App = ({ autoApprove = false, target }) => {
2654
2616
  const { exit } = useApp();
2655
- const [agent] = useState(() => new AutonomousHackingAgent(apiKey, { maxIterations, autoApprove }));
2656
- const [appState, setAppState] = useState({
2657
- status: "idle",
2658
- target: initialTarget || "",
2659
- currentPhase: "recon",
2660
- iteration: 0,
2661
- maxIterations,
2662
- findings: 0,
2663
- compromised: [],
2664
- credentials: 0,
2665
- services: 0
2666
- });
2667
- const [phases, setPhases] = useState([]);
2668
- const [thoughts, setThoughts] = useState([]);
2669
- const [logs, setLogs] = useState([]);
2617
+ const [messages, setMessages] = useState([]);
2670
2618
  const [input, setInput] = useState("");
2671
- const [showThoughts, setShowThoughts] = useState(true);
2672
- const [isThinking, setIsThinking] = useState(false);
2673
- const addLog = useCallback((type, message) => {
2674
- const entry = {
2675
- id: `log-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
2619
+ const [isProcessing, setIsProcessing] = useState(false);
2620
+ const [currentStatus, setCurrentStatus] = useState("");
2621
+ const [elapsedTime, setElapsedTime] = useState(0);
2622
+ const [agent] = useState(() => new AutonomousHackingAgent(void 0, { autoApprove }));
2623
+ const startTimeRef = useRef(0);
2624
+ const timerRef = useRef(null);
2625
+ const addMessage = useCallback((type, content, duration) => {
2626
+ setMessages((prev) => [...prev, {
2627
+ id: `${Date.now()}-${Math.random().toString(36).slice(2)}`,
2676
2628
  type,
2677
- message,
2678
- timestamp: /* @__PURE__ */ new Date()
2679
- };
2680
- setLogs((prev) => [...prev.slice(-50), entry]);
2629
+ content,
2630
+ timestamp: /* @__PURE__ */ new Date(),
2631
+ duration
2632
+ }]);
2633
+ }, []);
2634
+ const startTimer = useCallback(() => {
2635
+ startTimeRef.current = Date.now();
2636
+ timerRef.current = setInterval(() => {
2637
+ setElapsedTime(Math.floor((Date.now() - startTimeRef.current) / 100) / 10);
2638
+ }, 100);
2639
+ }, []);
2640
+ const stopTimer = useCallback(() => {
2641
+ if (timerRef.current) {
2642
+ clearInterval(timerRef.current);
2643
+ timerRef.current = null;
2644
+ }
2645
+ const duration = Math.floor((Date.now() - startTimeRef.current) / 100) / 10;
2646
+ setElapsedTime(0);
2647
+ return duration;
2681
2648
  }, []);
2682
2649
  useEffect(() => {
2683
- agent.on("thought", (thought) => {
2684
- setThoughts((prev) => [...prev.slice(-30), thought]);
2685
- setIsThinking(false);
2686
- });
2687
- agent.on("iteration", ({ current, max, phase }) => {
2688
- setAppState((prev) => ({
2689
- ...prev,
2690
- iteration: current,
2691
- maxIterations: max,
2692
- currentPhase: phase,
2693
- status: "running"
2694
- }));
2695
- setIsThinking(true);
2650
+ addMessage("system", "Pentesting Agent initialized. Type /help for commands.");
2651
+ if (target) {
2652
+ agent.setTarget(target);
2653
+ addMessage("system", `Target: ${target}`);
2654
+ }
2655
+ agent.on("thought", (type, content) => {
2656
+ setCurrentStatus(content.slice(0, 60));
2696
2657
  });
2697
- agent.on("phase_change", ({ phaseId, newStatus }) => {
2698
- setAppState((prev) => ({ ...prev, currentPhase: phaseId }));
2699
- addLog("info", `[phase] ${phaseId} -> ${newStatus}`);
2658
+ agent.on("tool_call", (data) => {
2659
+ const args = Object.entries(data.input).slice(0, 2).map(([k, v]) => `${k}=${typeof v === "string" ? v.slice(0, 30) : "..."}`).join(" ");
2660
+ setCurrentStatus(`Running ${data.name}...`);
2661
+ addMessage("tool", `\u25B6 ${data.name} ${args}`);
2700
2662
  });
2701
- agent.on("tool_call", ({ name, input: input2 }) => {
2702
- addLog("tool", `[tool] ${name}: ${JSON.stringify(input2).slice(0, 100)}...`);
2663
+ agent.on("tool_result", (data) => {
2664
+ const icon = data.result.success ? "\u2713" : "\u2717";
2665
+ const preview = data.result.output?.slice(0, 100).replace(/\n/g, " ") || "";
2666
+ addMessage("result", `${icon} ${preview}`);
2703
2667
  });
2704
- agent.on("tool_result", ({ name, result }) => {
2705
- if (result.success) {
2706
- addLog("success", `[+] ${name} completed (${result.duration}ms)`);
2707
- } else {
2708
- addLog("error", `[-] ${name} failed: ${result.error}`);
2709
- }
2668
+ agent.on("iteration", (data) => {
2669
+ setCurrentStatus(`Phase: ${data.phase} (iteration ${data.iteration})`);
2710
2670
  });
2711
2671
  agent.on("finding", (finding) => {
2712
- addLog("finding", `[!] [${finding.severity.toUpperCase()}] ${finding.title}`);
2713
- setAppState((prev) => ({ ...prev, findings: prev.findings + 1 }));
2672
+ addMessage("system", `\u{1F3AF} [${finding.severity.toUpperCase()}] ${finding.title}`);
2714
2673
  });
2715
- agent.on("credential", (cred) => {
2716
- addLog("success", `[cred] ${cred.type} - ${cred.username || "unknown"}`);
2717
- setAppState((prev) => ({ ...prev, credentials: prev.credentials + 1 }));
2718
- });
2719
- agent.on("compromised", (host) => {
2720
- addLog("success", `[pwned] ${host}`);
2721
- setAppState((prev) => ({
2722
- ...prev,
2723
- compromised: [...prev.compromised, host]
2724
- }));
2725
- });
2726
- agent.on("complete", (summary) => {
2727
- setAppState((prev) => ({ ...prev, status: "completed" }));
2728
- addLog("success", `[done] Assessment complete: ${JSON.stringify(summary)}`);
2674
+ agent.on("complete", () => {
2675
+ const duration = stopTimer();
2676
+ addMessage("system", `\u2713 Complete (${duration}s)`);
2677
+ setIsProcessing(false);
2678
+ setCurrentStatus("");
2729
2679
  });
2730
2680
  agent.on("error", (error) => {
2731
- addLog("error", `[error] ${error.message}`);
2732
- });
2733
- agent.on("report", (report) => {
2734
- addLog("info", `[report] Generated (${report.length} chars)`);
2681
+ stopTimer();
2682
+ addMessage("error", error.message);
2683
+ setIsProcessing(false);
2735
2684
  });
2736
- const state = agent.getState();
2737
- setPhases(state.phases);
2738
- if (autoStart && initialTarget) {
2739
- agent.setTarget(initialTarget);
2740
- setAppState((prev) => ({ ...prev, target: initialTarget }));
2741
- agent.runAutonomous(initialObjective);
2742
- }
2743
2685
  return () => {
2744
- agent.removeAllListeners();
2686
+ if (timerRef.current) clearInterval(timerRef.current);
2745
2687
  };
2746
- }, [agent, addLog, autoStart, initialTarget, initialObjective]);
2747
- useEffect(() => {
2748
- const interval = setInterval(() => {
2749
- const state = agent.getState();
2750
- setPhases(state.phases);
2751
- setAppState((prev) => ({
2752
- ...prev,
2753
- services: state.target.services.length,
2754
- credentials: state.target.credentials.length,
2755
- compromised: state.target.compromised,
2756
- findings: state.findings.length
2757
- }));
2758
- }, 1e3);
2759
- return () => clearInterval(interval);
2760
- }, [agent]);
2761
- useInput((key, mods) => {
2762
- if (mods.ctrl && key === "c") {
2763
- exit();
2764
- return;
2765
- }
2766
- if (key === "t") {
2767
- setShowThoughts((prev) => !prev);
2768
- }
2769
- if (key === "p" && appState.status === "running") {
2770
- agent.pause();
2771
- setAppState((prev) => ({ ...prev, status: "paused" }));
2772
- }
2773
- if (key === "r" && appState.status === "paused") {
2774
- agent.resume();
2775
- setAppState((prev) => ({ ...prev, status: "running" }));
2688
+ }, [agent, target, addMessage, stopTimer]);
2689
+ const handleSubmit = useCallback(async (value) => {
2690
+ const trimmed = value.trim();
2691
+ if (!trimmed || isProcessing) return;
2692
+ setInput("");
2693
+ addMessage("user", trimmed);
2694
+ if (trimmed.startsWith("/")) {
2695
+ const [cmd, ...args] = trimmed.slice(1).split(" ");
2696
+ switch (cmd) {
2697
+ case "help":
2698
+ case "h":
2699
+ addMessage(
2700
+ "system",
2701
+ `/target <ip> Set target
2702
+ /start [goal] Start pentest
2703
+ /stop Stop operation
2704
+ /findings Show findings
2705
+ /clear Clear screen
2706
+ /exit Exit`
2707
+ );
2708
+ return;
2709
+ case "target":
2710
+ case "t":
2711
+ if (args[0]) {
2712
+ agent.setTarget(args[0]);
2713
+ addMessage("system", `Target \u2192 ${args[0]}`);
2714
+ } else {
2715
+ addMessage("error", "Usage: /target <ip>");
2716
+ }
2717
+ return;
2718
+ case "start":
2719
+ case "s":
2720
+ setIsProcessing(true);
2721
+ startTimer();
2722
+ const objective = args.join(" ") || "Perform comprehensive penetration testing";
2723
+ setCurrentStatus("Initializing...");
2724
+ try {
2725
+ await agent.runAutonomous(objective);
2726
+ } catch (e) {
2727
+ addMessage("error", e instanceof Error ? e.message : String(e));
2728
+ }
2729
+ stopTimer();
2730
+ setIsProcessing(false);
2731
+ setCurrentStatus("");
2732
+ return;
2733
+ case "stop":
2734
+ agent.pause();
2735
+ stopTimer();
2736
+ addMessage("system", "Stopped.");
2737
+ setIsProcessing(false);
2738
+ setCurrentStatus("");
2739
+ return;
2740
+ case "findings":
2741
+ case "f":
2742
+ const findings = agent.getState().findings;
2743
+ if (findings.length === 0) {
2744
+ addMessage("system", "No findings.");
2745
+ } else {
2746
+ findings.forEach((f) => addMessage("system", `[${f.severity}] ${f.title}`));
2747
+ }
2748
+ return;
2749
+ case "clear":
2750
+ case "c":
2751
+ setMessages([]);
2752
+ return;
2753
+ case "exit":
2754
+ case "quit":
2755
+ case "q":
2756
+ exit();
2757
+ return;
2758
+ default:
2759
+ addMessage("error", `Unknown: ${cmd}`);
2760
+ return;
2761
+ }
2776
2762
  }
2777
- });
2778
- const processCommand = useCallback((cmd) => {
2779
- const parts = cmd.trim().split(/\s+/);
2780
- const command = parts[0].toLowerCase();
2781
- const args = parts.slice(1).join(" ");
2782
- switch (command) {
2783
- case "/target":
2784
- if (args) {
2785
- agent.setTarget(args);
2786
- setAppState((prev) => ({ ...prev, target: args }));
2787
- addLog("info", `[target] Set: ${args}`);
2788
- }
2789
- break;
2790
- case "/start":
2791
- case "/auto":
2792
- if (appState.target) {
2793
- const objective = args || void 0;
2794
- addLog("info", `[*] Starting autonomous hacking...`);
2795
- agent.runAutonomous(objective);
2796
- } else {
2797
- addLog("error", "No target set. Use /target <ip> first.");
2798
- }
2799
- break;
2800
- case "/hint":
2801
- if (args && appState.status === "running") {
2802
- agent.processUserHint(args);
2803
- addLog("info", `[hint] Sent to agent`);
2804
- }
2805
- break;
2806
- case "/pause":
2763
+ setIsProcessing(true);
2764
+ startTimer();
2765
+ setCurrentStatus("Thinking...");
2766
+ try {
2767
+ await agent.processUserHint(trimmed);
2768
+ addMessage("system", "Hint received.");
2769
+ } catch (e) {
2770
+ addMessage("error", e instanceof Error ? e.message : String(e));
2771
+ }
2772
+ stopTimer();
2773
+ setIsProcessing(false);
2774
+ setCurrentStatus("");
2775
+ }, [agent, isProcessing, addMessage, exit, startTimer, stopTimer]);
2776
+ useInput((input2, key) => {
2777
+ if (key.ctrl && input2 === "c") {
2778
+ if (isProcessing) {
2807
2779
  agent.pause();
2808
- setAppState((prev) => ({ ...prev, status: "paused" }));
2809
- break;
2810
- case "/resume":
2811
- agent.resume();
2812
- break;
2813
- case "/reset":
2814
- agent.reset();
2815
- setAppState({
2816
- status: "idle",
2817
- target: "",
2818
- currentPhase: "recon",
2819
- iteration: 0,
2820
- maxIterations,
2821
- findings: 0,
2822
- compromised: [],
2823
- credentials: 0,
2824
- services: 0
2825
- });
2826
- setThoughts([]);
2827
- setLogs([]);
2828
- addLog("info", "Session reset");
2829
- break;
2830
- case "/findings":
2831
- const state = agent.getState();
2832
- state.findings.forEach((f) => {
2833
- addLog("finding", `[${f.severity}] ${f.title}: ${f.description.slice(0, 100)}`);
2834
- });
2835
- break;
2836
- case "/help":
2837
- addLog("info", "Commands: /target <ip>, /start [objective], /hint <hint>, /pause, /resume, /reset, /findings, /help");
2838
- addLog("info", "Keys: [T] Toggle thoughts, [P] Pause, [R] Resume, Ctrl+C Exit");
2839
- break;
2840
- default:
2841
- if (appState.status === "running" && cmd) {
2842
- agent.processUserHint(cmd);
2843
- addLog("info", `[hint] ${cmd}`);
2844
- }
2780
+ stopTimer();
2781
+ setIsProcessing(false);
2782
+ setCurrentStatus("");
2783
+ addMessage("system", "Interrupted.");
2784
+ } else {
2785
+ exit();
2786
+ }
2845
2787
  }
2846
- setInput("");
2847
- }, [agent, appState, addLog, maxIterations]);
2848
- const getThoughtStyle = (type) => {
2788
+ });
2789
+ const getStyle = (type) => {
2849
2790
  const styles = {
2850
- observation: { prefix: "[observe]", color: THEME.text.accent },
2851
- hypothesis: { prefix: "[hypothesis]", color: THEME.status.warning },
2852
- plan: { prefix: "[plan]", color: THEME.status.running },
2853
- action: { prefix: "[action]", color: THEME.status.success },
2854
- result: { prefix: "[result]", color: THEME.text.primary },
2855
- reflection: { prefix: "[reflect]", color: THEME.semantic.high },
2856
- stuck: { prefix: "[stuck]", color: THEME.status.error },
2857
- breakthrough: { prefix: "[breakthrough]", color: "#00ff00" }
2791
+ user: { color: THEME.text.accent, prefix: "\u276F" },
2792
+ assistant: { color: THEME.text.primary, prefix: "\u25C8" },
2793
+ tool: { color: THEME.text.muted, prefix: " ", dim: true },
2794
+ result: { color: THEME.text.muted, prefix: " ", dim: true },
2795
+ thinking: { color: THEME.status.running, prefix: "\u25CB" },
2796
+ error: { color: THEME.status.error, prefix: "\u2717" },
2797
+ system: { color: THEME.text.muted, prefix: "\u2022" }
2858
2798
  };
2859
- return styles[type] || { prefix: "[info]", color: THEME.text.muted };
2860
- };
2861
- const getPhaseIcon = (status) => {
2862
- switch (status) {
2863
- case "completed":
2864
- return "[+]";
2865
- case "in_progress":
2866
- return "[*]";
2867
- case "failed":
2868
- return "[-]";
2869
- case "skipped":
2870
- return "[>]";
2871
- default:
2872
- return "[ ]";
2873
- }
2799
+ return styles[type] || styles.system;
2874
2800
  };
2875
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", padding: 1, children: [
2876
- /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
2877
- /* @__PURE__ */ jsx(Text, { color: THEME.status.success, children: ASCII_BANNER }),
2878
- /* @__PURE__ */ jsxs(Box, { marginTop: 1, justifyContent: "space-between", children: [
2879
- /* @__PURE__ */ jsxs(Text, { color: THEME.status.error, children: [
2880
- ICONS.target,
2881
- " Target: ",
2882
- /* @__PURE__ */ jsx(Text, { color: THEME.text.accent, bold: true, children: appState.target || "Not set" })
2883
- ] }),
2884
- /* @__PURE__ */ jsxs(Text, { color: THEME.text.muted, children: [
2885
- "Status: ",
2886
- /* @__PURE__ */ jsx(Text, { color: appState.status === "running" ? THEME.status.success : THEME.status.warning, children: appState.status.toUpperCase() })
2887
- ] }),
2888
- /* @__PURE__ */ jsxs(Text, { color: THEME.text.muted, children: [
2889
- "Iteration: ",
2890
- /* @__PURE__ */ jsxs(Text, { color: THEME.text.accent, children: [
2891
- appState.iteration,
2892
- "/",
2893
- appState.maxIterations
2894
- ] })
2801
+ const state = agent.getState();
2802
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingX: 1, children: [
2803
+ /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsx(Static, { items: messages.slice(-40), children: (msg) => {
2804
+ const style = getStyle(msg.type);
2805
+ return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { color: style.color, dimColor: style.dim, children: [
2806
+ style.prefix,
2807
+ " ",
2808
+ msg.content,
2809
+ msg.duration && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
2810
+ " (",
2811
+ msg.duration,
2812
+ "s)"
2813
+ ] })
2814
+ ] }) }, msg.id);
2815
+ } }) }),
2816
+ isProcessing ? /* @__PURE__ */ jsxs(Box, { children: [
2817
+ /* @__PURE__ */ jsx(Text, { color: THEME.status.running, children: /* @__PURE__ */ jsx(Spinner, { type: "dots" }) }),
2818
+ /* @__PURE__ */ jsxs(Text, { color: THEME.text.muted, children: [
2819
+ " ",
2820
+ currentStatus,
2821
+ elapsedTime > 0 && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
2822
+ " (",
2823
+ elapsedTime,
2824
+ "s)"
2895
2825
  ] })
2896
2826
  ] })
2897
- ] }),
2898
- /* @__PURE__ */ jsxs(Box, { borderStyle: "single", borderColor: THEME.status.running, paddingX: 1, children: [
2899
- /* @__PURE__ */ jsx(Text, { color: THEME.text.muted, children: "Services: " }),
2900
- /* @__PURE__ */ jsx(Text, { color: THEME.status.success, children: appState.services }),
2901
- /* @__PURE__ */ jsx(Text, { children: " | " }),
2902
- /* @__PURE__ */ jsx(Text, { color: THEME.text.muted, children: "Creds: " }),
2903
- /* @__PURE__ */ jsx(Text, { color: THEME.status.warning, children: appState.credentials }),
2904
- /* @__PURE__ */ jsx(Text, { children: " | " }),
2905
- /* @__PURE__ */ jsx(Text, { color: THEME.text.muted, children: "Pwned: " }),
2906
- /* @__PURE__ */ jsx(Text, { color: appState.compromised.length > 0 ? THEME.status.success : THEME.text.muted, children: appState.compromised.length > 0 ? appState.compromised.join(", ") : "0" }),
2907
- /* @__PURE__ */ jsx(Text, { children: " | " }),
2908
- /* @__PURE__ */ jsx(Text, { color: THEME.text.muted, children: "Findings: " }),
2909
- /* @__PURE__ */ jsx(Text, { color: THEME.semantic.high, children: appState.findings })
2910
- ] }),
2911
- /* @__PURE__ */ jsxs(Box, { borderStyle: "single", borderColor: THEME.text.accent, paddingX: 1, marginTop: 1, children: [
2912
- /* @__PURE__ */ jsx(Text, { color: THEME.text.accent, bold: true, children: "[phases] " }),
2913
- phases.map((phase) => /* @__PURE__ */ jsx(Box, { marginRight: 1, children: /* @__PURE__ */ jsxs(
2914
- Text,
2827
+ ] }) : /* @__PURE__ */ jsxs(Box, { children: [
2828
+ /* @__PURE__ */ jsx(Text, { color: THEME.status.success, children: "\u276F " }),
2829
+ /* @__PURE__ */ jsx(
2830
+ TextInput,
2915
2831
  {
2916
- color: phase.id === appState.currentPhase ? THEME.status.warning : phase.status === "completed" ? THEME.status.success : THEME.text.muted,
2917
- bold: phase.id === appState.currentPhase,
2918
- children: [
2919
- getPhaseIcon(phase.status),
2920
- phase.name,
2921
- phase.attempts > 0 && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
2922
- "(",
2923
- phase.attempts,
2924
- ")"
2925
- ] })
2926
- ]
2832
+ value: input,
2833
+ onChange: setInput,
2834
+ onSubmit: handleSubmit,
2835
+ placeholder: "Message or /help..."
2927
2836
  }
2928
- ) }, phase.id))
2837
+ )
2929
2838
  ] }),
2930
- showThoughts && /* @__PURE__ */ jsxs(
2931
- Box,
2932
- {
2933
- flexDirection: "column",
2934
- borderStyle: "single",
2935
- borderColor: THEME.status.running,
2936
- paddingX: 1,
2937
- height: 10,
2938
- marginTop: 1,
2939
- children: [
2940
- /* @__PURE__ */ jsxs(Box, { children: [
2941
- /* @__PURE__ */ jsx(Text, { color: THEME.status.running, bold: true, children: "[agent thoughts]" }),
2942
- isThinking && /* @__PURE__ */ jsxs(Box, { marginLeft: 2, children: [
2943
- /* @__PURE__ */ jsx(Text, { color: THEME.status.warning, children: /* @__PURE__ */ jsx(Spinner, { type: "dots" }) }),
2944
- /* @__PURE__ */ jsx(Text, { color: THEME.status.warning, children: " Thinking..." })
2945
- ] })
2946
- ] }),
2947
- /* @__PURE__ */ jsx(Static, { items: thoughts.slice(-6), children: (thought) => {
2948
- const style = getThoughtStyle(thought.type);
2949
- return /* @__PURE__ */ jsxs(Box, { children: [
2950
- /* @__PURE__ */ jsxs(Text, { color: THEME.text.muted, dimColor: true, children: [
2951
- "[",
2952
- thought.timestamp.toLocaleTimeString(),
2953
- "]"
2954
- ] }),
2955
- /* @__PURE__ */ jsxs(Text, { color: style.color, children: [
2956
- " ",
2957
- style.prefix,
2958
- " ",
2959
- thought.content.slice(0, 120),
2960
- thought.content.length > 120 && "..."
2961
- ] })
2962
- ] }, thought.id);
2963
- } })
2964
- ]
2965
- }
2966
- ),
2967
- /* @__PURE__ */ jsxs(
2968
- Box,
2969
- {
2970
- flexDirection: "column",
2971
- borderStyle: "single",
2972
- borderColor: THEME.status.success,
2973
- paddingX: 1,
2974
- height: 12,
2975
- marginTop: 1,
2976
- children: [
2977
- /* @__PURE__ */ jsx(Text, { color: THEME.status.success, bold: true, children: "[activity log]" }),
2978
- /* @__PURE__ */ jsx(Static, { items: logs.slice(-10), children: (log) => /* @__PURE__ */ jsxs(Box, { children: [
2979
- /* @__PURE__ */ jsxs(Text, { color: THEME.text.muted, dimColor: true, children: [
2980
- "[",
2981
- log.timestamp.toLocaleTimeString(),
2982
- "]"
2983
- ] }),
2984
- /* @__PURE__ */ jsxs(Text, { color: log.type === "success" ? THEME.status.success : log.type === "error" ? THEME.status.error : log.type === "warning" ? THEME.status.warning : log.type === "finding" ? THEME.semantic.high : log.type === "tool" ? THEME.text.accent : THEME.text.primary, children: [
2985
- " ",
2986
- log.message
2987
- ] })
2988
- ] }, log.id) })
2989
- ]
2990
- }
2991
- ),
2992
- /* @__PURE__ */ jsxs(Box, { marginTop: 1, children: [
2993
- /* @__PURE__ */ jsxs(Text, { color: THEME.status.success, bold: true, children: [
2994
- "pentesting ",
2995
- ">",
2996
- " "
2839
+ /* @__PURE__ */ jsxs(Box, { marginTop: 1, justifyContent: "space-between", children: [
2840
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
2841
+ state.target.primary || "No target",
2842
+ " \u2502",
2843
+ state.findings.length,
2844
+ " findings \u2502",
2845
+ state.currentPhase !== "idle" && ` ${state.currentPhase} \u2502`
2997
2846
  ] }),
2998
- /* @__PURE__ */ jsx(Text, { color: THEME.text.primary, children: input }),
2999
- /* @__PURE__ */ jsx(Text, { color: THEME.status.success, children: "_" })
3000
- ] }),
3001
- /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { color: THEME.text.muted, dimColor: true, children: "[T] Toggle thoughts | [P] Pause | [R] Resume | Type command or hint" }) })
2847
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
2848
+ "/help \u2502 Ctrl+C ",
2849
+ isProcessing ? "stop" : "exit"
2850
+ ] })
2851
+ ] })
3002
2852
  ] });
3003
2853
  };
3004
2854
  var app_default = App;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pentesting",
3
- "version": "0.1.5",
3
+ "version": "0.1.8",
4
4
  "description": "Autonomous Penetration Testing AI Agent",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",