pentesting 0.1.6 → 0.1.9

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 +203 -102
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ 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";
8
+ import { useState, useEffect, useCallback, useRef } from "react";
9
9
  import { Box, Text, useInput, useApp, Static } from "ink";
10
10
  import TextInput from "ink-text-input";
11
11
  import Spinner from "ink-spinner";
@@ -2610,6 +2610,52 @@ var ASCII_BANNER = `
2610
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
2611
2611
  `;
2612
2612
 
2613
+ // src/config/agent-constants.ts
2614
+ var AGENT_EVENT = {
2615
+ // Lifecycle
2616
+ PLUGINS_LOADED: "plugins_loaded",
2617
+ HOOKS_LOADED: "hooks_loaded",
2618
+ COMMANDS_LOADED: "commands_loaded",
2619
+ MCP_SERVER_ADDED: "mcp_server_added",
2620
+ // Execution
2621
+ ITERATION: "iteration",
2622
+ THOUGHT: "thought",
2623
+ RESPONSE: "response",
2624
+ TOOL_CALL: "tool_call",
2625
+ TOOL_RESULT: "tool_result",
2626
+ COMMAND_EXECUTE: "command_execute",
2627
+ // State changes
2628
+ TARGET_SET: "target_set",
2629
+ PHASE_CHANGE: "phase_change",
2630
+ AGENT_SWITCH: "agent_switch",
2631
+ // Discoveries
2632
+ FINDING: "finding",
2633
+ CREDENTIAL: "credential",
2634
+ COMPROMISED: "compromised",
2635
+ // Completion
2636
+ COMPLETE: "complete",
2637
+ REPORT: "report",
2638
+ ERROR: "error"
2639
+ };
2640
+ var CLI_COMMAND = {
2641
+ HELP: "help",
2642
+ TARGET: "target",
2643
+ START: "start",
2644
+ STOP: "stop",
2645
+ FINDINGS: "findings",
2646
+ CLEAR: "clear",
2647
+ EXIT: "exit"
2648
+ };
2649
+ var MESSAGE_TYPE = {
2650
+ USER: "user",
2651
+ ASSISTANT: "assistant",
2652
+ TOOL: "tool",
2653
+ THINKING: "thinking",
2654
+ ERROR: "error",
2655
+ SYSTEM: "system",
2656
+ RESULT: "result"
2657
+ };
2658
+
2613
2659
  // src/cli/app.tsx
2614
2660
  import { jsx, jsxs } from "react/jsx-runtime";
2615
2661
  var App = ({ autoApprove = false, target }) => {
@@ -2617,164 +2663,213 @@ var App = ({ autoApprove = false, target }) => {
2617
2663
  const [messages, setMessages] = useState([]);
2618
2664
  const [input, setInput] = useState("");
2619
2665
  const [isProcessing, setIsProcessing] = useState(false);
2666
+ const [currentStatus, setCurrentStatus] = useState("");
2667
+ const [elapsedTime, setElapsedTime] = useState(0);
2620
2668
  const [agent] = useState(() => new AutonomousHackingAgent(void 0, { autoApprove }));
2621
- const addMessage = useCallback((type, content) => {
2669
+ const startTimeRef = useRef(0);
2670
+ const timerRef = useRef(null);
2671
+ const addMessage = useCallback((type, content, duration) => {
2622
2672
  setMessages((prev) => [...prev, {
2623
2673
  id: `${Date.now()}-${Math.random().toString(36).slice(2)}`,
2624
2674
  type,
2625
2675
  content,
2626
- timestamp: /* @__PURE__ */ new Date()
2676
+ timestamp: /* @__PURE__ */ new Date(),
2677
+ duration
2627
2678
  }]);
2628
2679
  }, []);
2680
+ const startTimer = useCallback(() => {
2681
+ startTimeRef.current = Date.now();
2682
+ timerRef.current = setInterval(() => {
2683
+ setElapsedTime(Math.floor((Date.now() - startTimeRef.current) / 100) / 10);
2684
+ }, 100);
2685
+ }, []);
2686
+ const stopTimer = useCallback(() => {
2687
+ if (timerRef.current) {
2688
+ clearInterval(timerRef.current);
2689
+ timerRef.current = null;
2690
+ }
2691
+ const duration = Math.floor((Date.now() - startTimeRef.current) / 100) / 10;
2692
+ setElapsedTime(0);
2693
+ return duration;
2694
+ }, []);
2629
2695
  useEffect(() => {
2630
- addMessage("system", "Pentesting Agent ready. Type a message or use /help for commands.");
2696
+ addMessage(MESSAGE_TYPE.SYSTEM, "Pentesting Agent initialized. Type /help for commands.");
2631
2697
  if (target) {
2632
2698
  agent.setTarget(target);
2633
- addMessage("system", `Target set: ${target}`);
2699
+ addMessage(MESSAGE_TYPE.SYSTEM, `Target: ${target}`);
2634
2700
  }
2635
- agent.on("thought", (type, content) => {
2636
- addMessage("assistant", `[${type}] ${content}`);
2701
+ agent.on(AGENT_EVENT.THOUGHT, (thought) => {
2702
+ setCurrentStatus(thought.content.slice(0, 60));
2703
+ });
2704
+ agent.on(AGENT_EVENT.TOOL_CALL, (data) => {
2705
+ const args = Object.entries(data.input).slice(0, 2).map(([k, v]) => `${k}=${typeof v === "string" ? v.slice(0, 30) : "..."}`).join(" ");
2706
+ setCurrentStatus(`Running ${data.name}...`);
2707
+ addMessage(MESSAGE_TYPE.TOOL, `\u25B6 ${data.name} ${args}`);
2708
+ });
2709
+ agent.on(AGENT_EVENT.TOOL_RESULT, (data) => {
2710
+ const icon = data.result.success ? "\u2713" : "\u2717";
2711
+ const preview = data.result.output?.slice(0, 100).replace(/\n/g, " ") || "";
2712
+ addMessage(MESSAGE_TYPE.RESULT, `${icon} ${preview}`);
2637
2713
  });
2638
- agent.on("tool_call", (data) => {
2639
- const inputStr = Object.entries(data.input).map(([k, v]) => `${k}=${typeof v === "string" ? v : JSON.stringify(v)}`).join(" ");
2640
- addMessage("tool", `\u25B6 ${data.name} ${inputStr}`);
2714
+ agent.on(AGENT_EVENT.ITERATION, (data) => {
2715
+ setCurrentStatus(`Phase: ${data.phase} (iteration ${data.current})`);
2641
2716
  });
2642
- agent.on("tool_result", (data) => {
2643
- const status = data.result.success ? "\u2713" : "\u2717";
2644
- const output = data.result.output?.slice(0, 200) || "";
2645
- addMessage("tool", `${status} ${data.name}: ${output}`);
2717
+ agent.on(AGENT_EVENT.FINDING, (finding) => {
2718
+ addMessage(MESSAGE_TYPE.SYSTEM, `\u{1F3AF} [${finding.severity.toUpperCase()}] ${finding.title}`);
2646
2719
  });
2647
- agent.on("finding", (finding) => {
2648
- addMessage("system", `\u{1F3AF} Finding: [${finding.severity.toUpperCase()}] ${finding.title}`);
2720
+ agent.on(AGENT_EVENT.COMPLETE, () => {
2721
+ const duration = stopTimer();
2722
+ addMessage(MESSAGE_TYPE.SYSTEM, `\u2713 Complete (${duration}s)`);
2723
+ setIsProcessing(false);
2724
+ setCurrentStatus("");
2649
2725
  });
2650
- agent.on("error", (error) => {
2651
- addMessage("error", `Error: ${error.message}`);
2726
+ agent.on(AGENT_EVENT.ERROR, (error) => {
2727
+ stopTimer();
2728
+ addMessage(MESSAGE_TYPE.ERROR, error.message);
2729
+ setIsProcessing(false);
2652
2730
  });
2653
- }, [agent, target, addMessage]);
2731
+ return () => {
2732
+ if (timerRef.current) clearInterval(timerRef.current);
2733
+ };
2734
+ }, [agent, target, addMessage, stopTimer]);
2654
2735
  const handleSubmit = useCallback(async (value) => {
2655
2736
  const trimmed = value.trim();
2656
2737
  if (!trimmed || isProcessing) return;
2657
2738
  setInput("");
2658
- addMessage("user", trimmed);
2739
+ addMessage(MESSAGE_TYPE.USER, trimmed);
2659
2740
  if (trimmed.startsWith("/")) {
2660
2741
  const [cmd, ...args] = trimmed.slice(1).split(" ");
2661
2742
  switch (cmd) {
2662
- case "help":
2663
- addMessage("system", `Commands:
2664
- /target <ip> Set target
2665
- /start Start autonomous mode
2666
- /stop Stop current operation
2667
- /findings Show findings
2668
- /clear Clear messages
2669
- /exit Exit`);
2743
+ case CLI_COMMAND.HELP:
2744
+ case "h":
2745
+ addMessage(
2746
+ MESSAGE_TYPE.SYSTEM,
2747
+ `/target <ip> Set target
2748
+ /start [goal] Start pentest
2749
+ /stop Stop operation
2750
+ /findings Show findings
2751
+ /clear Clear screen
2752
+ /exit Exit`
2753
+ );
2670
2754
  return;
2671
- case "target":
2755
+ case CLI_COMMAND.TARGET:
2756
+ case "t":
2672
2757
  if (args[0]) {
2673
2758
  agent.setTarget(args[0]);
2674
- addMessage("system", `Target set: ${args[0]}`);
2759
+ addMessage(MESSAGE_TYPE.SYSTEM, `Target \u2192 ${args[0]}`);
2675
2760
  } else {
2676
- addMessage("error", "Usage: /target <ip or domain>");
2761
+ addMessage(MESSAGE_TYPE.ERROR, "Usage: /target <ip>");
2677
2762
  }
2678
2763
  return;
2679
- case "start":
2680
- const objective = args.join(" ") || "Perform comprehensive penetration test";
2764
+ case CLI_COMMAND.START:
2765
+ case "s":
2681
2766
  setIsProcessing(true);
2682
- addMessage("system", `Starting: ${objective}`);
2767
+ startTimer();
2768
+ const objective = args.join(" ") || "Perform comprehensive penetration testing";
2769
+ setCurrentStatus("Initializing...");
2683
2770
  try {
2684
- await agent.run(objective);
2771
+ await agent.runAutonomous(objective);
2685
2772
  } catch (e) {
2686
- addMessage("error", `Failed: ${e instanceof Error ? e.message : String(e)}`);
2773
+ addMessage(MESSAGE_TYPE.ERROR, e instanceof Error ? e.message : String(e));
2687
2774
  }
2775
+ stopTimer();
2688
2776
  setIsProcessing(false);
2777
+ setCurrentStatus("");
2689
2778
  return;
2690
- case "stop":
2691
- agent.stop();
2692
- addMessage("system", "Stopped.");
2779
+ case CLI_COMMAND.STOP:
2780
+ agent.pause();
2781
+ stopTimer();
2782
+ addMessage(MESSAGE_TYPE.SYSTEM, "Stopped.");
2693
2783
  setIsProcessing(false);
2784
+ setCurrentStatus("");
2694
2785
  return;
2695
- case "findings":
2786
+ case CLI_COMMAND.FINDINGS:
2787
+ case "f":
2696
2788
  const findings = agent.getState().findings;
2697
2789
  if (findings.length === 0) {
2698
- addMessage("system", "No findings yet.");
2790
+ addMessage(MESSAGE_TYPE.SYSTEM, "No findings.");
2699
2791
  } else {
2700
- findings.forEach((f) => {
2701
- addMessage("system", `[${f.severity.toUpperCase()}] ${f.title}`);
2702
- });
2792
+ findings.forEach((f) => addMessage(MESSAGE_TYPE.SYSTEM, `[${f.severity}] ${f.title}`));
2703
2793
  }
2704
2794
  return;
2705
- case "clear":
2795
+ case CLI_COMMAND.CLEAR:
2796
+ case "c":
2706
2797
  setMessages([]);
2707
- addMessage("system", "Cleared.");
2708
2798
  return;
2709
- case "exit":
2799
+ case CLI_COMMAND.EXIT:
2710
2800
  case "quit":
2801
+ case "q":
2711
2802
  exit();
2712
2803
  return;
2713
2804
  default:
2714
- addMessage("error", `Unknown command: ${cmd}. Type /help`);
2805
+ addMessage(MESSAGE_TYPE.ERROR, `Unknown: ${cmd}`);
2715
2806
  return;
2716
2807
  }
2717
2808
  }
2718
2809
  setIsProcessing(true);
2810
+ startTimer();
2811
+ setCurrentStatus("Thinking...");
2719
2812
  try {
2720
- await agent.chat(trimmed);
2813
+ await agent.processUserHint(trimmed);
2814
+ addMessage(MESSAGE_TYPE.SYSTEM, "Hint received.");
2721
2815
  } catch (e) {
2722
- addMessage("error", `Error: ${e instanceof Error ? e.message : String(e)}`);
2816
+ addMessage(MESSAGE_TYPE.ERROR, e instanceof Error ? e.message : String(e));
2723
2817
  }
2818
+ stopTimer();
2724
2819
  setIsProcessing(false);
2725
- }, [agent, isProcessing, addMessage, exit]);
2820
+ setCurrentStatus("");
2821
+ }, [agent, isProcessing, addMessage, exit, startTimer, stopTimer]);
2726
2822
  useInput((input2, key) => {
2727
2823
  if (key.ctrl && input2 === "c") {
2728
2824
  if (isProcessing) {
2729
- agent.stop();
2825
+ agent.pause();
2826
+ stopTimer();
2730
2827
  setIsProcessing(false);
2731
- addMessage("system", "Interrupted.");
2828
+ setCurrentStatus("");
2829
+ addMessage(MESSAGE_TYPE.SYSTEM, "Interrupted.");
2732
2830
  } else {
2733
2831
  exit();
2734
2832
  }
2735
2833
  }
2736
2834
  });
2737
- const getColor = (type) => {
2738
- switch (type) {
2739
- case "user":
2740
- return THEME.text.accent;
2741
- case "assistant":
2742
- return THEME.text.primary;
2743
- case "tool":
2744
- return THEME.status.info;
2745
- case "error":
2746
- return THEME.status.error;
2747
- case "system":
2748
- return THEME.text.muted;
2749
- default:
2750
- return THEME.text.primary;
2751
- }
2752
- };
2753
- const getPrefix = (type) => {
2754
- switch (type) {
2755
- case "user":
2756
- return "\u276F";
2757
- case "assistant":
2758
- return "\u25C8";
2759
- case "tool":
2760
- return "\u2699";
2761
- case "error":
2762
- return "\u2717";
2763
- case "system":
2764
- return "\u2022";
2765
- default:
2766
- return " ";
2767
- }
2835
+ const getStyle = (type) => {
2836
+ const styles = {
2837
+ [MESSAGE_TYPE.USER]: { color: THEME.text.accent, prefix: "\u276F" },
2838
+ [MESSAGE_TYPE.ASSISTANT]: { color: THEME.text.primary, prefix: "\u25C8" },
2839
+ [MESSAGE_TYPE.TOOL]: { color: THEME.text.muted, prefix: " ", dim: true },
2840
+ [MESSAGE_TYPE.RESULT]: { color: THEME.text.muted, prefix: " ", dim: true },
2841
+ [MESSAGE_TYPE.THINKING]: { color: THEME.status.running, prefix: "\u25CB" },
2842
+ [MESSAGE_TYPE.ERROR]: { color: THEME.status.error, prefix: "\u2717" },
2843
+ [MESSAGE_TYPE.SYSTEM]: { color: THEME.text.muted, prefix: "\u2022" }
2844
+ };
2845
+ return styles[type] || styles[MESSAGE_TYPE.SYSTEM];
2768
2846
  };
2769
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", padding: 1, children: [
2770
- /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsx(Static, { items: messages.slice(-30), children: (msg) => /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { color: getColor(msg.type), children: [
2771
- getPrefix(msg.type),
2772
- " ",
2773
- msg.content
2774
- ] }) }, msg.id) }) }),
2775
- /* @__PURE__ */ jsx(Box, { children: isProcessing ? /* @__PURE__ */ jsxs(Text, { color: THEME.status.running, children: [
2776
- /* @__PURE__ */ jsx(Spinner, { type: "dots" }),
2777
- " Processing..."
2847
+ const state = agent.getState();
2848
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingX: 1, children: [
2849
+ /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsx(Static, { items: messages.slice(-40), children: (msg) => {
2850
+ const style = getStyle(msg.type);
2851
+ return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { color: style.color, dimColor: style.dim, children: [
2852
+ style.prefix,
2853
+ " ",
2854
+ msg.content,
2855
+ msg.duration && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
2856
+ " (",
2857
+ msg.duration,
2858
+ "s)"
2859
+ ] })
2860
+ ] }) }, msg.id);
2861
+ } }) }),
2862
+ isProcessing ? /* @__PURE__ */ jsxs(Box, { children: [
2863
+ /* @__PURE__ */ jsx(Text, { color: THEME.status.running, children: /* @__PURE__ */ jsx(Spinner, { type: "dots" }) }),
2864
+ /* @__PURE__ */ jsxs(Text, { color: THEME.text.muted, children: [
2865
+ " ",
2866
+ currentStatus,
2867
+ elapsedTime > 0 && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
2868
+ " (",
2869
+ elapsedTime,
2870
+ "s)"
2871
+ ] })
2872
+ ] })
2778
2873
  ] }) : /* @__PURE__ */ jsxs(Box, { children: [
2779
2874
  /* @__PURE__ */ jsx(Text, { color: THEME.status.success, children: "\u276F " }),
2780
2875
  /* @__PURE__ */ jsx(
@@ -2783,17 +2878,23 @@ var App = ({ autoApprove = false, target }) => {
2783
2878
  value: input,
2784
2879
  onChange: setInput,
2785
2880
  onSubmit: handleSubmit,
2786
- placeholder: "Type a message or /help..."
2881
+ placeholder: "Message or /help..."
2787
2882
  }
2788
2883
  )
2789
- ] }) }),
2790
- /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsxs(Text, { color: THEME.text.muted, dimColor: true, children: [
2791
- agent.getState().target ? `Target: ${agent.getState().target}` : "No target",
2792
- " | Findings: ",
2793
- agent.getState().findings.length,
2794
- " | Ctrl+C to ",
2795
- isProcessing ? "stop" : "exit"
2796
- ] }) })
2884
+ ] }),
2885
+ /* @__PURE__ */ jsxs(Box, { marginTop: 1, justifyContent: "space-between", children: [
2886
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
2887
+ state.target.primary || "No target",
2888
+ " \u2502",
2889
+ state.findings.length,
2890
+ " findings \u2502",
2891
+ state.currentPhase !== "idle" && ` ${state.currentPhase} \u2502`
2892
+ ] }),
2893
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
2894
+ "/help \u2502 Ctrl+C ",
2895
+ isProcessing ? "stop" : "exit"
2896
+ ] })
2897
+ ] })
2797
2898
  ] });
2798
2899
  };
2799
2900
  var app_default = App;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pentesting",
3
- "version": "0.1.6",
3
+ "version": "0.1.9",
4
4
  "description": "Autonomous Penetration Testing AI Agent",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",