pentesting 0.24.0 → 0.24.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 (3) hide show
  1. package/README.md +1 -1
  2. package/dist/main.js +174 -136
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -38,4 +38,4 @@ docker run -it --rm \
38
38
 
39
39
  ## Issue
40
40
 
41
- email: agnusdei1207@gmail.com
41
+ email: pentesting@agnusdei.kr
package/dist/main.js CHANGED
@@ -13,7 +13,7 @@ import chalk from "chalk";
13
13
  import gradient from "gradient-string";
14
14
 
15
15
  // src/platform/tui/app.tsx
16
- import { useState as useState4, useCallback as useCallback3, useEffect as useEffect4 } from "react";
16
+ import { useState as useState4, useCallback as useCallback3, useEffect as useEffect4, useRef as useRef3 } from "react";
17
17
  import { Box as Box6, useInput, useApp } from "ink";
18
18
 
19
19
  // src/platform/tui/hooks/useAgent.ts
@@ -127,11 +127,16 @@ var AGENT_LIMITS = {
127
127
  /** ID radix for generation */
128
128
  ID_RADIX: 36,
129
129
  /** Maximum token budget for LLM response (matches LLM_LIMITS.streamMaxTokens) */
130
- MAX_TOKENS: 32768,
130
+ MAX_TOKENS: 128e3,
131
131
  /** Maximum consecutive idle iterations before nudging agent (deadlock prevention) */
132
132
  MAX_CONSECUTIVE_IDLE: 3,
133
- /** Maximum tool output length before truncation (context hygiene) */
134
- MAX_TOOL_OUTPUT_LENGTH: 2e4,
133
+ /** Maximum tool output length before truncation (context hygiene)
134
+ * WHY 200K: pentesting tools (linpeas, enum4linux, nmap -sV --script=*)
135
+ * routinely produce 100K+ chars with critical findings scattered throughout.
136
+ * Truncation loses data the agent can never recover.
137
+ * Let the LLM see everything and summarize — it's what LLMs are good at.
138
+ */
139
+ MAX_TOOL_OUTPUT_LENGTH: 2e5,
135
140
  /** Max chars to include in blocked pattern tracking key (loop detection) */
136
141
  BLOCKED_PATTERN_KEY_SLICE: 80,
137
142
  /** Max chars of error text to include in web_search suggestion */
@@ -161,7 +166,7 @@ var INPUT_PROMPT_PATTERNS = [
161
166
  /\(Y\/n\)/i
162
167
  ];
163
168
 
164
- // src/shared/constants/exit-codes.ts
169
+ // src/shared/constants/system.ts
165
170
  var EXIT_CODES = {
166
171
  /** Successful execution */
167
172
  SUCCESS: 0,
@@ -178,12 +183,110 @@ var EXIT_CODES = {
178
183
  /** Process killed by SIGKILL */
179
184
  SIGKILL: 137
180
185
  };
186
+ var PROCESS_ROLES = {
187
+ LISTENER: "listener",
188
+ ACTIVE_SHELL: "active_shell",
189
+ SERVER: "server",
190
+ SNIFFER: "sniffer",
191
+ SPOOFER: "spoofer",
192
+ CALLBACK: "callback",
193
+ PROXY: "proxy",
194
+ BACKGROUND: "background"
195
+ };
196
+ var PROCESS_ICONS = {
197
+ [PROCESS_ROLES.LISTENER]: "[LISTENER]",
198
+ [PROCESS_ROLES.ACTIVE_SHELL]: "[SHELL]",
199
+ [PROCESS_ROLES.SERVER]: "[SERVER]",
200
+ [PROCESS_ROLES.SNIFFER]: "[SNIFFER]",
201
+ [PROCESS_ROLES.SPOOFER]: "[SPOOFER]",
202
+ [PROCESS_ROLES.CALLBACK]: "[CALLBACK]",
203
+ [PROCESS_ROLES.PROXY]: "[PROXY]",
204
+ [PROCESS_ROLES.BACKGROUND]: "[BG]"
205
+ };
206
+ var STATUS_MARKERS = {
207
+ RUNNING: "[RUNNING]",
208
+ STOPPED: "[STOPPED]",
209
+ WARNING: "[WARNING]",
210
+ INTERACTIVE: "[INTERACTIVE]",
211
+ EXITED: "[EXITED]"
212
+ };
213
+ var PROCESS_EVENTS = {
214
+ STARTED: "started",
215
+ CONNECTION_DETECTED: "connection_detected",
216
+ ROLE_CHANGED: "role_changed",
217
+ COMMAND_SENT: "command_sent",
218
+ STOPPED: "stopped",
219
+ DIED: "died",
220
+ ZOMBIE_CLEANED: "zombie_cleaned"
221
+ };
222
+ var SYSTEM_LIMITS = {
223
+ /** Maximum wait time for interactive shell responses (10 seconds) */
224
+ MAX_WAIT_MS_INTERACT: 1e4,
225
+ /** Default wait time for interactive shell responses (2 seconds) */
226
+ DEFAULT_WAIT_MS_INTERACT: 2e3,
227
+ /** Maximum characters for process description */
228
+ MAX_DESCRIPTION_LENGTH: 80,
229
+ /** Maximum characters for stored command string */
230
+ MAX_COMMAND_LENGTH: 200,
231
+ /** Maximum characters to show from stdout
232
+ * WHY 50K: background processes (linpeas, scans, shells) produce large
233
+ * output with findings scattered throughout. Let the LLM see it all. */
234
+ MAX_STDOUT_SLICE: 5e4,
235
+ /** Maximum characters to show from stderr */
236
+ MAX_STDERR_SLICE: 5e3,
237
+ /** Maximum characters for error detail messages */
238
+ MAX_ERROR_DETAIL_SLICE: 2e3,
239
+ /** Maximum characters for input prompt previews */
240
+ MAX_PROMPT_PREVIEW: 50,
241
+ /** Maximum characters for input snippets in logs */
242
+ MAX_INPUT_SLICE: 100,
243
+ /** Maximum events to keep in process event log */
244
+ MAX_EVENT_LOG: 30,
245
+ /** Wait time for child PID discovery via pgrep */
246
+ CHILD_PID_DISCOVERY_MS: 500,
247
+ /** Wait time between SIGTERM and SIGKILL during graceful shutdown */
248
+ SHUTDOWN_WAIT_MS: 500,
249
+ /** Wait time between process cleanup batches */
250
+ CLEANUP_BATCH_WAIT_MS: 300,
251
+ /** Timeout for pgrep and pkill operations */
252
+ PROCESS_OP_TIMEOUT_MS: 2e3,
253
+ /** Port range for web services (development servers) */
254
+ WEB_PORT_RANGE: { MIN: 8e3, MAX: 9e3 },
255
+ /** Port range for API services */
256
+ API_PORT_RANGE: { MIN: 3e3, MAX: 3500 }
257
+ };
258
+ var DETECTION_PATTERNS = {
259
+ LISTENER: /-(?:lvnp|nlvp|lp|p)\s+(\d+)/,
260
+ HTTP_SERVER: /(?:http\.server|SimpleHTTPServer)\s+(\d+)/,
261
+ GENERIC_PORT: /-(?:p|port|S)\s+(?:\S+:)?(\d+)/,
262
+ CONNECTION: [
263
+ /connection\s+from/i,
264
+ /connect\s+to/i,
265
+ /\$\s*$/m,
266
+ /#\s*$/m,
267
+ /bash-\d/i,
268
+ /sh-\d/i,
269
+ /www-data/i
270
+ ]
271
+ };
272
+ var ORPHAN_PROCESS_NAMES = [
273
+ "arpspoof",
274
+ "ettercap",
275
+ "mitmdump",
276
+ "mitmproxy",
277
+ "dnsspoof",
278
+ "tcpdump",
279
+ "tshark",
280
+ "socat",
281
+ "nc",
282
+ "python"
283
+ ];
181
284
 
182
285
  // src/shared/constants/agent.ts
183
286
  var ID_LENGTH = AGENT_LIMITS.ID_LENGTH;
184
287
  var ID_RADIX = AGENT_LIMITS.ID_RADIX;
185
288
  var APP_NAME = "Pentest AI";
186
- var APP_VERSION = "0.24.0";
289
+ var APP_VERSION = "0.24.2";
187
290
  var APP_DESCRIPTION = "Autonomous Penetration Testing AI Agent";
188
291
  var LLM_ROLES = {
189
292
  SYSTEM: "system",
@@ -499,104 +602,6 @@ function ensureDirExists(dirPath) {
499
602
  }
500
603
  }
501
604
 
502
- // src/shared/constants/system.ts
503
- var PROCESS_ROLES = {
504
- LISTENER: "listener",
505
- ACTIVE_SHELL: "active_shell",
506
- SERVER: "server",
507
- SNIFFER: "sniffer",
508
- SPOOFER: "spoofer",
509
- CALLBACK: "callback",
510
- PROXY: "proxy",
511
- BACKGROUND: "background"
512
- };
513
- var PROCESS_ICONS = {
514
- [PROCESS_ROLES.LISTENER]: "[LISTENER]",
515
- [PROCESS_ROLES.ACTIVE_SHELL]: "[SHELL]",
516
- [PROCESS_ROLES.SERVER]: "[SERVER]",
517
- [PROCESS_ROLES.SNIFFER]: "[SNIFFER]",
518
- [PROCESS_ROLES.SPOOFER]: "[SPOOFER]",
519
- [PROCESS_ROLES.CALLBACK]: "[CALLBACK]",
520
- [PROCESS_ROLES.PROXY]: "[PROXY]",
521
- [PROCESS_ROLES.BACKGROUND]: "[BG]"
522
- };
523
- var STATUS_MARKERS = {
524
- RUNNING: "[RUNNING]",
525
- STOPPED: "[STOPPED]",
526
- WARNING: "[WARNING]",
527
- INTERACTIVE: "[INTERACTIVE]",
528
- EXITED: "[EXITED]"
529
- };
530
- var PROCESS_EVENTS = {
531
- STARTED: "started",
532
- CONNECTION_DETECTED: "connection_detected",
533
- ROLE_CHANGED: "role_changed",
534
- COMMAND_SENT: "command_sent",
535
- STOPPED: "stopped",
536
- DIED: "died",
537
- ZOMBIE_CLEANED: "zombie_cleaned"
538
- };
539
- var SYSTEM_LIMITS = {
540
- /** Maximum wait time for interactive shell responses (10 seconds) */
541
- MAX_WAIT_MS_INTERACT: 1e4,
542
- /** Default wait time for interactive shell responses (2 seconds) */
543
- DEFAULT_WAIT_MS_INTERACT: 2e3,
544
- /** Maximum characters for process description */
545
- MAX_DESCRIPTION_LENGTH: 80,
546
- /** Maximum characters for stored command string */
547
- MAX_COMMAND_LENGTH: 200,
548
- /** Maximum characters to show from stdout */
549
- MAX_STDOUT_SLICE: 3e3,
550
- /** Maximum characters to show from stderr */
551
- MAX_STDERR_SLICE: 500,
552
- /** Maximum characters for error detail messages */
553
- MAX_ERROR_DETAIL_SLICE: 200,
554
- /** Maximum characters for input prompt previews */
555
- MAX_PROMPT_PREVIEW: 50,
556
- /** Maximum characters for input snippets in logs */
557
- MAX_INPUT_SLICE: 100,
558
- /** Maximum events to keep in process event log */
559
- MAX_EVENT_LOG: 30,
560
- /** Wait time for child PID discovery via pgrep */
561
- CHILD_PID_DISCOVERY_MS: 500,
562
- /** Wait time between SIGTERM and SIGKILL during graceful shutdown */
563
- SHUTDOWN_WAIT_MS: 500,
564
- /** Wait time between process cleanup batches */
565
- CLEANUP_BATCH_WAIT_MS: 300,
566
- /** Timeout for pgrep and pkill operations */
567
- PROCESS_OP_TIMEOUT_MS: 2e3,
568
- /** Port range for web services (development servers) */
569
- WEB_PORT_RANGE: { MIN: 8e3, MAX: 9e3 },
570
- /** Port range for API services */
571
- API_PORT_RANGE: { MIN: 3e3, MAX: 3500 }
572
- };
573
- var DETECTION_PATTERNS = {
574
- LISTENER: /-(?:lvnp|nlvp|lp|p)\s+(\d+)/,
575
- HTTP_SERVER: /(?:http\.server|SimpleHTTPServer)\s+(\d+)/,
576
- GENERIC_PORT: /-(?:p|port|S)\s+(?:\S+:)?(\d+)/,
577
- CONNECTION: [
578
- /connection\s+from/i,
579
- /connect\s+to/i,
580
- /\$\s*$/m,
581
- /#\s*$/m,
582
- /bash-\d/i,
583
- /sh-\d/i,
584
- /www-data/i
585
- ]
586
- };
587
- var ORPHAN_PROCESS_NAMES = [
588
- "arpspoof",
589
- "ettercap",
590
- "mitmdump",
591
- "mitmproxy",
592
- "dnsspoof",
593
- "tcpdump",
594
- "tshark",
595
- "socat",
596
- "nc",
597
- "python"
598
- ];
599
-
600
605
  // src/shared/utils/command-security-lists.ts
601
606
  var ALLOWED_BINARIES = /* @__PURE__ */ new Set([
602
607
  // Network scanning
@@ -5496,7 +5501,7 @@ var ZombieHunter = class {
5496
5501
 
5497
5502
  // src/shared/constants/orchestrator.ts
5498
5503
  var GRACEFUL_SHUTDOWN_WAIT_MS = 200;
5499
- var PROCESS_OUTPUT_TRUNCATION_LIMIT = 500;
5504
+ var PROCESS_OUTPUT_TRUNCATION_LIMIT = 1e4;
5500
5505
  var MS_PER_MINUTE = 6e4;
5501
5506
  var LONG_RUNNING_THRESHOLD_MS = 5 * MS_PER_MINUTE;
5502
5507
  var VERY_LONG_RUNNING_THRESHOLD_MS = 15 * MS_PER_MINUTE;
@@ -6167,8 +6172,12 @@ var RETRY_CONFIG = {
6167
6172
  // Initial delay for rate limit retry (exponential backoff)
6168
6173
  };
6169
6174
  var LLM_LIMITS = {
6170
- nonStreamMaxTokens: 16384,
6171
- streamMaxTokens: 32768,
6175
+ /** WHY 64K: non-streaming calls (orchestrator, summaries) benefit from
6176
+ * generous output budgets. Don't force premature truncation. */
6177
+ nonStreamMaxTokens: 65536,
6178
+ /** WHY 128K: streaming calls are the main agent loop. Max out so the LLM
6179
+ * can produce full analysis, tool calls, and reasoning without cutoff. */
6180
+ streamMaxTokens: 128e3,
6172
6181
  /** WHY: ~3.5 chars/token is a reasonable average for mixed English/CJK content */
6173
6182
  charsPerTokenEstimate: 3.5
6174
6183
  };
@@ -7798,14 +7807,32 @@ var THEME = {
7798
7807
  identity: "#38bdf8"
7799
7808
  };
7800
7809
  var ASCII_BANNER = `
7801
- \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557
7802
- \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D
7803
- \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2557
7804
- \u2588\u2588\u2554\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551
7805
- \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D
7806
- \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D
7807
- \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
7808
- A U T O N O M O U S S E C U R I T Y A G E N T
7810
+ \u2571\u2594\u2594\u2572
7811
+ \u2571\u2594 \u2594\u2572
7812
+ \u2571\u2594 \u2694 \u2594\u2572
7813
+ \u2571\u2594 \u2594\u2572
7814
+ \u2571\u2594 \u2594\u2572
7815
+ \u2571\u2594 \u2594\u2572
7816
+ \u2571\u2594 \u2594\u2572
7817
+ \u2571\u2594 \u2594\u2572
7818
+ \u2572\u2581 \u2581\u2571
7819
+ \u2572\u2581\u2581 \u2581\u2581\u2571
7820
+ \u2572\u2581\u2581 \u2581\u2581\u2571
7821
+ \u2500\u2500\u2500\u2500\u2500\u2573\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2573\u2500\u2500\u2500\u2500\u2500
7822
+ \u2572 \u2571
7823
+ \u2572 \u2571
7824
+ \u2572 \u2571
7825
+ \u2572 \u2571
7826
+ \u2572 \u2571
7827
+ \u25C9
7828
+
7829
+ \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557
7830
+ \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D
7831
+ \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551
7832
+ \u2588\u2588\u2554\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551 \u2588\u2588\u2551
7833
+ \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551
7834
+ \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D
7835
+ A U T O N O M O U S P E N T E S T A G E N T
7809
7836
  `;
7810
7837
  var ICONS = {
7811
7838
  // Status
@@ -7971,6 +7998,7 @@ var useAgentState = () => {
7971
7998
  }, []);
7972
7999
  const manageTimer = useCallback((action) => {
7973
8000
  if (action === "start") {
8001
+ if (timerRef.current) clearInterval(timerRef.current);
7974
8002
  startTimeRef.current = Date.now();
7975
8003
  timerRef.current = setInterval(() => {
7976
8004
  setElapsedTime(Math.floor((Date.now() - startTimeRef.current) / 1e3));
@@ -8025,6 +8053,7 @@ var useAgentEvents = (agent, eventsRef, state) => {
8025
8053
  setCurrentStatus,
8026
8054
  setRetryState,
8027
8055
  setCurrentTokens,
8056
+ setInputRequest,
8028
8057
  setStats,
8029
8058
  lastResponseMetaRef,
8030
8059
  retryCountdownRef,
@@ -8077,7 +8106,7 @@ var useAgentEvents = (agent, eventsRef, state) => {
8077
8106
  return new Promise((resolve) => {
8078
8107
  const isPassword = /password|passphrase/i.test(p);
8079
8108
  const inputType = /sudo/i.test(p) ? "sudo_password" : isPassword ? "password" : "text";
8080
- state.setInputRequest({
8109
+ setInputRequest({
8081
8110
  isActive: true,
8082
8111
  prompt: p.trim(),
8083
8112
  isPassword,
@@ -8091,7 +8120,7 @@ var useAgentEvents = (agent, eventsRef, state) => {
8091
8120
  const hiddenTypes = ["password", "sudo_password", "ssh_password", "passphrase", "api_key", "credential"];
8092
8121
  const isPassword = hiddenTypes.includes(request.type);
8093
8122
  const displayPrompt = buildCredentialPrompt(request);
8094
- state.setInputRequest({
8123
+ setInputRequest({
8095
8124
  isActive: true,
8096
8125
  prompt: displayPrompt,
8097
8126
  isPassword,
@@ -8139,6 +8168,7 @@ var useAgentEvents = (agent, eventsRef, state) => {
8139
8168
  setCurrentStatus,
8140
8169
  setRetryState,
8141
8170
  setCurrentTokens,
8171
+ setInputRequest,
8142
8172
  setStats,
8143
8173
  lastResponseMetaRef,
8144
8174
  retryCountdownRef,
@@ -8146,7 +8176,7 @@ var useAgentEvents = (agent, eventsRef, state) => {
8146
8176
  tokenAccumRef,
8147
8177
  lastStepTokensRef,
8148
8178
  clearAllTimers,
8149
- state
8179
+ eventsRef
8150
8180
  ]);
8151
8181
  };
8152
8182
  function formatToolInput(toolName, input) {
@@ -8229,6 +8259,7 @@ var useAgent = (shouldAutoApprove, target) => {
8229
8259
  isProcessing,
8230
8260
  setIsProcessing,
8231
8261
  currentStatus,
8262
+ setCurrentStatus,
8232
8263
  elapsedTime,
8233
8264
  retryState,
8234
8265
  currentTokens,
@@ -8250,7 +8281,7 @@ var useAgent = (shouldAutoApprove, target) => {
8250
8281
  const executeTask = useCallback2(async (task) => {
8251
8282
  setIsProcessing(true);
8252
8283
  manageTimer("start");
8253
- state.setCurrentStatus("Thinking");
8284
+ setCurrentStatus("Thinking");
8254
8285
  resetCumulativeCounters();
8255
8286
  try {
8256
8287
  const response = await agent.execute(task);
@@ -8262,23 +8293,26 @@ var useAgent = (shouldAutoApprove, target) => {
8262
8293
  } finally {
8263
8294
  manageTimer("stop");
8264
8295
  setIsProcessing(false);
8265
- state.setCurrentStatus("");
8296
+ setCurrentStatus("");
8266
8297
  }
8267
- }, [agent, addMessage, manageTimer, resetCumulativeCounters, setIsProcessing, lastResponseMetaRef, state]);
8298
+ }, [agent, addMessage, manageTimer, resetCumulativeCounters, setIsProcessing, lastResponseMetaRef, setCurrentStatus]);
8268
8299
  const abort = useCallback2(() => {
8269
8300
  agent.abort();
8270
8301
  setIsProcessing(false);
8271
8302
  manageTimer("stop");
8272
- state.setCurrentStatus("");
8303
+ setCurrentStatus("");
8273
8304
  addMessage("system", "Interrupted");
8274
- }, [agent, addMessage, manageTimer, setIsProcessing, state]);
8305
+ }, [agent, addMessage, manageTimer, setIsProcessing, setCurrentStatus]);
8306
+ const inputRequestRef = useRef2(inputRequest);
8307
+ inputRequestRef.current = inputRequest;
8275
8308
  const cancelInputRequest = useCallback2(() => {
8276
- if (inputRequest.isActive && inputRequest.resolve) {
8277
- inputRequest.resolve(null);
8309
+ const ir = inputRequestRef.current;
8310
+ if (ir.isActive && ir.resolve) {
8311
+ ir.resolve(null);
8278
8312
  setInputRequest({ isActive: false, prompt: "", isPassword: false, resolve: null });
8279
8313
  addMessage("system", "Input cancelled");
8280
8314
  }
8281
- }, [inputRequest, setInputRequest, addMessage]);
8315
+ }, [setInputRequest, addMessage]);
8282
8316
  return {
8283
8317
  agent,
8284
8318
  messages,
@@ -8674,13 +8708,16 @@ var App = ({ autoApprove = false, target }) => {
8674
8708
  cancelInputRequest,
8675
8709
  addMessage
8676
8710
  } = useAgent(autoApproveMode, target);
8711
+ const inputRequestRef = useRef3(inputRequest);
8712
+ inputRequestRef.current = inputRequest;
8677
8713
  const handleExit = useCallback3(() => {
8678
- if (inputRequest.isActive && inputRequest.resolve) inputRequest.resolve(null);
8714
+ const ir = inputRequestRef.current;
8715
+ if (ir.isActive && ir.resolve) ir.resolve(null);
8679
8716
  cleanupAllProcesses().catch(() => {
8680
8717
  });
8681
8718
  exit();
8682
8719
  setTimeout(() => process.exit(0), DISPLAY_LIMITS.EXIT_DELAY);
8683
- }, [exit, inputRequest, cancelInputRequest]);
8720
+ }, [exit]);
8684
8721
  const handleCommand = useCallback3(async (cmd, args) => {
8685
8722
  switch (cmd) {
8686
8723
  case UI_COMMANDS.HELP:
@@ -8780,21 +8817,22 @@ ${procData.stdout || "(no output)"}
8780
8817
  }
8781
8818
  }, [addMessage, executeTask, handleCommand]);
8782
8819
  const handleSecretSubmit = useCallback3((value) => {
8783
- if (!inputRequest.isActive || !inputRequest.resolve) return;
8784
- const displayText = inputRequest.isPassword ? "\u2022".repeat(value.length) : value;
8785
- const promptLabel = inputRequest.prompt || "Input";
8820
+ const ir = inputRequestRef.current;
8821
+ if (!ir.isActive || !ir.resolve) return;
8822
+ const displayText = ir.isPassword ? "\u2022".repeat(value.length) : value;
8823
+ const promptLabel = ir.prompt || "Input";
8786
8824
  addMessage("system", `\u21B3 ${promptLabel} ${displayText}`);
8787
- inputRequest.resolve(value);
8825
+ ir.resolve(value);
8788
8826
  setInputRequest({ isActive: false, prompt: "", isPassword: false, resolve: null });
8789
8827
  setSecretInput("");
8790
- }, [inputRequest, addMessage, setInputRequest]);
8791
- useInput((ch, key) => {
8828
+ }, [addMessage, setInputRequest]);
8829
+ useInput(useCallback3((ch, key) => {
8792
8830
  if (key.escape) {
8793
- if (inputRequest.isActive) cancelInputRequest();
8831
+ if (inputRequestRef.current.isActive) cancelInputRequest();
8794
8832
  else if (isProcessing) abort();
8795
8833
  }
8796
8834
  if (key.ctrl && ch === "c") handleExit();
8797
- });
8835
+ }, [cancelInputRequest, isProcessing, abort, handleExit]));
8798
8836
  useEffect4(() => {
8799
8837
  const onSignal = () => handleExit();
8800
8838
  process.on("SIGINT", onSignal);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pentesting",
3
- "version": "0.24.0",
3
+ "version": "0.24.2",
4
4
  "description": "Autonomous Penetration Testing AI Agent",
5
5
  "type": "module",
6
6
  "main": "dist/main.js",
@@ -19,7 +19,7 @@
19
19
  "dev:tsx": "tsx src/platform/tui/main.tsx",
20
20
  "build": "tsup",
21
21
  "start": "node dist/main.js",
22
- "test": "vitest run",
22
+ "test": "mkdir -p /tmp/pentesting-vitest && TMPDIR=/tmp/pentesting-vitest vitest run",
23
23
  "test:watch": "vitest",
24
24
  "lint": "tsc --noEmit",
25
25
  "prepublishOnly": "npm run build",