pentesting 0.56.0 → 0.56.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 (2) hide show
  1. package/dist/main.js +57 -39
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -711,7 +711,7 @@ var INPUT_PROMPT_PATTERNS = [
711
711
 
712
712
  // src/shared/constants/agent.ts
713
713
  var APP_NAME = "Pentest AI";
714
- var APP_VERSION = "0.56.0";
714
+ var APP_VERSION = "0.56.2";
715
715
  var APP_DESCRIPTION = "Autonomous Penetration Testing AI Agent";
716
716
  var LLM_ROLES = {
717
717
  SYSTEM: "system",
@@ -768,7 +768,7 @@ import gradient from "gradient-string";
768
768
 
769
769
  // src/platform/tui/app.tsx
770
770
  import { useState as useState8, useCallback as useCallback11, useRef as useRef10 } from "react";
771
- import { Box as Box18, useApp, useStdout as useStdout2 } from "ink";
771
+ import { Box as Box18, useApp, useStdout as useStdout4 } from "ink";
772
772
 
773
773
  // src/platform/tui/hooks/useAgent.ts
774
774
  import { useState as useState2, useEffect as useEffect2, useCallback as useCallback2, useRef as useRef3 } from "react";
@@ -14911,7 +14911,10 @@ var formatFlags = (flags) => {
14911
14911
  if (!flags.length) return "";
14912
14912
  const lines = [];
14913
14913
  const total = flags.length;
14914
- lines.push(`\u2500\u2500\u2500 Captured (${total}) \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`);
14914
+ const label = `\u2500\u2500\u2500 Captured (${total}) `;
14915
+ const cols = process.stdout?.columns ?? 80;
14916
+ const fillWidth = Math.max(3, cols - 2 - label.length);
14917
+ lines.push(`${label}${"\u2500".repeat(fillWidth)}`);
14915
14918
  lines.push("");
14916
14919
  flags.forEach((flag, i) => {
14917
14920
  lines.push(` ${(i + 1).toString().padStart(2, " ")}. ${flag}`);
@@ -14920,6 +14923,12 @@ var formatFlags = (flags) => {
14920
14923
  };
14921
14924
 
14922
14925
  // src/platform/tui/hooks/commands/formatters/graph-summary.ts
14926
+ var getBoxWidth = () => Math.max(30, (process.stdout?.columns ?? 80) - 2);
14927
+ var boxLine = (content, width) => {
14928
+ const inner = width - 2;
14929
+ const truncated = content.length > inner ? content.slice(0, inner - 1) + "\u2026" : content;
14930
+ return `\u2502 ${truncated.padEnd(inner - 1)}`;
14931
+ };
14923
14932
  var formatFindingsWithFlags = (findings, flags) => {
14924
14933
  const findingsOutput = formatFindings(findings);
14925
14934
  const flagsOutput = formatFlags(flags);
@@ -14931,38 +14940,40 @@ ${flagsOutput}`;
14931
14940
  };
14932
14941
  var formatGraphWithSummary = (_graphASCII, findings, flags) => {
14933
14942
  const lines = [];
14934
- lines.push("\u250C\u2500\u2500\u2500 Attack Graph \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\u2510");
14935
- lines.push(`\u2502 \u{1F5A5} 1 \u26A0 ${findings.length} \u2699 1`);
14936
- lines.push("\u2502");
14937
- lines.push("\u2502 \u{1F5A5} HOST (1)");
14938
- lines.push(`\u2502 \u25CB 138.2.89.94 \u2192 138.2.89.94:443`);
14939
- lines.push("\u2502");
14940
- lines.push(`\u2502 \u26A0 VULNERABILITY (${findings.length})`);
14943
+ const w = getBoxWidth();
14944
+ const innerDash = w - 2;
14945
+ lines.push(`\u250C${"\u2500".repeat(innerDash)}\u2510`);
14946
+ lines.push(boxLine(`\u{1F5A5} 1 \u26A0 ${findings.length} \u2699 1`, w));
14947
+ lines.push(boxLine("", w));
14948
+ lines.push(boxLine("\u{1F5A5} HOST (1)", w));
14949
+ lines.push(boxLine(` \u25CB 138.2.89.94 \u2192 138.2.89.94:443`, w));
14950
+ lines.push(boxLine("", w));
14951
+ lines.push(boxLine(`\u26A0 VULNERABILITY (${findings.length})`, w));
14941
14952
  const sortedFindings = [...findings].sort((a, b) => b.confidence - a.confidence).slice(0, 5);
14942
14953
  for (const f of sortedFindings) {
14943
14954
  const icon = confIcon(f.confidence);
14944
14955
  const cat = f.category ? ` \u2502 ${f.category}` : "";
14945
- lines.push(`\u2502 \u25CB ${icon} ${f.title.slice(0, 60)}${f.title.length > 60 ? "..." : ""}`);
14946
- lines.push(`\u2502 ${confLabel(f.confidence).toUpperCase()} \u2502 ${f.severity.toUpperCase()}${cat}`);
14956
+ lines.push(boxLine(` \u25CB ${icon} ${f.title.slice(0, 60)}${f.title.length > 60 ? "..." : ""}`, w));
14957
+ lines.push(boxLine(` ${confLabel(f.confidence).toUpperCase()} \u2502 ${f.severity.toUpperCase()}${cat}`, w));
14947
14958
  }
14948
14959
  if (findings.length > 5) {
14949
- lines.push(`\u2502 ... and ${findings.length - 5} more findings`);
14960
+ lines.push(boxLine(` ... and ${findings.length - 5} more findings`, w));
14950
14961
  }
14951
14962
  const cveFindings = findings.filter((f) => f.title.includes("CVE"));
14952
14963
  if (cveFindings.length > 0) {
14953
- lines.push(`\u2502 \u25CB CVE search: https nginx/1.24.0 (Ubuntu) -> Apache CouchDB 3.5.1`);
14964
+ lines.push(boxLine(` \u25CB CVE search: https nginx/1.24.0 (Ubuntu) -> Apache CouchDB 3.5.1`, w));
14954
14965
  }
14955
- lines.push("\u2502");
14956
- lines.push("\u2502 \u2699 SERVICE (1)");
14957
- lines.push(`\u2502 \u25CB 138.2.89.94:443 (nginx/1.24.0 (Ubuntu) -> Apache CouchDB 3.5.1) \u2192 CVE search: https nginx/1.24.0 (Ubuntu) -> Apache CouchDB 3.5.1`);
14966
+ lines.push(boxLine("", w));
14967
+ lines.push(boxLine("\u2699 SERVICE (1)", w));
14968
+ lines.push(boxLine(` \u25CB 138.2.89.94:443 (nginx/1.24.0 (Ubuntu) -> Apache CouchDB 3.5.1)`, w));
14958
14969
  if (flags.length > 0) {
14959
- lines.push("\u2502");
14960
- lines.push(`\u2502 \u{1F3F4} Captured: ${flags.length}`);
14970
+ lines.push(boxLine("", w));
14971
+ lines.push(boxLine(`\u{1F3F4} Captured: ${flags.length}`, w));
14961
14972
  }
14962
- lines.push("\u2502");
14963
- lines.push("\u251C\u2500\u2500\u2500 Summary \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\u2524");
14964
- lines.push(`\u2502 Nodes: ${findings.length + 2} | Edges: 2 | Succeeded: 0 | Failed: 0 | Chains: 0`);
14965
- lines.push("\u2514\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\u2518");
14973
+ lines.push(boxLine("", w));
14974
+ lines.push(`\u251C${"\u2500".repeat(innerDash)}\u2524`);
14975
+ lines.push(boxLine(`Nodes: ${findings.length + 2} | Edges: 2 | Succeeded: 0 | Failed: 0 | Chains: 0`, w));
14976
+ lines.push(`\u2514${"\u2500".repeat(innerDash)}\u2518`);
14966
14977
  return lines.join("\n");
14967
14978
  };
14968
14979
 
@@ -16160,17 +16171,21 @@ var AutocompletePreview = ({
16160
16171
  };
16161
16172
 
16162
16173
  // src/platform/tui/components/input/SecretInputArea.tsx
16163
- import { Box as Box12, Text as Text14 } from "ink";
16174
+ import { Box as Box12, Text as Text14, useStdout } from "ink";
16164
16175
  import TextInput from "ink-text-input";
16165
16176
  import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
16177
+ var OUTER_PADDING = 2;
16166
16178
  var SecretInputArea = ({
16167
16179
  inputRequest,
16168
16180
  secretInput,
16169
16181
  setSecretInput,
16170
16182
  onSecretSubmit
16171
16183
  }) => {
16184
+ const { stdout } = useStdout();
16185
+ const borderWidth = Math.max(10, (stdout?.columns ?? 80) - OUTER_PADDING);
16186
+ const borderLine = "\u2501".repeat(borderWidth);
16172
16187
  return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", children: [
16173
- /* @__PURE__ */ jsx14(Box12, { children: /* @__PURE__ */ jsx14(Text14, { color: THEME.yellow, children: "\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501" }) }),
16188
+ /* @__PURE__ */ jsx14(Box12, { children: /* @__PURE__ */ jsx14(Text14, { color: THEME.yellow, children: borderLine }) }),
16174
16189
  /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", paddingX: 1, children: [
16175
16190
  /* @__PURE__ */ jsxs12(Box12, { children: [
16176
16191
  /* @__PURE__ */ jsx14(Text14, { color: THEME.yellow, bold: true, children: "\u{1F512} " }),
@@ -16190,14 +16205,15 @@ var SecretInputArea = ({
16190
16205
  )
16191
16206
  ] })
16192
16207
  ] }),
16193
- /* @__PURE__ */ jsx14(Box12, { children: /* @__PURE__ */ jsx14(Text14, { color: THEME.yellow, children: "\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501" }) })
16208
+ /* @__PURE__ */ jsx14(Box12, { children: /* @__PURE__ */ jsx14(Text14, { color: THEME.yellow, children: borderLine }) })
16194
16209
  ] });
16195
16210
  };
16196
16211
 
16197
16212
  // src/platform/tui/components/input/NormalInputArea.tsx
16198
- import { Box as Box13, Text as Text15 } from "ink";
16213
+ import { Box as Box13, Text as Text15, useStdout as useStdout2 } from "ink";
16199
16214
  import TextInput2 from "ink-text-input";
16200
16215
  import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
16216
+ var OUTER_PADDING2 = 2;
16201
16217
  var NormalInputArea = ({
16202
16218
  inputKey,
16203
16219
  value,
@@ -16205,8 +16221,11 @@ var NormalInputArea = ({
16205
16221
  onSubmit,
16206
16222
  placeholder
16207
16223
  }) => {
16224
+ const { stdout } = useStdout2();
16225
+ const borderWidth = Math.max(10, (stdout?.columns ?? 80) - OUTER_PADDING2);
16226
+ const borderLine = "\u2500".repeat(borderWidth);
16208
16227
  return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", children: [
16209
- /* @__PURE__ */ jsx15(Box13, { children: /* @__PURE__ */ jsx15(Text15, { dimColor: true, color: THEME.dimGray, children: "\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\u2500\u2500\u2500\u2500\u2500" }) }),
16228
+ /* @__PURE__ */ jsx15(Box13, { children: /* @__PURE__ */ jsx15(Text15, { dimColor: true, color: THEME.dimGray, children: borderLine }) }),
16210
16229
  /* @__PURE__ */ jsxs13(Box13, { paddingX: 1, children: [
16211
16230
  /* @__PURE__ */ jsx15(Text15, { color: THEME.primary, children: "\u276F " }),
16212
16231
  /* @__PURE__ */ jsx15(
@@ -16220,7 +16239,7 @@ var NormalInputArea = ({
16220
16239
  inputKey
16221
16240
  )
16222
16241
  ] }),
16223
- /* @__PURE__ */ jsx15(Box13, { children: /* @__PURE__ */ jsx15(Text15, { dimColor: true, color: THEME.dimGray, children: "\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\u2500\u2500\u2500\u2500\u2500" }) })
16242
+ /* @__PURE__ */ jsx15(Box13, { children: /* @__PURE__ */ jsx15(Text15, { dimColor: true, color: THEME.dimGray, children: borderLine }) })
16224
16243
  ] });
16225
16244
  };
16226
16245
 
@@ -16361,6 +16380,7 @@ var Footer = memo11(({ phase, targets, findings, todo, elapsedTime, isProcessing
16361
16380
  return /* @__PURE__ */ jsxs15(
16362
16381
  Box15,
16363
16382
  {
16383
+ width: "100%",
16364
16384
  paddingX: 1,
16365
16385
  justifyContent: "space-between",
16366
16386
  overflow: "hidden",
@@ -16412,7 +16432,7 @@ var footer_default = Footer;
16412
16432
 
16413
16433
  // src/platform/tui/components/Modal.tsx
16414
16434
  import { useMemo as useMemo2, memo as memo12, useCallback as useCallback10, useRef as useRef9 } from "react";
16415
- import { Box as Box16, Text as Text18, useStdout, useInput as useInput4 } from "ink";
16435
+ import { Box as Box16, Text as Text18, useStdout as useStdout3, useInput as useInput4 } from "ink";
16416
16436
  import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
16417
16437
  var MODAL_TITLES = {
16418
16438
  findings: "\u25C8 FINDINGS \u25C8",
@@ -16430,7 +16450,7 @@ var Modal = memo12(({
16430
16450
  onScrollRef.current = onScroll;
16431
16451
  const onCloseRef = useRef9(onClose);
16432
16452
  onCloseRef.current = onClose;
16433
- const { stdout } = useStdout();
16453
+ const { stdout } = useStdout3();
16434
16454
  const terminalHeight = stdout?.rows ?? 24;
16435
16455
  const terminalWidth = (stdout?.columns ?? 80) - 4;
16436
16456
  const maxHeight = Math.max(1, terminalHeight - 6);
@@ -16464,13 +16484,11 @@ var Modal = memo12(({
16464
16484
  width: terminalWidth,
16465
16485
  height: terminalHeight,
16466
16486
  children: [
16467
- /* @__PURE__ */ jsx18(Box16, { justifyContent: "center", marginBottom: 0, children: /* @__PURE__ */ jsxs16(Text18, { color: THEME.cyan, bold: true, children: [
16468
- "\u2500".repeat(10),
16469
- " ",
16470
- MODAL_TITLES[type],
16471
- " ",
16472
- "\u2500".repeat(10)
16473
- ] }) }),
16487
+ /* @__PURE__ */ jsx18(Box16, { justifyContent: "center", marginBottom: 0, children: /* @__PURE__ */ jsx18(Text18, { color: THEME.cyan, bold: true, children: (() => {
16488
+ const title = MODAL_TITLES[type];
16489
+ const sideWidth = Math.max(3, Math.floor((terminalWidth - title.length - 2) / 2));
16490
+ return `${"\u2500".repeat(sideWidth)} ${title} ${"\u2500".repeat(sideWidth)}`;
16491
+ })() }) }),
16474
16492
  /* @__PURE__ */ jsx18(
16475
16493
  Box16,
16476
16494
  {
@@ -16575,7 +16593,7 @@ import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
16575
16593
  var MODEL_NAME = getModel() || DEFAULT_MODEL;
16576
16594
  var App = ({ autoApprove = false, target }) => {
16577
16595
  const { exit } = useApp();
16578
- const { stdout } = useStdout2();
16596
+ const { stdout } = useStdout4();
16579
16597
  const terminalWidth = stdout?.columns ?? 80;
16580
16598
  const [input, setInput] = useState8("");
16581
16599
  const [secretInput, setSecretInput] = useState8("");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pentesting",
3
- "version": "0.56.0",
3
+ "version": "0.56.2",
4
4
  "description": "Autonomous Penetration Testing AI Agent",
5
5
  "type": "module",
6
6
  "main": "dist/main.js",