pentesting 0.73.5 → 0.73.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -42,11 +42,10 @@ import {
42
42
  rotateTurnRecords,
43
43
  setCurrentTurn,
44
44
  writePolicyDocument
45
- } from "./chunk-ULP6TF2X.js";
45
+ } from "./chunk-HSZZHAGX.js";
46
46
  import {
47
47
  AGENT_ROLES,
48
48
  APP_DESCRIPTION,
49
- APP_NAME,
50
49
  APP_VERSION,
51
50
  AUXILIARY_WORK_TYPES,
52
51
  COMMAND_EVENT_TYPES,
@@ -85,15 +84,15 @@ import {
85
84
  setActiveSessionRuntime,
86
85
  setTorEnabled,
87
86
  snapshotToPrompt
88
- } from "./chunk-EIPVHHPI.js";
87
+ } from "./chunk-4HG57VDC.js";
89
88
  import {
90
89
  EXIT_CODES,
91
90
  getOptionalRuntimeSection,
92
91
  getRequiredRuntimeSection
93
- } from "./chunk-I52SWXYV.js";
92
+ } from "./chunk-KAUE3MSR.js";
94
93
 
95
94
  // src/platform/tui/main.tsx
96
- import chalk5 from "chalk";
95
+ import chalk4 from "chalk";
97
96
 
98
97
  // src/shared/constants/theme.ts
99
98
  var HEX = {
@@ -946,8 +945,25 @@ async function executeLayer(layer, ctx) {
946
945
  }
947
946
 
948
947
  // src/agents/prompt-builder/prompt-section-builder.ts
948
+ function getLayerSortKey(id) {
949
+ if (typeof id === "number") {
950
+ return { rank: id, tieBreak: "" };
951
+ }
952
+ const numericPrefix = Number.parseFloat(id);
953
+ if (Number.isFinite(numericPrefix)) {
954
+ return { rank: numericPrefix, tieBreak: id };
955
+ }
956
+ return { rank: Number.POSITIVE_INFINITY, tieBreak: id };
957
+ }
949
958
  function sortLayersByPriority(layers) {
950
- return [...layers].sort((a, b) => a.id - b.id);
959
+ return [...layers].sort((a, b) => {
960
+ const left = getLayerSortKey(a.id);
961
+ const right = getLayerSortKey(b.id);
962
+ if (left.rank !== right.rank) {
963
+ return left.rank - right.rank;
964
+ }
965
+ return left.tieBreak.localeCompare(right.tieBreak);
966
+ });
951
967
  }
952
968
  async function buildPromptSections(layers, ctx) {
953
969
  const sortedLayers = sortLayersByPriority(layers);
@@ -1476,7 +1492,7 @@ var makeRotateTurns = (_llm, _opts) => async (_ctx) => {
1476
1492
  };
1477
1493
  var makeSaveSession = (_llm, _opts) => async (ctx) => {
1478
1494
  try {
1479
- const { saveState: saveState2 } = await import("./persistence-EFKMGPYS.js");
1495
+ const { saveState: saveState2 } = await import("./persistence-TBJPBHKF.js");
1480
1496
  saveState2(ctx.state);
1481
1497
  } catch {
1482
1498
  }
@@ -3479,7 +3495,8 @@ var MainAgent = class extends CoreAgent {
3479
3495
  agentType: AGENT_ROLES.ORCHESTRATOR,
3480
3496
  state: options.state,
3481
3497
  events: options.events,
3482
- toolRegistry: options.toolRegistry
3498
+ toolRegistry: options.toolRegistry,
3499
+ maxIterations: options.maxIterations
3483
3500
  });
3484
3501
  this.approvalGate = options.approvalGate;
3485
3502
  this.scopeGuard = options.scopeGuard;
@@ -3721,10 +3738,10 @@ import { render } from "ink";
3721
3738
  import { Box as Box18 } from "ink";
3722
3739
 
3723
3740
  // src/platform/tui/hooks/useAgent.ts
3724
- import { useState as useState6, useEffect as useEffect2, useCallback as useCallback6, useRef as useRef6 } from "react";
3741
+ import { useState as useState6, useEffect as useEffect2, useCallback as useCallback7, useRef as useRef7 } from "react";
3725
3742
 
3726
3743
  // src/agents/factory.ts
3727
- function createMainAgent(autoApproveTools = false) {
3744
+ function createMainAgent(autoApproveTools = false, maxIterations) {
3728
3745
  const state = new SharedState();
3729
3746
  const events = new AgentEventEmitter();
3730
3747
  const approvalGate = new ApprovalGate(autoApproveTools);
@@ -3735,7 +3752,14 @@ function createMainAgent(autoApproveTools = false) {
3735
3752
  approvalGate,
3736
3753
  events
3737
3754
  );
3738
- return AgentRuntime.build({ state, events, toolRegistry, approvalGate, scopeGuard });
3755
+ return AgentRuntime.build({
3756
+ state,
3757
+ events,
3758
+ toolRegistry,
3759
+ approvalGate,
3760
+ scopeGuard,
3761
+ maxIterations
3762
+ });
3739
3763
  }
3740
3764
 
3741
3765
  // src/platform/tui/hooks/useAgentState.ts
@@ -4864,6 +4888,83 @@ var useAgentEvents = (agent, eventsRef, state, isTyping = false) => {
4864
4888
  ]);
4865
4889
  };
4866
4890
 
4891
+ // src/platform/tui/hooks/useAgentTaskRunner.ts
4892
+ import { useCallback as useCallback6, useRef as useRef6 } from "react";
4893
+ function shouldContinueWithQueuedInput(agent, isAborted) {
4894
+ return isAborted && agent.hasPendingUserInput();
4895
+ }
4896
+ async function runAgentTaskLoop({
4897
+ agent,
4898
+ initialTask,
4899
+ state,
4900
+ clearAborted,
4901
+ isAborted
4902
+ }) {
4903
+ let currentTask = initialTask;
4904
+ while (true) {
4905
+ clearAborted();
4906
+ state.setTurnCount((n) => n + 1);
4907
+ state.setIsProcessing(true);
4908
+ state.manageTimer("start");
4909
+ state.setCurrentStatus(UI_MESSAGES.STATUS_THINKING);
4910
+ state.resetCumulativeCounters();
4911
+ let continuing = false;
4912
+ try {
4913
+ await agent.execute(currentTask);
4914
+ if (shouldContinueWithQueuedInput(agent, isAborted())) {
4915
+ currentTask = "";
4916
+ continuing = true;
4917
+ continue;
4918
+ }
4919
+ if (agent.hasPendingUserInput()) {
4920
+ currentTask = "";
4921
+ continuing = true;
4922
+ continue;
4923
+ }
4924
+ break;
4925
+ } catch (error) {
4926
+ if (shouldContinueWithQueuedInput(agent, isAborted())) {
4927
+ currentTask = "";
4928
+ continuing = true;
4929
+ continue;
4930
+ }
4931
+ if (!isAborted()) {
4932
+ state.addMessage("error", error instanceof Error ? error.message : String(error));
4933
+ }
4934
+ break;
4935
+ } finally {
4936
+ if (!isAborted() && !continuing) {
4937
+ state.manageTimer("stop");
4938
+ state.setIsProcessing(false);
4939
+ state.setCurrentStatus("");
4940
+ }
4941
+ }
4942
+ }
4943
+ }
4944
+ function useAgentTaskRunner(agent, state) {
4945
+ const abortedRef = useRef6(false);
4946
+ const executeTask = useCallback6(async (task) => {
4947
+ await runAgentTaskLoop({
4948
+ agent,
4949
+ initialTask: task,
4950
+ state,
4951
+ clearAborted: () => {
4952
+ abortedRef.current = false;
4953
+ },
4954
+ isAborted: () => abortedRef.current
4955
+ });
4956
+ }, [agent, state]);
4957
+ const abort = useCallback6(() => {
4958
+ abortedRef.current = true;
4959
+ agent.abort();
4960
+ state.setIsProcessing(false);
4961
+ state.manageTimer("stop");
4962
+ state.setCurrentStatus("");
4963
+ state.addMessage("system", UI_MESSAGES.INTERRUPTED);
4964
+ }, [agent, state]);
4965
+ return { abort, executeTask };
4966
+ }
4967
+
4867
4968
  // src/platform/tui/hooks/useAgent.ts
4868
4969
  function trimQueuedMessages(queue, maxLength, maxItems) {
4869
4970
  const trimmed = queue.map((text) => truncate(text, maxLength));
@@ -4872,7 +4973,7 @@ function trimQueuedMessages(queue, maxLength, maxItems) {
4872
4973
  }
4873
4974
  var useAgent = (shouldAutoApprove, target, isTyping = false) => {
4874
4975
  const [agent] = useState6(() => createMainAgent(shouldAutoApprove));
4875
- const eventsRef = useRef6(agent.getEventEmitter());
4976
+ const eventsRef = useRef7(agent.getEventEmitter());
4876
4977
  const state = useAgentState(isTyping);
4877
4978
  const {
4878
4979
  messages,
@@ -4898,8 +4999,8 @@ var useAgent = (shouldAutoApprove, target, isTyping = false) => {
4898
4999
  cancelAllInputRequests
4899
5000
  } = state;
4900
5001
  const [messageQueue, setMessageQueue] = useState6([]);
4901
- const messageQueueLengthRef = useRef6(0);
4902
- const setMessageQueueSafe = useCallback6((value) => {
5002
+ const messageQueueLengthRef = useRef7(0);
5003
+ const setMessageQueueSafe = useCallback7((value) => {
4903
5004
  setMessageQueue((prev) => {
4904
5005
  const next = typeof value === "function" ? value(prev) : value;
4905
5006
  return trimQueuedMessages(
@@ -4935,76 +5036,29 @@ var useAgent = (shouldAutoApprove, target, isTyping = false) => {
4935
5036
  };
4936
5037
  }, [agent, addMessage, setMessageQueueSafe]);
4937
5038
  useAgentEvents(agent, eventsRef, state, isTyping);
4938
- const abortedRef = useRef6(false);
4939
- const executeTask = useCallback6(async (task) => {
4940
- let currentTask = task;
4941
- while (true) {
4942
- abortedRef.current = false;
4943
- setTurnCount((n) => n + 1);
4944
- setIsProcessing(true);
4945
- manageTimer("start");
4946
- setCurrentStatus(UI_MESSAGES.STATUS_THINKING);
4947
- resetCumulativeCounters();
4948
- let continuing = false;
4949
- try {
4950
- const response = await agent.execute(currentTask);
4951
- if (abortedRef.current) {
4952
- if (agent.hasPendingUserInput()) {
4953
- currentTask = "";
4954
- continuing = true;
4955
- continue;
4956
- }
4957
- return;
4958
- }
4959
- if (agent.hasPendingUserInput()) {
4960
- currentTask = "";
4961
- continuing = true;
4962
- continue;
4963
- }
4964
- break;
4965
- } catch (e) {
4966
- if (abortedRef.current) {
4967
- if (agent.hasPendingUserInput()) {
4968
- currentTask = "";
4969
- continuing = true;
4970
- continue;
4971
- }
4972
- return;
4973
- }
4974
- addMessage("error", e instanceof Error ? e.message : String(e));
4975
- break;
4976
- } finally {
4977
- if (!abortedRef.current && !continuing) {
4978
- manageTimer("stop");
4979
- setIsProcessing(false);
4980
- setCurrentStatus("");
4981
- }
4982
- }
4983
- }
4984
- }, [agent, addMessage, manageTimer, resetCumulativeCounters, setIsProcessing, setCurrentStatus, setTurnCount]);
4985
- const abort = useCallback6(() => {
4986
- abortedRef.current = true;
4987
- agent.abort();
4988
- setIsProcessing(false);
4989
- manageTimer("stop");
4990
- setCurrentStatus("");
4991
- addMessage("system", UI_MESSAGES.INTERRUPTED);
4992
- }, [agent, addMessage, manageTimer, setIsProcessing, setCurrentStatus]);
4993
- const recallQueuedInput = useCallback6(() => {
5039
+ const { executeTask, abort } = useAgentTaskRunner(agent, {
5040
+ addMessage,
5041
+ manageTimer,
5042
+ resetCumulativeCounters,
5043
+ setCurrentStatus,
5044
+ setIsProcessing,
5045
+ setTurnCount
5046
+ });
5047
+ const recallQueuedInput = useCallback7(() => {
4994
5048
  const recalled = agent.dequeueLastUserInput();
4995
5049
  if (!recalled) return null;
4996
5050
  return recalled;
4997
5051
  }, [agent]);
4998
- const inputRequestRef = useRef6(inputRequest);
5052
+ const inputRequestRef = useRef7(inputRequest);
4999
5053
  inputRequestRef.current = inputRequest;
5000
- const cancelInputRequest = useCallback6(() => {
5054
+ const cancelInputRequest = useCallback7(() => {
5001
5055
  const ir = inputRequestRef.current;
5002
5056
  if (ir.status === "active") {
5003
5057
  settleActiveInputRequest(null);
5004
5058
  addMessage("system", UI_MESSAGES.INPUT_CANCELLED);
5005
5059
  }
5006
5060
  }, [settleActiveInputRequest, addMessage]);
5007
- const refreshStats = useCallback6(() => {
5061
+ const refreshStats = useCallback7(() => {
5008
5062
  const s = agent.getState();
5009
5063
  setStats({
5010
5064
  phase: s.getPhase() || PHASES.RECON,
@@ -5042,7 +5096,7 @@ var useAgent = (shouldAutoApprove, target, isTyping = false) => {
5042
5096
  };
5043
5097
 
5044
5098
  // src/platform/tui/hooks/commands/index.ts
5045
- import { useCallback as useCallback7, useMemo } from "react";
5099
+ import { useCallback as useCallback8, useMemo } from "react";
5046
5100
 
5047
5101
  // src/platform/tui/constants/commands.ts
5048
5102
  var COMMAND_DEFINITIONS = [
@@ -5619,7 +5673,7 @@ var useCommands = (props) => {
5619
5673
  ...createDisplayCommands(ctx),
5620
5674
  ...createToggleCommands(ctx)
5621
5675
  }), [ctx]);
5622
- const handleCommand = useCallback7(async (cmd, args) => {
5676
+ const handleCommand = useCallback8(async (cmd, args) => {
5623
5677
  const handler = handlers[cmd];
5624
5678
  if (handler) {
5625
5679
  await handler(args);
@@ -5631,15 +5685,15 @@ var useCommands = (props) => {
5631
5685
  };
5632
5686
 
5633
5687
  // src/platform/tui/hooks/useKeyboardShortcuts.ts
5634
- import { useCallback as useCallback10, useEffect as useEffect4 } from "react";
5688
+ import { useCallback as useCallback11, useEffect as useEffect4 } from "react";
5635
5689
  import { useInput } from "ink";
5636
5690
 
5637
5691
  // src/platform/tui/hooks/keyboard/useDoubleTap.ts
5638
- import { useRef as useRef7, useCallback as useCallback8, useEffect as useEffect3 } from "react";
5692
+ import { useRef as useRef8, useCallback as useCallback9, useEffect as useEffect3 } from "react";
5639
5693
  var useDoubleTap = ({ onFirstTap, onSecondTap, windowMs }) => {
5640
- const timerRef = useRef7(null);
5641
- const pressedRef = useRef7(false);
5642
- const trigger = useCallback8(() => {
5694
+ const timerRef = useRef8(null);
5695
+ const pressedRef = useRef8(false);
5696
+ const trigger = useCallback9(() => {
5643
5697
  if (pressedRef.current) {
5644
5698
  if (timerRef.current) clearTimeout(timerRef.current);
5645
5699
  pressedRef.current = false;
@@ -5654,7 +5708,7 @@ var useDoubleTap = ({ onFirstTap, onSecondTap, windowMs }) => {
5654
5708
  timerRef.current = null;
5655
5709
  }, windowMs);
5656
5710
  }, [onFirstTap, onSecondTap, windowMs]);
5657
- const reset = useCallback8(() => {
5711
+ const reset = useCallback9(() => {
5658
5712
  if (timerRef.current) clearTimeout(timerRef.current);
5659
5713
  pressedRef.current = false;
5660
5714
  timerRef.current = null;
@@ -5687,7 +5741,7 @@ var useExitHandler = ({
5687
5741
  };
5688
5742
 
5689
5743
  // src/platform/tui/hooks/keyboard/useEscHandler.ts
5690
- import { useCallback as useCallback9 } from "react";
5744
+ import { useCallback as useCallback10 } from "react";
5691
5745
  var useEscHandler = ({
5692
5746
  cancelInputRequest,
5693
5747
  abort,
@@ -5710,7 +5764,7 @@ var useEscHandler = ({
5710
5764
  },
5711
5765
  windowMs
5712
5766
  });
5713
- const handleEsc = useCallback9(() => {
5767
+ const handleEsc = useCallback10(() => {
5714
5768
  if (inputRequestRef.current.status === "active") {
5715
5769
  cancelInputRequest();
5716
5770
  return;
@@ -5756,7 +5810,7 @@ var useKeyboardShortcuts = ({
5756
5810
  inputRef,
5757
5811
  windowMs: DOUBLE_TAP_WINDOW
5758
5812
  });
5759
- useInput(useCallback10((ch, key) => {
5813
+ useInput(useCallback11((ch, key) => {
5760
5814
  if (isModalOpenRef.current) return;
5761
5815
  if (key.escape) handleEsc();
5762
5816
  if (key.ctrl && ch === "c") handleCtrlC();
@@ -5774,8 +5828,11 @@ var useKeyboardShortcuts = ({
5774
5828
  };
5775
5829
 
5776
5830
  // src/platform/tui/hooks/useAppLogic.ts
5777
- import { useState as useState7, useCallback as useCallback11, useRef as useRef8 } from "react";
5831
+ import { useState as useState7, useCallback as useCallback13, useRef as useRef9 } from "react";
5778
5832
  import { useApp } from "ink";
5833
+
5834
+ // src/platform/tui/hooks/useAppSubmission.ts
5835
+ import { useCallback as useCallback12 } from "react";
5779
5836
  function sanitizeInput(value) {
5780
5837
  return value.replace(/(?:\x1b)?\[<\d+;\d+;\d+[mM]/g, "").replace(/\x1b\[[0-9;]*[A-Za-z]/g, "").replace(/[\x00-\x08\x0B-\x1F\x7F-\x9F]/g, "").trim();
5781
5838
  }
@@ -5795,6 +5852,80 @@ function parseSlashCommandInput(value) {
5795
5852
  args
5796
5853
  };
5797
5854
  }
5855
+ function prepareSubmittedInput(value, maxChars) {
5856
+ const trimmed = sanitizeInput(value);
5857
+ if (!trimmed) return null;
5858
+ return {
5859
+ safeInput: trimmed.slice(0, maxChars),
5860
+ wasTruncated: trimmed.length > maxChars
5861
+ };
5862
+ }
5863
+ function resolveSubmissionRoute(parsedCommand, inputRequestStatus, isProcessing) {
5864
+ if (parsedCommand) return "command";
5865
+ if (inputRequestStatus === "active") return "active_input_request";
5866
+ return isProcessing ? "queue" : "execute";
5867
+ }
5868
+ function useAppSubmission({
5869
+ addMessage,
5870
+ agent,
5871
+ executeTask,
5872
+ handleCommand,
5873
+ inputRequestRef,
5874
+ isProcessingRef,
5875
+ recallQueuedInput,
5876
+ setInput,
5877
+ setSecretInput,
5878
+ settleActiveInputRequest
5879
+ }) {
5880
+ const handleRecallQueuedInput = useCallback12(() => {
5881
+ return recallQueuedInput();
5882
+ }, [recallQueuedInput]);
5883
+ const handleSecretSubmit = useCallback12((value) => {
5884
+ const ir = inputRequestRef.current;
5885
+ if (ir.status !== "active") return;
5886
+ const sanitized = sanitizeInput(value).slice(0, TUI_DISPLAY_LIMITS.MAX_INPUT_CHARS);
5887
+ const displayText = ir.isPassword ? "\u2022".repeat(Math.min(sanitized.length, TUI_DISPLAY_LIMITS.PASSWORD_MASK_MAX)) : sanitized;
5888
+ addMessage("user", displayText);
5889
+ settleActiveInputRequest(sanitized);
5890
+ setSecretInput("");
5891
+ }, [addMessage, inputRequestRef, setSecretInput, settleActiveInputRequest]);
5892
+ const handleSubmit = useCallback12(async (value) => {
5893
+ const preparedInput = prepareSubmittedInput(value, TUI_DISPLAY_LIMITS.MAX_INPUT_CHARS);
5894
+ if (!preparedInput) return;
5895
+ setInput("");
5896
+ if (preparedInput.wasTruncated) {
5897
+ addMessage("system", `Input truncated to ${TUI_DISPLAY_LIMITS.MAX_INPUT_CHARS} chars for terminal stability.`);
5898
+ }
5899
+ const parsedCommand = parseSlashCommandInput(preparedInput.safeInput);
5900
+ const route = resolveSubmissionRoute(
5901
+ parsedCommand,
5902
+ inputRequestRef.current.status,
5903
+ isProcessingRef.current
5904
+ );
5905
+ if (route === "command" && parsedCommand) {
5906
+ addMessage("command", parsedCommand.normalized);
5907
+ await handleCommand(parsedCommand.cmd, parsedCommand.args);
5908
+ return;
5909
+ }
5910
+ if (route === "active_input_request") {
5911
+ handleSecretSubmit(preparedInput.safeInput);
5912
+ return;
5913
+ }
5914
+ if (route === "queue") {
5915
+ agent.enqueueUserInput(preparedInput.safeInput);
5916
+ return;
5917
+ }
5918
+ addMessage("user", preparedInput.safeInput);
5919
+ await executeTask(preparedInput.safeInput);
5920
+ }, [addMessage, agent, executeTask, handleCommand, handleSecretSubmit, inputRequestRef, isProcessingRef, setInput]);
5921
+ return {
5922
+ handleRecallQueuedInput,
5923
+ handleSecretSubmit,
5924
+ handleSubmit
5925
+ };
5926
+ }
5927
+
5928
+ // src/platform/tui/hooks/useAppLogic.ts
5798
5929
  var useAppLogic = ({ autoApprove = false, target }) => {
5799
5930
  const { exit } = useApp();
5800
5931
  const { columns: terminalWidth, rows: terminalHeight } = useTerminalSize();
@@ -5828,26 +5959,26 @@ var useAppLogic = ({ autoApprove = false, target }) => {
5828
5959
  addMessage,
5829
5960
  refreshStats
5830
5961
  } = useAgent(autoApproveMode, target, isTyping);
5831
- const isProcessingRef = useRef8(isProcessing);
5962
+ const isProcessingRef = useRef9(isProcessing);
5832
5963
  isProcessingRef.current = isProcessing;
5833
- const autoApproveModeRef = useRef8(autoApproveMode);
5964
+ const autoApproveModeRef = useRef9(autoApproveMode);
5834
5965
  autoApproveModeRef.current = autoApproveMode;
5835
- const inputRequestRef = useRef8(inputRequest);
5966
+ const inputRequestRef = useRef9(inputRequest);
5836
5967
  inputRequestRef.current = inputRequest;
5837
- const isModalOpenRef = useRef8(!!modal.type);
5968
+ const isModalOpenRef = useRef9(!!modal.type);
5838
5969
  isModalOpenRef.current = !!modal.type;
5839
- const inputRef = useRef8(input);
5970
+ const inputRef = useRef9(input);
5840
5971
  inputRef.current = input;
5841
- const clearInput = useCallback11(() => {
5972
+ const clearInput = useCallback13(() => {
5842
5973
  setInput("");
5843
5974
  }, []);
5844
- const showModal = useCallback11((type, content) => {
5975
+ const showModal = useCallback13((type, content) => {
5845
5976
  setModal({ type, content, scrollOffset: 0 });
5846
5977
  }, []);
5847
- const closeModal = useCallback11(() => {
5978
+ const closeModal = useCallback13(() => {
5848
5979
  setModal({ type: null, content: "", scrollOffset: 0 });
5849
5980
  }, []);
5850
- const handleModalScroll = useCallback11((delta) => {
5981
+ const handleModalScroll = useCallback13((delta) => {
5851
5982
  setModal((prev) => {
5852
5983
  const lines = prev.content.split("\n");
5853
5984
  const maxHeight = terminalHeight - TUI_DISPLAY_LIMITS.MODAL_CHROME_HEIGHT;
@@ -5856,7 +5987,7 @@ var useAppLogic = ({ autoApprove = false, target }) => {
5856
5987
  return { ...prev, scrollOffset: newOffset };
5857
5988
  });
5858
5989
  }, [terminalHeight]);
5859
- const handleExit = useCallback11(() => {
5990
+ const handleExit = useCallback13(() => {
5860
5991
  cancelAllInputRequests();
5861
5992
  cleanupAllProcesses().catch(() => {
5862
5993
  });
@@ -5884,39 +6015,18 @@ var useAppLogic = ({ autoApprove = false, target }) => {
5884
6015
  isProcessingRef,
5885
6016
  autoApproveModeRef
5886
6017
  });
5887
- const handleRecallQueuedInput = useCallback11(() => {
5888
- return recallQueuedInput();
5889
- }, [recallQueuedInput]);
5890
- const handleSecretSubmit = useCallback11((value) => {
5891
- const ir = inputRequestRef.current;
5892
- if (ir.status !== "active") return;
5893
- const sanitized = sanitizeInput(value).slice(0, TUI_DISPLAY_LIMITS.MAX_INPUT_CHARS);
5894
- const displayText = ir.isPassword ? "\u2022".repeat(Math.min(sanitized.length, TUI_DISPLAY_LIMITS.PASSWORD_MASK_MAX)) : sanitized;
5895
- addMessage("user", displayText);
5896
- settleActiveInputRequest(sanitized);
5897
- setSecretInput("");
5898
- }, [addMessage, settleActiveInputRequest]);
5899
- const handleSubmit = useCallback11(async (value) => {
5900
- const trimmed = sanitizeInput(value);
5901
- if (!trimmed) return;
5902
- setInput("");
5903
- const safeInput = trimmed.slice(0, TUI_DISPLAY_LIMITS.MAX_INPUT_CHARS);
5904
- if (safeInput.length < trimmed.length) {
5905
- addMessage("system", `Input truncated to ${TUI_DISPLAY_LIMITS.MAX_INPUT_CHARS} chars for terminal stability.`);
5906
- }
5907
- const parsedCommand = parseSlashCommandInput(safeInput);
5908
- if (parsedCommand) {
5909
- addMessage("command", parsedCommand.normalized);
5910
- await handleCommand(parsedCommand.cmd, parsedCommand.args);
5911
- } else if (inputRequestRef.current.status === "active") {
5912
- handleSecretSubmit(safeInput);
5913
- } else if (isProcessingRef.current) {
5914
- agent.enqueueUserInput(safeInput);
5915
- } else {
5916
- addMessage("user", safeInput);
5917
- await executeTask(safeInput);
5918
- }
5919
- }, [agent, addMessage, executeTask, handleCommand, handleSecretSubmit]);
6018
+ const { handleRecallQueuedInput, handleSecretSubmit, handleSubmit } = useAppSubmission({
6019
+ addMessage,
6020
+ agent,
6021
+ executeTask,
6022
+ handleCommand,
6023
+ inputRequestRef,
6024
+ isProcessingRef,
6025
+ recallQueuedInput,
6026
+ setInput,
6027
+ setSecretInput,
6028
+ settleActiveInputRequest
6029
+ });
5920
6030
  useKeyboardShortcuts({
5921
6031
  addMessage,
5922
6032
  handleExit,
@@ -6580,10 +6690,10 @@ var MessageList = memo6(({
6580
6690
  import { memo as memo9 } from "react";
6581
6691
 
6582
6692
  // src/platform/tui/hooks/useStatusTimer.ts
6583
- import { useState as useState10, useEffect as useEffect7, useRef as useRef9 } from "react";
6693
+ import { useState as useState10, useEffect as useEffect7, useRef as useRef10 } from "react";
6584
6694
  var useStatusTimer = (currentStatus, isProcessing) => {
6585
6695
  const [statusElapsed, setStatusElapsed] = useState10(0);
6586
- const lastStatusRef = useRef9("");
6696
+ const lastStatusRef = useRef10("");
6587
6697
  useEffect7(() => {
6588
6698
  if (!isProcessing || !currentStatus) {
6589
6699
  lastStatusRef.current = "";
@@ -6838,7 +6948,7 @@ var StatusDisplay = memo9(({
6838
6948
  });
6839
6949
 
6840
6950
  // src/platform/tui/components/ChatInput.tsx
6841
- import { useMemo as useMemo4, useCallback as useCallback12, useRef as useRef11, memo as memo10, useState as useState12 } from "react";
6951
+ import { useMemo as useMemo4, useCallback as useCallback14, useRef as useRef12, memo as memo10, useState as useState12 } from "react";
6842
6952
  import { Box as Box14, Text as Text15 } from "ink";
6843
6953
 
6844
6954
  // src/platform/tui/components/input/AutocompletePreview.tsx
@@ -6881,7 +6991,7 @@ var AutocompletePreview = ({
6881
6991
  import { Box as Box12, Text as Text13 } from "ink";
6882
6992
 
6883
6993
  // src/platform/tui/components/input/SimpleTextInput.tsx
6884
- import { useState as useState11, useEffect as useEffect8, useRef as useRef10, useMemo as useMemo3 } from "react";
6994
+ import { useState as useState11, useEffect as useEffect8, useRef as useRef11, useMemo as useMemo3 } from "react";
6885
6995
  import { Box as Box11, Text as Text12, useInput as useInput2, useStdout as useStdout2 } from "ink";
6886
6996
  import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
6887
6997
  var MOUSE_SEQUENCE_RE = /(?:\x1b)?\[<\d+;\d+;\d+[mM]/g;
@@ -6917,12 +7027,12 @@ var SimpleTextInput = ({
6917
7027
  write?.("\x1B[?25l");
6918
7028
  };
6919
7029
  }, [write]);
6920
- const lastInputRef = useRef10("");
6921
- const lastInputTimeRef = useRef10(0);
6922
- const valueRef = useRef10(value || "");
7030
+ const lastInputRef = useRef11("");
7031
+ const lastInputTimeRef = useRef11(0);
7032
+ const valueRef = useRef11(value || "");
6923
7033
  valueRef.current = value || "";
6924
- const mouseFragmentRef = useRef10("");
6925
- const cursorRef = useRef10(cursor);
7034
+ const mouseFragmentRef = useRef11("");
7035
+ const cursorRef = useRef11(cursor);
6926
7036
  cursorRef.current = cursor;
6927
7037
  useEffect8(() => {
6928
7038
  setCursor((prev) => {
@@ -7115,38 +7225,38 @@ var ChatInput = memo10(({
7115
7225
  const showCommandHelp = isSlashMode && !hasArgs && suggestions.length === 0 && value.length > 1;
7116
7226
  const [selectedIdx, setSelectedIdx] = useState12(0);
7117
7227
  const clampedIdx = Math.min(selectedIdx, Math.max(0, suggestions.length - 1));
7118
- const selectedIdxRef = useRef11(clampedIdx);
7228
+ const selectedIdxRef = useRef12(clampedIdx);
7119
7229
  selectedIdxRef.current = clampedIdx;
7120
- const suggestionsRef = useRef11(suggestions);
7230
+ const suggestionsRef = useRef12(suggestions);
7121
7231
  suggestionsRef.current = suggestions;
7122
- const isSlashModeRef = useRef11(isSlashMode);
7232
+ const isSlashModeRef = useRef12(isSlashMode);
7123
7233
  isSlashModeRef.current = isSlashMode;
7124
- const hasArgsRef = useRef11(hasArgs);
7234
+ const hasArgsRef = useRef12(hasArgs);
7125
7235
  hasArgsRef.current = hasArgs;
7126
- const showPreviewRef = useRef11(showPreview);
7236
+ const showPreviewRef = useRef12(showPreview);
7127
7237
  showPreviewRef.current = showPreview;
7128
- const inputRequestRef = useRef11(inputRequest);
7238
+ const inputRequestRef = useRef12(inputRequest);
7129
7239
  inputRequestRef.current = inputRequest;
7130
- const onChangeRef = useRef11(onChange);
7240
+ const onChangeRef = useRef12(onChange);
7131
7241
  onChangeRef.current = onChange;
7132
- const onRecallQueuedInputRef = useRef11(onRecallQueuedInput);
7242
+ const onRecallQueuedInputRef = useRef12(onRecallQueuedInput);
7133
7243
  onRecallQueuedInputRef.current = onRecallQueuedInput;
7134
- const queuedCountRef = useRef11(queuedCount);
7244
+ const queuedCountRef = useRef12(queuedCount);
7135
7245
  queuedCountRef.current = queuedCount;
7136
- const latestValueRef = useRef11(value);
7246
+ const latestValueRef = useRef12(value);
7137
7247
  latestValueRef.current = value;
7138
- const handleLocalChange = useCallback12((newVal) => {
7248
+ const handleLocalChange = useCallback14((newVal) => {
7139
7249
  latestValueRef.current = newVal;
7140
7250
  onChange(newVal);
7141
7251
  }, [onChange]);
7142
- const latestSecretRef = useRef11(secretInput);
7252
+ const latestSecretRef = useRef12(secretInput);
7143
7253
  latestSecretRef.current = secretInput;
7144
- const handleSecretChange = useCallback12((newVal) => {
7254
+ const handleSecretChange = useCallback14((newVal) => {
7145
7255
  latestSecretRef.current = newVal;
7146
7256
  setSecretInput(newVal);
7147
7257
  }, [setSecretInput]);
7148
7258
  const [inputKey, setInputKey] = useState12(0);
7149
- const completeCommand = useCallback12((idx) => {
7259
+ const completeCommand = useCallback14((idx) => {
7150
7260
  const sug = suggestionsRef.current;
7151
7261
  if (!sug.length) return;
7152
7262
  const best = sug[Math.min(idx, sug.length - 1)];
@@ -7156,9 +7266,9 @@ var ChatInput = memo10(({
7156
7266
  setSelectedIdx(0);
7157
7267
  setInputKey((k) => k + 1);
7158
7268
  }, []);
7159
- const onSubmitRef = useRef11(onSubmit);
7269
+ const onSubmitRef = useRef12(onSubmit);
7160
7270
  onSubmitRef.current = onSubmit;
7161
- const wrappedOnSubmit = useCallback12((_staleVal) => {
7271
+ const wrappedOnSubmit = useCallback14((_staleVal) => {
7162
7272
  const finalValue = latestValueRef.current;
7163
7273
  if (showPreviewRef.current) {
7164
7274
  const sug = suggestionsRef.current;
@@ -7178,12 +7288,12 @@ var ChatInput = memo10(({
7178
7288
  }
7179
7289
  onSubmitRef.current(finalValue);
7180
7290
  }, [completeCommand]);
7181
- const onSecretSubmitRef = useRef11(onSecretSubmit);
7291
+ const onSecretSubmitRef = useRef12(onSecretSubmit);
7182
7292
  onSecretSubmitRef.current = onSecretSubmit;
7183
- const wrappedSecretSubmit = useCallback12((_staleVal) => {
7293
+ const wrappedSecretSubmit = useCallback14((_staleVal) => {
7184
7294
  onSecretSubmitRef.current(latestSecretRef.current);
7185
7295
  }, []);
7186
- const handleSpecialKey = useCallback12((key) => {
7296
+ const handleSpecialKey = useCallback14((key) => {
7187
7297
  if (inputRequestRef.current.status === "active") return false;
7188
7298
  const sug = suggestionsRef.current;
7189
7299
  const visible = showPreviewRef.current;
@@ -7333,7 +7443,7 @@ var Footer = memo11(({
7333
7443
  var footer_default = Footer;
7334
7444
 
7335
7445
  // src/platform/tui/components/Modal.tsx
7336
- import { useMemo as useMemo5, memo as memo12, useCallback as useCallback13, useRef as useRef12 } from "react";
7446
+ import { useMemo as useMemo5, memo as memo12, useCallback as useCallback15, useRef as useRef13 } from "react";
7337
7447
  import { Box as Box16, Text as Text17, useInput as useInput3 } from "ink";
7338
7448
  import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
7339
7449
  var MODAL_TITLES = {
@@ -7348,9 +7458,9 @@ var Modal = memo12(({
7348
7458
  onScroll,
7349
7459
  onClose
7350
7460
  }) => {
7351
- const onScrollRef = useRef12(onScroll);
7461
+ const onScrollRef = useRef13(onScroll);
7352
7462
  onScrollRef.current = onScroll;
7353
- const onCloseRef = useRef12(onClose);
7463
+ const onCloseRef = useRef13(onClose);
7354
7464
  onCloseRef.current = onClose;
7355
7465
  const { columns, rows } = useTerminalSize();
7356
7466
  const terminalHeight = rows;
@@ -7362,7 +7472,7 @@ var Modal = memo12(({
7362
7472
  () => lines.slice(scrollOffset, scrollOffset + maxHeight),
7363
7473
  [lines, scrollOffset, maxHeight]
7364
7474
  );
7365
- useInput3(useCallback13((input, key) => {
7475
+ useInput3(useCallback15((input, key) => {
7366
7476
  if (key.escape || input === "q") {
7367
7477
  onCloseRef.current();
7368
7478
  } else if (key.upArrow || input === "k") {
@@ -8465,57 +8575,6 @@ async function scanAction(target, options) {
8465
8575
  }
8466
8576
  }
8467
8577
 
8468
- // src/platform/tui/cli/commands/help.ts
8469
- import chalk4 from "chalk";
8470
- function helpExtendedAction() {
8471
- console.log(`
8472
- ${chalk4.hex(HEX.primary)(APP_NAME + " - Autonomous Penetration Testing AI")}
8473
-
8474
- ${chalk4.hex(HEX.yellow)("Usage:")}
8475
-
8476
- ${chalk4.hex(HEX.gray)("$ pentesting")} Start interactive mode
8477
- ${chalk4.hex(HEX.gray)("$ pentesting -t 192.168.1.1")} Start with target
8478
- ${chalk4.hex(HEX.gray)("$ pentesting --dangerously-skip-permissions")} Enable tool auto-approve in strict mode
8479
-
8480
- ${chalk4.hex(HEX.yellow)("Commands:")}
8481
-
8482
- ${chalk4.hex(HEX.primary)("pentesting")} Interactive TUI mode
8483
- ${chalk4.hex(HEX.primary)("pentesting run <objective>")} Run single objective
8484
- ${chalk4.hex(HEX.primary)("pentesting scan <target>")} Quick scan target
8485
-
8486
- ${chalk4.hex(HEX.yellow)("Options:")}
8487
-
8488
- ${chalk4.hex(HEX.primary)("--dangerously-skip-permissions")} Bypass strict approval mode by auto-approving tools
8489
- ${chalk4.hex(HEX.primary)("-t, --target <ip>")} Set target
8490
- ${chalk4.hex(HEX.primary)("-o, --output <file>")} Save results to file
8491
-
8492
- ${chalk4.hex(HEX.yellow)("Interactive Commands:")}
8493
-
8494
- ${chalk4.hex(HEX.primary)("/target <ip>")} Set target
8495
- ${chalk4.hex(HEX.primary)("/start")} Start autonomous mode
8496
- ${chalk4.hex(HEX.primary)("/hint <text>")} Provide hint
8497
- ${chalk4.hex(HEX.primary)("/findings")} Show findings
8498
- ${chalk4.hex(HEX.primary)("/clear")} Reset session
8499
-
8500
- ${chalk4.hex(HEX.yellow)("Examples:")}
8501
-
8502
- ${chalk4.hex(HEX.gray)("# Full autonomous mode")}
8503
- $ pentesting --dangerously-skip-permissions -t 10.10.10.5
8504
-
8505
- ${chalk4.hex(HEX.gray)("# Run specific objective")}
8506
- $ pentesting run "Find SQL injection" -t http://target.com -o report.json
8507
-
8508
- ${chalk4.hex(HEX.gray)("# Quick vulnerability scan")}
8509
- $ pentesting scan 192.168.1.1 -s vuln
8510
-
8511
- ${chalk4.hex(HEX.yellow)("Environment:")}
8512
-
8513
- ${chalk4.hex(HEX.primary)("PENTEST_API_KEY")} Required - LLM API key
8514
- ${chalk4.hex(HEX.primary)("PENTEST_BASE_URL")} Optional - AI API base URL
8515
- ${chalk4.hex(HEX.primary)("PENTEST_MODEL")} Optional - Model override
8516
- `);
8517
- }
8518
-
8519
8578
  // src/platform/tui/cli/args.ts
8520
8579
  import { InvalidArgumentError } from "commander";
8521
8580
  function parsePositiveInt(value) {
@@ -8552,9 +8611,6 @@ function createProgram() {
8552
8611
  dangerouslySkipPermissions: opts.dangerouslySkipPermissions
8553
8612
  });
8554
8613
  });
8555
- program2.command("help-extended").description("Show extended help with examples").action(() => {
8556
- helpExtendedAction();
8557
- });
8558
8614
  return program2;
8559
8615
  }
8560
8616
 
@@ -8565,7 +8621,7 @@ if (process.env.PENTEST_TOR === "true" && isContainerizedRuntime()) {
8565
8621
  }
8566
8622
  var _configErrors = validateRequiredConfig();
8567
8623
  if (_configErrors.length > 0) {
8568
- _configErrors.forEach((e) => console.error(chalk5.hex(HEX.red)(e)));
8624
+ _configErrors.forEach((e) => console.error(chalk4.hex(HEX.red)(e)));
8569
8625
  process.exit(EXIT_CODES.CONFIG_ERROR);
8570
8626
  }
8571
8627
  var program = createProgram();