pentesting 0.3.1 → 0.3.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/index.js +719 -38
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,4 +1,10 @@
1
1
  #!/usr/bin/env node
2
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
3
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
4
+ }) : x)(function(x) {
5
+ if (typeof require !== "undefined") return require.apply(this, arguments);
6
+ throw Error('Dynamic require of "' + x + '" is not supported');
7
+ });
2
8
 
3
9
  // src/index.tsx
4
10
  import { render } from "ink";
@@ -6,7 +12,7 @@ import { Command } from "commander";
6
12
 
7
13
  // src/cli/app.tsx
8
14
  import { useState, useEffect, useCallback, useRef } from "react";
9
- import { Box, Text, useInput, useApp, Static } from "ink";
15
+ import { Box as Box2, Text as Text2, useInput, useApp, Static } from "ink";
10
16
  import TextInput from "ink-text-input";
11
17
  import Spinner from "ink-spinner";
12
18
 
@@ -1194,7 +1200,7 @@ async function executeMetasploit(input) {
1194
1200
  return executeBash(`msfconsole -q -x "${command}; exit"`, { timeout: 3e5 });
1195
1201
  }
1196
1202
  async function generatePayload(input) {
1197
- const { payload_type, lhost, lport, platform, format, encoder, output } = input;
1203
+ const { payload_type, lhost, lport, platform: platform2, format, encoder, output } = input;
1198
1204
  const payloads = {
1199
1205
  windows: {
1200
1206
  reverse_tcp: "windows/meterpreter/reverse_tcp",
@@ -1213,7 +1219,7 @@ async function generatePayload(input) {
1213
1219
  reverse_tcp: "python/meterpreter/reverse_tcp"
1214
1220
  }
1215
1221
  };
1216
- const payloadName = payloads[platform]?.[payload_type] || `${platform}/meterpreter/reverse_tcp`;
1222
+ const payloadName = payloads[platform2]?.[payload_type] || `${platform2}/meterpreter/reverse_tcp`;
1217
1223
  let cmd = `msfvenom -p ${payloadName} LHOST=${lhost} LPORT=${lport}`;
1218
1224
  if (format) cmd += ` -f ${format}`;
1219
1225
  if (encoder) cmd += ` -e ${encoder}`;
@@ -1376,7 +1382,7 @@ const { chromium } = require('playwright');
1376
1382
  }
1377
1383
 
1378
1384
  // src/config/constants.ts
1379
- var APP_VERSION = "0.3.1";
1385
+ var APP_VERSION = "0.3.2";
1380
1386
  var APP_DESCRIPTION = "Autonomous Penetration Testing AI Agent";
1381
1387
  var LLM_API_KEY = process.env.PENTEST_API_KEY || process.env.ANTHROPIC_API_KEY || "";
1382
1388
  var LLM_BASE_URL = process.env.PENTEST_BASE_URL || void 0;
@@ -4327,6 +4333,499 @@ function getSlashCommandRegistry() {
4327
4333
  return registry;
4328
4334
  }
4329
4335
 
4336
+ // src/core/context/context-manager.ts
4337
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, renameSync } from "fs";
4338
+ import { join as join3, dirname as dirname2 } from "path";
4339
+ import { EventEmitter as EventEmitter6 } from "events";
4340
+ var CONTEXT_EVENT = {
4341
+ MESSAGE_ADDED: "message_added",
4342
+ CHECKPOINT_CREATED: "checkpoint_created",
4343
+ REVERTED: "reverted",
4344
+ CLEARED: "cleared",
4345
+ COMPACTED: "compacted"
4346
+ };
4347
+ var ContextManager2 = class extends EventEmitter6 {
4348
+ filePath;
4349
+ state;
4350
+ maxMessages;
4351
+ constructor(sessionDir, options) {
4352
+ super();
4353
+ this.filePath = join3(sessionDir, "context.jsonl");
4354
+ this.maxMessages = options?.maxMessages || 100;
4355
+ this.state = {
4356
+ messages: [],
4357
+ checkpoints: [],
4358
+ tokenCount: 0,
4359
+ nextCheckpointId: 0
4360
+ };
4361
+ const dir = dirname2(this.filePath);
4362
+ if (!existsSync(dir)) {
4363
+ mkdirSync(dir, { recursive: true });
4364
+ }
4365
+ }
4366
+ /**
4367
+ * Restore context from file
4368
+ */
4369
+ async restore() {
4370
+ if (!existsSync(this.filePath)) {
4371
+ return false;
4372
+ }
4373
+ try {
4374
+ const content = readFileSync(this.filePath, "utf-8");
4375
+ const lines = content.trim().split("\n").filter((l) => l);
4376
+ for (const line of lines) {
4377
+ const data = JSON.parse(line);
4378
+ if (data.role === "_checkpoint") {
4379
+ this.state.checkpoints.push({
4380
+ id: data.id,
4381
+ timestamp: data.timestamp,
4382
+ messageCount: data.messageCount,
4383
+ description: data.description
4384
+ });
4385
+ this.state.nextCheckpointId = Math.max(this.state.nextCheckpointId, data.id + 1);
4386
+ } else if (data.role === "_usage") {
4387
+ this.state.tokenCount = data.tokenCount;
4388
+ } else {
4389
+ this.state.messages.push(data);
4390
+ }
4391
+ }
4392
+ return this.state.messages.length > 0;
4393
+ } catch (error) {
4394
+ console.error("Failed to restore context:", error);
4395
+ return false;
4396
+ }
4397
+ }
4398
+ /**
4399
+ * Get conversation history
4400
+ */
4401
+ getHistory() {
4402
+ return [...this.state.messages];
4403
+ }
4404
+ /**
4405
+ * Get checkpoints
4406
+ */
4407
+ getCheckpoints() {
4408
+ return [...this.state.checkpoints];
4409
+ }
4410
+ /**
4411
+ * Add a message to context
4412
+ */
4413
+ async addMessage(message) {
4414
+ const msg = {
4415
+ ...message,
4416
+ timestamp: Date.now()
4417
+ };
4418
+ this.state.messages.push(msg);
4419
+ await this.appendToFile(msg);
4420
+ this.emit(CONTEXT_EVENT.MESSAGE_ADDED, msg);
4421
+ }
4422
+ /**
4423
+ * Create a checkpoint
4424
+ */
4425
+ async checkpoint(description) {
4426
+ const checkpoint = {
4427
+ id: this.state.nextCheckpointId++,
4428
+ timestamp: Date.now(),
4429
+ messageCount: this.state.messages.length,
4430
+ description
4431
+ };
4432
+ this.state.checkpoints.push(checkpoint);
4433
+ await this.appendToFile({
4434
+ role: "_checkpoint",
4435
+ ...checkpoint
4436
+ });
4437
+ this.emit(CONTEXT_EVENT.CHECKPOINT_CREATED, checkpoint);
4438
+ return checkpoint;
4439
+ }
4440
+ /**
4441
+ * Revert to a specific checkpoint
4442
+ */
4443
+ async revertTo(checkpointId) {
4444
+ const checkpoint = this.state.checkpoints.find((c) => c.id === checkpointId);
4445
+ if (!checkpoint) {
4446
+ return false;
4447
+ }
4448
+ const backupPath = `${this.filePath}.bak`;
4449
+ if (existsSync(this.filePath)) {
4450
+ renameSync(this.filePath, backupPath);
4451
+ }
4452
+ this.state.messages = this.state.messages.slice(0, checkpoint.messageCount);
4453
+ this.state.checkpoints = this.state.checkpoints.filter((c) => c.id < checkpointId);
4454
+ await this.rewriteFile();
4455
+ this.emit(CONTEXT_EVENT.REVERTED, checkpointId);
4456
+ return true;
4457
+ }
4458
+ /**
4459
+ * Undo last checkpoint (go back one step)
4460
+ */
4461
+ async undo() {
4462
+ if (this.state.checkpoints.length === 0) {
4463
+ return false;
4464
+ }
4465
+ const lastCheckpoint = this.state.checkpoints[this.state.checkpoints.length - 1];
4466
+ return this.revertTo(lastCheckpoint.id);
4467
+ }
4468
+ /**
4469
+ * Clear all context
4470
+ */
4471
+ async clear() {
4472
+ const backupPath = `${this.filePath}.${Date.now()}.bak`;
4473
+ if (existsSync(this.filePath)) {
4474
+ renameSync(this.filePath, backupPath);
4475
+ }
4476
+ this.state = {
4477
+ messages: [],
4478
+ checkpoints: [],
4479
+ tokenCount: 0,
4480
+ nextCheckpointId: 0
4481
+ };
4482
+ this.emit(CONTEXT_EVENT.CLEARED);
4483
+ }
4484
+ /**
4485
+ * Update token count
4486
+ */
4487
+ async updateTokenCount(count) {
4488
+ this.state.tokenCount = count;
4489
+ await this.appendToFile({ role: "_usage", tokenCount: count });
4490
+ }
4491
+ /**
4492
+ * Get token count
4493
+ */
4494
+ getTokenCount() {
4495
+ return this.state.tokenCount;
4496
+ }
4497
+ /**
4498
+ * Check if context needs compaction
4499
+ */
4500
+ needsCompaction(maxTokens, reservedTokens = 5e4) {
4501
+ return this.state.tokenCount + reservedTokens >= maxTokens;
4502
+ }
4503
+ /**
4504
+ * Compact context (keep last N messages, summarize rest)
4505
+ */
4506
+ async compact(summary, keepLast = 2) {
4507
+ if (this.state.messages.length <= keepLast) {
4508
+ return;
4509
+ }
4510
+ const preserved = this.state.messages.slice(-keepLast);
4511
+ const summaryMessage = {
4512
+ role: "system",
4513
+ content: `[Context Compacted]
4514
+
4515
+ Previous conversation summary:
4516
+ ${summary}`,
4517
+ timestamp: Date.now(),
4518
+ metadata: { compacted: true }
4519
+ };
4520
+ const backupPath = `${this.filePath}.compact.bak`;
4521
+ if (existsSync(this.filePath)) {
4522
+ renameSync(this.filePath, backupPath);
4523
+ }
4524
+ this.state.messages = [summaryMessage, ...preserved];
4525
+ this.state.checkpoints = [];
4526
+ this.state.nextCheckpointId = 0;
4527
+ await this.rewriteFile();
4528
+ this.emit(CONTEXT_EVENT.COMPACTED, { summary, preserved: preserved.length });
4529
+ }
4530
+ async appendToFile(data) {
4531
+ const line = JSON.stringify(data) + "\n";
4532
+ const { appendFileSync: appendFileSync2 } = await import("fs");
4533
+ appendFileSync2(this.filePath, line, "utf-8");
4534
+ }
4535
+ async rewriteFile() {
4536
+ let content = "";
4537
+ for (const msg of this.state.messages) {
4538
+ content += JSON.stringify(msg) + "\n";
4539
+ }
4540
+ for (const cp of this.state.checkpoints) {
4541
+ content += JSON.stringify({ role: "_checkpoint", ...cp }) + "\n";
4542
+ }
4543
+ if (this.state.tokenCount > 0) {
4544
+ content += JSON.stringify({ role: "_usage", tokenCount: this.state.tokenCount }) + "\n";
4545
+ }
4546
+ writeFileSync(this.filePath, content, "utf-8");
4547
+ }
4548
+ };
4549
+
4550
+ // src/wire/wire-logger.ts
4551
+ import { existsSync as existsSync2, appendFileSync, readFileSync as readFileSync2, mkdirSync as mkdirSync2 } from "fs";
4552
+ import { join as join4, dirname as dirname3 } from "path";
4553
+ var WireFile = class {
4554
+ filePath;
4555
+ sequence = 0;
4556
+ constructor(sessionDir) {
4557
+ this.filePath = join4(sessionDir, "wire.jsonl");
4558
+ const dir = dirname3(this.filePath);
4559
+ if (!existsSync2(dir)) {
4560
+ mkdirSync2(dir, { recursive: true });
4561
+ }
4562
+ if (existsSync2(this.filePath)) {
4563
+ try {
4564
+ const content = readFileSync2(this.filePath, "utf-8");
4565
+ this.sequence = content.trim().split("\n").filter((l) => l).length;
4566
+ } catch {
4567
+ this.sequence = 0;
4568
+ }
4569
+ }
4570
+ }
4571
+ /**
4572
+ * Write a message to the wire log
4573
+ */
4574
+ write(message) {
4575
+ const record = {
4576
+ sequence: this.sequence++,
4577
+ message: {
4578
+ ...message,
4579
+ timestamp: Date.now()
4580
+ }
4581
+ };
4582
+ const line = JSON.stringify(record) + "\n";
4583
+ appendFileSync(this.filePath, line, "utf-8");
4584
+ return record;
4585
+ }
4586
+ /**
4587
+ * Read all records from the wire log
4588
+ */
4589
+ async *readRecords() {
4590
+ if (!existsSync2(this.filePath)) {
4591
+ return;
4592
+ }
4593
+ const content = readFileSync2(this.filePath, "utf-8");
4594
+ const lines = content.trim().split("\n").filter((l) => l);
4595
+ for (const line of lines) {
4596
+ try {
4597
+ yield JSON.parse(line);
4598
+ } catch {
4599
+ }
4600
+ }
4601
+ }
4602
+ /**
4603
+ * Check if wire file is empty
4604
+ */
4605
+ isEmpty() {
4606
+ if (!existsSync2(this.filePath)) {
4607
+ return true;
4608
+ }
4609
+ try {
4610
+ const content = readFileSync2(this.filePath, "utf-8");
4611
+ return content.trim().length === 0;
4612
+ } catch {
4613
+ return true;
4614
+ }
4615
+ }
4616
+ /**
4617
+ * Get file path
4618
+ */
4619
+ getPath() {
4620
+ return this.filePath;
4621
+ }
4622
+ };
4623
+ var WireLogger = class {
4624
+ wire;
4625
+ sessionId;
4626
+ constructor(sessionDir, sessionId) {
4627
+ this.wire = new WireFile(sessionDir);
4628
+ this.sessionId = sessionId;
4629
+ }
4630
+ turnBegin(userInput) {
4631
+ this.wire.write({
4632
+ type: "turn_begin",
4633
+ sessionId: this.sessionId,
4634
+ data: { userInput }
4635
+ });
4636
+ }
4637
+ turnEnd() {
4638
+ this.wire.write({
4639
+ type: "turn_end",
4640
+ sessionId: this.sessionId,
4641
+ data: {}
4642
+ });
4643
+ }
4644
+ stepBegin(stepId) {
4645
+ this.wire.write({
4646
+ type: "step_begin",
4647
+ sessionId: this.sessionId,
4648
+ data: { stepId }
4649
+ });
4650
+ }
4651
+ stepEnd(stepId) {
4652
+ this.wire.write({
4653
+ type: "step_end",
4654
+ sessionId: this.sessionId,
4655
+ data: { stepId }
4656
+ });
4657
+ }
4658
+ contentPart(content, isThinking = false) {
4659
+ this.wire.write({
4660
+ type: "content_part",
4661
+ sessionId: this.sessionId,
4662
+ data: { content, isThinking }
4663
+ });
4664
+ }
4665
+ toolCall(toolId, toolName, args) {
4666
+ this.wire.write({
4667
+ type: "tool_call",
4668
+ sessionId: this.sessionId,
4669
+ data: { toolId, toolName, args }
4670
+ });
4671
+ }
4672
+ toolResult(toolId, result, isError = false) {
4673
+ this.wire.write({
4674
+ type: "tool_result",
4675
+ sessionId: this.sessionId,
4676
+ data: { toolId, result, isError }
4677
+ });
4678
+ }
4679
+ approvalRequest(id, toolName, riskLevel) {
4680
+ this.wire.write({
4681
+ type: "approval_request",
4682
+ sessionId: this.sessionId,
4683
+ data: { id, toolName, riskLevel }
4684
+ });
4685
+ }
4686
+ approvalResponse(id, decision) {
4687
+ this.wire.write({
4688
+ type: "approval_response",
4689
+ sessionId: this.sessionId,
4690
+ data: { id, decision }
4691
+ });
4692
+ }
4693
+ statusUpdate(data) {
4694
+ this.wire.write({
4695
+ type: "status_update",
4696
+ sessionId: this.sessionId,
4697
+ data
4698
+ });
4699
+ }
4700
+ error(message, stack) {
4701
+ this.wire.write({
4702
+ type: "error",
4703
+ sessionId: this.sessionId,
4704
+ data: { message, stack }
4705
+ });
4706
+ }
4707
+ };
4708
+ var wireLogger = null;
4709
+ function initWireLogger(sessionDir, sessionId) {
4710
+ wireLogger = new WireLogger(sessionDir, sessionId);
4711
+ return wireLogger;
4712
+ }
4713
+
4714
+ // src/utils/clipboard.ts
4715
+ import { execSync } from "child_process";
4716
+ import { platform } from "os";
4717
+ import { existsSync as existsSync3, readFileSync as readFileSync3, unlinkSync as unlinkSync2 } from "fs";
4718
+ import { join as join5 } from "path";
4719
+ import { tmpdir } from "os";
4720
+ function readClipboardText() {
4721
+ const os = platform();
4722
+ try {
4723
+ if (os === "darwin") {
4724
+ return execSync("pbpaste", { encoding: "utf-8" });
4725
+ } else if (os === "linux") {
4726
+ try {
4727
+ return execSync("xclip -selection clipboard -o", { encoding: "utf-8" });
4728
+ } catch {
4729
+ return execSync("xsel --clipboard --output", { encoding: "utf-8" });
4730
+ }
4731
+ } else if (os === "win32") {
4732
+ return execSync('powershell -command "Get-Clipboard"', { encoding: "utf-8" });
4733
+ }
4734
+ } catch (error) {
4735
+ console.error("Failed to read clipboard:", error);
4736
+ return null;
4737
+ }
4738
+ return null;
4739
+ }
4740
+ function readClipboardImage() {
4741
+ const os = platform();
4742
+ const tmpPath = join5(tmpdir(), `clipboard-${Date.now()}.png`);
4743
+ try {
4744
+ if (os === "darwin") {
4745
+ const script = `
4746
+ set saveFile to POSIX file "${tmpPath}"
4747
+ try
4748
+ set imageData to the clipboard as \xABclass PNGf\xBB
4749
+ set fileRef to open for access saveFile with write permission
4750
+ write imageData to fileRef
4751
+ close access fileRef
4752
+ return "success"
4753
+ on error
4754
+ return "no image"
4755
+ end try
4756
+ `;
4757
+ const result = execSync(`osascript -e '${script}'`, { encoding: "utf-8" }).trim();
4758
+ if (result === "success" && existsSync3(tmpPath)) {
4759
+ const imageBuffer = readFileSync3(tmpPath);
4760
+ const base64 = imageBuffer.toString("base64");
4761
+ return { path: tmpPath, base64 };
4762
+ }
4763
+ } else if (os === "linux") {
4764
+ try {
4765
+ execSync(`xclip -selection clipboard -t image/png -o > "${tmpPath}"`, {
4766
+ encoding: "utf-8",
4767
+ shell: "/bin/bash"
4768
+ });
4769
+ if (existsSync3(tmpPath)) {
4770
+ const stats = __require("fs").statSync(tmpPath);
4771
+ if (stats.size > 0) {
4772
+ const imageBuffer = readFileSync3(tmpPath);
4773
+ const base64 = imageBuffer.toString("base64");
4774
+ return { path: tmpPath, base64 };
4775
+ }
4776
+ }
4777
+ } catch {
4778
+ }
4779
+ } else if (os === "win32") {
4780
+ const script = `
4781
+ Add-Type -AssemblyName System.Windows.Forms
4782
+ $img = [System.Windows.Forms.Clipboard]::GetImage()
4783
+ if ($img -ne $null) {
4784
+ $img.Save("${tmpPath.replace(/\\/g, "\\\\")}")
4785
+ Write-Output "success"
4786
+ } else {
4787
+ Write-Output "no image"
4788
+ }
4789
+ `;
4790
+ const result = execSync(`powershell -command "${script}"`, { encoding: "utf-8" }).trim();
4791
+ if (result === "success" && existsSync3(tmpPath)) {
4792
+ const imageBuffer = readFileSync3(tmpPath);
4793
+ const base64 = imageBuffer.toString("base64");
4794
+ return { path: tmpPath, base64 };
4795
+ }
4796
+ }
4797
+ } catch (error) {
4798
+ console.error("Failed to read clipboard image:", error);
4799
+ }
4800
+ if (existsSync3(tmpPath)) {
4801
+ try {
4802
+ unlinkSync2(tmpPath);
4803
+ } catch {
4804
+ }
4805
+ }
4806
+ return null;
4807
+ }
4808
+ function hasClipboardImage() {
4809
+ const os = platform();
4810
+ try {
4811
+ if (os === "darwin") {
4812
+ const result = execSync(
4813
+ `osascript -e 'try' -e 'the clipboard as \xABclass PNGf\xBB' -e 'return "yes"' -e 'on error' -e 'return "no"' -e 'end try'`,
4814
+ { encoding: "utf-8" }
4815
+ ).trim();
4816
+ return result === "yes";
4817
+ } else if (os === "linux") {
4818
+ const result = execSync("xclip -selection clipboard -t TARGETS -o", {
4819
+ encoding: "utf-8"
4820
+ });
4821
+ return result.includes("image/png") || result.includes("image/jpeg");
4822
+ }
4823
+ } catch {
4824
+ return false;
4825
+ }
4826
+ return false;
4827
+ }
4828
+
4330
4829
  // src/config/theme.ts
4331
4830
  var THEME = {
4332
4831
  // Primary backgrounds (dark purple tones)
@@ -4444,8 +4943,68 @@ var ASCII_BANNER = `
4444
4943
  \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
4445
4944
  `;
4446
4945
 
4447
- // src/cli/app.tsx
4946
+ // src/cli/components/rich-display.tsx
4947
+ import { Box, Text } from "ink";
4448
4948
  import { jsx, jsxs } from "react/jsx-runtime";
4949
+ var SeverityBadge = ({ severity }) => {
4950
+ const colors = {
4951
+ critical: THEME.semantic.critical,
4952
+ high: THEME.semantic.high,
4953
+ medium: THEME.semantic.medium,
4954
+ low: THEME.semantic.low,
4955
+ info: THEME.semantic.info
4956
+ };
4957
+ return /* @__PURE__ */ jsxs(Text, { color: colors[severity], bold: true, children: [
4958
+ "\u25CF ",
4959
+ severity.toUpperCase()
4960
+ ] });
4961
+ };
4962
+ var FindingDisplay = ({ block }) => {
4963
+ const severityColors = {
4964
+ critical: THEME.semantic.critical,
4965
+ high: THEME.semantic.high,
4966
+ medium: THEME.semantic.medium,
4967
+ low: THEME.semantic.low,
4968
+ info: THEME.semantic.info
4969
+ };
4970
+ return /* @__PURE__ */ jsxs(
4971
+ Box,
4972
+ {
4973
+ flexDirection: "column",
4974
+ borderStyle: "double",
4975
+ borderColor: severityColors[block.severity],
4976
+ paddingX: 1,
4977
+ children: [
4978
+ /* @__PURE__ */ jsxs(Box, { children: [
4979
+ /* @__PURE__ */ jsx(SeverityBadge, { severity: block.severity }),
4980
+ /* @__PURE__ */ jsxs(Text, { color: THEME.text.primary, bold: true, children: [
4981
+ " ",
4982
+ block.title
4983
+ ] }),
4984
+ block.cve && /* @__PURE__ */ jsxs(Text, { color: THEME.text.muted, children: [
4985
+ " (",
4986
+ block.cve,
4987
+ ")"
4988
+ ] })
4989
+ ] }),
4990
+ /* @__PURE__ */ jsx(Box, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx(Text, { color: THEME.text.secondary, children: block.description }) }),
4991
+ block.evidence && /* @__PURE__ */ jsxs(Box, { marginTop: 1, flexDirection: "column", children: [
4992
+ /* @__PURE__ */ jsx(Text, { color: THEME.accent.cyan, bold: true, children: "Evidence:" }),
4993
+ /* @__PURE__ */ jsx(Text, { color: THEME.text.muted, children: block.evidence })
4994
+ ] }),
4995
+ block.recommendation && /* @__PURE__ */ jsxs(Box, { marginTop: 1, flexDirection: "column", children: [
4996
+ /* @__PURE__ */ jsx(Text, { color: THEME.accent.green, bold: true, children: "Recommendation:" }),
4997
+ /* @__PURE__ */ jsx(Text, { color: THEME.text.secondary, children: block.recommendation })
4998
+ ] })
4999
+ ]
5000
+ }
5001
+ );
5002
+ };
5003
+
5004
+ // src/cli/app.tsx
5005
+ import { homedir } from "os";
5006
+ import { join as join6 } from "path";
5007
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
4449
5008
  var App = ({ autoApprove = false, target }) => {
4450
5009
  const { exit } = useApp();
4451
5010
  const [messages, setMessages] = useState([]);
@@ -4458,9 +5017,23 @@ var App = ({ autoApprove = false, target }) => {
4458
5017
  const [tokenUsage, setTokenUsage] = useState({ input: 0, output: 0, total: 0 });
4459
5018
  const [showCommandHints, setShowCommandHints] = useState(false);
4460
5019
  const [mode, setMode] = useState("agent");
5020
+ const [checkpointCount, setCheckpointCount] = useState(0);
4461
5021
  const [agent] = useState(() => new AutonomousHackingAgent(void 0, { autoApprove }));
4462
5022
  const sessionManager2 = getSessionManager();
4463
5023
  const approvalManager2 = getApprovalManager({ yoloMode: autoApprove });
5024
+ const sessionDirRef = useRef(join6(homedir(), ".pentest", "sessions", `session-${Date.now()}`));
5025
+ const contextManagerRef = useRef(null);
5026
+ const wireLoggerRef = useRef(null);
5027
+ useEffect(() => {
5028
+ const sessionId = `session-${Date.now()}`;
5029
+ contextManagerRef.current = new ContextManager2(sessionDirRef.current);
5030
+ wireLoggerRef.current = initWireLogger(sessionDirRef.current, sessionId);
5031
+ contextManagerRef.current.restore().then((restored) => {
5032
+ if (restored) {
5033
+ setCheckpointCount(contextManagerRef.current?.getCheckpoints().length || 0);
5034
+ }
5035
+ });
5036
+ }, []);
4464
5037
  const startTimeRef = useRef(0);
4465
5038
  const timerRef = useRef(null);
4466
5039
  const addMessage = useCallback((type, content, duration) => {
@@ -4498,31 +5071,39 @@ var App = ({ autoApprove = false, target }) => {
4498
5071
  }
4499
5072
  agent.on(AGENT_EVENT.THOUGHT, (thought) => {
4500
5073
  setCurrentStatus(thought.content.slice(0, 60));
5074
+ wireLoggerRef.current?.contentPart(thought.content, thought.type === "thinking");
4501
5075
  });
4502
5076
  agent.on(AGENT_EVENT.TOOL_CALL, (data) => {
4503
5077
  const args = Object.entries(data.input).slice(0, 2).map(([k, v]) => `${k}=${typeof v === "string" ? v.slice(0, 30) : "..."}`).join(" ");
4504
5078
  setCurrentStatus(`Running ${data.name}...`);
4505
5079
  addMessage(MESSAGE_TYPE.TOOL, `\u25B6 ${data.name} ${args}`);
5080
+ wireLoggerRef.current?.toolCall(data.id, data.name, data.input);
4506
5081
  });
4507
5082
  agent.on(AGENT_EVENT.TOOL_RESULT, (data) => {
4508
5083
  const icon = data.result.success ? "\u2713" : "\u2717";
4509
5084
  const preview = data.result.output?.slice(0, 100).replace(/\n/g, " ") || "";
4510
5085
  addMessage(MESSAGE_TYPE.RESULT, `${icon} ${preview}`);
5086
+ wireLoggerRef.current?.toolResult(data.id, data.result, !data.result.success);
4511
5087
  });
4512
5088
  agent.on(AGENT_EVENT.ITERATION, (data) => {
4513
5089
  setCurrentStatus(`Phase: ${data.phase} (iteration ${data.current})`);
5090
+ wireLoggerRef.current?.stepBegin(data.current);
4514
5091
  });
4515
5092
  agent.on(AGENT_EVENT.FINDING, (finding) => {
4516
5093
  addMessage(MESSAGE_TYPE.SYSTEM, `\u{1F3AF} [${finding.severity.toUpperCase()}] ${finding.title}`);
5094
+ wireLoggerRef.current?.statusUpdate({ event: "finding", ...finding });
4517
5095
  });
4518
5096
  agent.on(AGENT_EVENT.PHASE_CHANGE, (data) => {
4519
5097
  addMessage(MESSAGE_TYPE.SYSTEM, `\u{1F4CD} Phase: ${data.phaseId}`);
5098
+ wireLoggerRef.current?.statusUpdate({ event: "phase_change", phase: data.phaseId });
4520
5099
  });
4521
5100
  agent.on(AGENT_EVENT.CONTEXT_COMPACTED, () => {
4522
5101
  addMessage(MESSAGE_TYPE.SYSTEM, "\u{1F4BE} Context compacted to save tokens");
5102
+ wireLoggerRef.current?.statusUpdate({ event: "context_compacted" });
4523
5103
  });
4524
5104
  agent.on(AGENT_EVENT.TOKEN_USAGE, (usage) => {
4525
5105
  setTokenUsage(usage);
5106
+ wireLoggerRef.current?.statusUpdate({ event: "token_usage", ...usage });
4526
5107
  });
4527
5108
  agent.on(AGENT_EVENT.APPROVAL_NEEDED, (data) => {
4528
5109
  setPendingApproval({
@@ -4601,16 +5182,30 @@ var App = ({ autoApprove = false, target }) => {
4601
5182
  case "h":
4602
5183
  addMessage(
4603
5184
  MESSAGE_TYPE.SYSTEM,
4604
- `/target <ip> Set target
5185
+ `\u2500\u2500 Core \u2500\u2500
5186
+ /target <ip> Set target
4605
5187
  /start [goal] Start autonomous pentest
4606
5188
  /stop Stop operation
4607
- /findings Show findings
5189
+ /status Show status report
5190
+
5191
+ \u2500\u2500 Session \u2500\u2500
5192
+ /checkpoint [desc] Create checkpoint
5193
+ /checkpoints List all checkpoints
5194
+ /undo Undo to last checkpoint
5195
+ /revert <id> Revert to checkpoint
5196
+ /compact Compact context
4608
5197
  /sessions List saved sessions
4609
5198
  /resume [id] Resume session
5199
+
5200
+ \u2500\u2500 Findings \u2500\u2500
5201
+ /findings Show findings
5202
+
5203
+ \u2500\u2500 Utility \u2500\u2500
5204
+ /paste Paste from clipboard
4610
5205
  /yolo Toggle auto-approve
4611
5206
  /clear Clear screen
4612
5207
  /exit Exit
4613
- /approve /deny Approve/deny tool (during approval)`
5208
+ /y /n /ya Approve/Deny/Always (approval)`
4614
5209
  );
4615
5210
  return;
4616
5211
  case CLI_COMMAND.TARGET:
@@ -4724,17 +5319,99 @@ var App = ({ autoApprove = false, target }) => {
4724
5319
  addMessage(MESSAGE_TYPE.ERROR, "No pending approval");
4725
5320
  }
4726
5321
  return;
4727
- // kimi-cli inspired commands
5322
+ // kimi-cli inspired commands - REAL IMPLEMENTATIONS
4728
5323
  case "undo":
4729
5324
  case "u":
4730
- addMessage(MESSAGE_TYPE.SYSTEM, "\u21A9\uFE0F Undo not yet integrated (context checkpoints)");
5325
+ if (contextManagerRef.current) {
5326
+ const success = await contextManagerRef.current.undo();
5327
+ if (success) {
5328
+ setCheckpointCount((prev) => Math.max(0, prev - 1));
5329
+ wireLoggerRef.current?.statusUpdate({ action: "undo" });
5330
+ addMessage(MESSAGE_TYPE.SYSTEM, "\u21A9\uFE0F Undone to previous checkpoint");
5331
+ } else {
5332
+ addMessage(MESSAGE_TYPE.ERROR, "No checkpoint to undo");
5333
+ }
5334
+ } else {
5335
+ addMessage(MESSAGE_TYPE.ERROR, "Context manager not initialized");
5336
+ }
4731
5337
  return;
4732
5338
  case "checkpoint":
4733
5339
  case "cp":
4734
- addMessage(MESSAGE_TYPE.SYSTEM, "\u{1F4CD} Checkpoint created");
5340
+ if (contextManagerRef.current) {
5341
+ const description = args.join(" ") || void 0;
5342
+ const cp = await contextManagerRef.current.checkpoint(description);
5343
+ setCheckpointCount((prev) => prev + 1);
5344
+ wireLoggerRef.current?.statusUpdate({ action: "checkpoint", id: cp.id });
5345
+ addMessage(MESSAGE_TYPE.SYSTEM, `\u{1F4CD} Checkpoint #${cp.id} created${description ? `: ${description}` : ""}`);
5346
+ } else {
5347
+ addMessage(MESSAGE_TYPE.ERROR, "Context manager not initialized");
5348
+ }
4735
5349
  return;
4736
5350
  case "compact":
4737
- addMessage(MESSAGE_TYPE.SYSTEM, "\u{1F5DC}\uFE0F Context compacted");
5351
+ if (contextManagerRef.current) {
5352
+ const summary = "Previous conversation summarized for context efficiency.";
5353
+ await contextManagerRef.current.compact(summary, 3);
5354
+ wireLoggerRef.current?.statusUpdate({ action: "compact" });
5355
+ addMessage(MESSAGE_TYPE.SYSTEM, "\u{1F5DC}\uFE0F Context compacted (keeping last 3 messages)");
5356
+ } else {
5357
+ addMessage(MESSAGE_TYPE.ERROR, "Context manager not initialized");
5358
+ }
5359
+ return;
5360
+ case "paste":
5361
+ case "p":
5362
+ try {
5363
+ if (hasClipboardImage()) {
5364
+ const img = readClipboardImage();
5365
+ if (img) {
5366
+ addMessage(MESSAGE_TYPE.SYSTEM, `\u{1F4F7} Image from clipboard: ${img.path}`);
5367
+ addMessage(MESSAGE_TYPE.SYSTEM, ` Size: ${Math.round(img.base64.length / 1024)}KB base64`);
5368
+ }
5369
+ } else {
5370
+ const text = readClipboardText();
5371
+ if (text) {
5372
+ const preview = text.length > 100 ? text.slice(0, 100) + "..." : text;
5373
+ addMessage(MESSAGE_TYPE.SYSTEM, `\u{1F4CB} Clipboard: ${preview}`);
5374
+ setInput(text);
5375
+ } else {
5376
+ addMessage(MESSAGE_TYPE.ERROR, "Clipboard is empty");
5377
+ }
5378
+ }
5379
+ } catch (e) {
5380
+ addMessage(MESSAGE_TYPE.ERROR, `Clipboard error: ${e instanceof Error ? e.message : String(e)}`);
5381
+ }
5382
+ return;
5383
+ case "revert":
5384
+ if (contextManagerRef.current && args[0]) {
5385
+ const cpId = parseInt(args[0], 10);
5386
+ if (isNaN(cpId)) {
5387
+ addMessage(MESSAGE_TYPE.ERROR, "Usage: /revert <checkpoint_id>");
5388
+ return;
5389
+ }
5390
+ const success = await contextManagerRef.current.revertTo(cpId);
5391
+ if (success) {
5392
+ wireLoggerRef.current?.statusUpdate({ action: "revert", checkpointId: cpId });
5393
+ addMessage(MESSAGE_TYPE.SYSTEM, `\u21A9\uFE0F Reverted to checkpoint #${cpId}`);
5394
+ } else {
5395
+ addMessage(MESSAGE_TYPE.ERROR, `Checkpoint #${cpId} not found`);
5396
+ }
5397
+ } else {
5398
+ addMessage(MESSAGE_TYPE.ERROR, "Usage: /revert <checkpoint_id>");
5399
+ }
5400
+ return;
5401
+ case "checkpoints":
5402
+ case "cps":
5403
+ if (contextManagerRef.current) {
5404
+ const cps = contextManagerRef.current.getCheckpoints();
5405
+ if (cps.length === 0) {
5406
+ addMessage(MESSAGE_TYPE.SYSTEM, "No checkpoints");
5407
+ } else {
5408
+ addMessage(MESSAGE_TYPE.SYSTEM, `\u{1F4CD} ${cps.length} Checkpoints:`);
5409
+ cps.forEach((cp) => {
5410
+ const time = new Date(cp.timestamp).toLocaleTimeString();
5411
+ addMessage(MESSAGE_TYPE.SYSTEM, ` #${cp.id} @ ${time} (${cp.messageCount} msgs)${cp.description ? ` - ${cp.description}` : ""}`);
5412
+ });
5413
+ }
5414
+ }
4738
5415
  return;
4739
5416
  case "status":
4740
5417
  const state2 = agent.getState();
@@ -4743,7 +5420,8 @@ var App = ({ autoApprove = false, target }) => {
4743
5420
  Iteration: ${state2.iteration}
4744
5421
  Findings: ${state2.findings.length}
4745
5422
  Compromised: ${state2.compromisedHosts.length}
4746
- Tokens: ${tokenUsage.total.toLocaleString()}`);
5423
+ Tokens: ${tokenUsage.total.toLocaleString()}
5424
+ Checkpoints: ${checkpointCount}`);
4747
5425
  return;
4748
5426
  case "think":
4749
5427
  addMessage(MESSAGE_TYPE.SYSTEM, "\u{1F9E0} Thinking mode: Extended reasoning enabled");
@@ -4774,8 +5452,8 @@ var App = ({ autoApprove = false, target }) => {
4774
5452
  startTimer();
4775
5453
  setCurrentStatus(`Running: ${trimmed}`);
4776
5454
  try {
4777
- const { execSync } = await import("child_process");
4778
- const output = execSync(trimmed, {
5455
+ const { execSync: execSync2 } = await import("child_process");
5456
+ const output = execSync2(trimmed, {
4779
5457
  encoding: "utf-8",
4780
5458
  timeout: 3e4,
4781
5459
  maxBuffer: 1024 * 1024
@@ -4859,48 +5537,51 @@ var App = ({ autoApprove = false, target }) => {
4859
5537
  return styles[type] || styles[MESSAGE_TYPE.SYSTEM];
4860
5538
  };
4861
5539
  const state = agent.getState();
4862
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingX: 1, children: [
4863
- /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsx(Static, { items: messages.slice(-40), children: (msg) => {
5540
+ return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", paddingX: 1, children: [
5541
+ /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsx2(Static, { items: messages.slice(-40), children: (msg) => {
4864
5542
  const style = getStyle(msg.type);
4865
- return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { color: style.color, dimColor: style.dim, children: [
5543
+ if (msg.finding) {
5544
+ return /* @__PURE__ */ jsx2(Box2, { marginY: 0, children: /* @__PURE__ */ jsx2(FindingDisplay, { block: msg.finding }) }, msg.id);
5545
+ }
5546
+ return /* @__PURE__ */ jsx2(Box2, { children: /* @__PURE__ */ jsxs2(Text2, { color: style.color, dimColor: style.dim, children: [
4866
5547
  style.prefix,
4867
5548
  " ",
4868
5549
  msg.content,
4869
- msg.duration && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
5550
+ msg.duration && /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
4870
5551
  " (",
4871
5552
  msg.duration,
4872
5553
  "s)"
4873
5554
  ] })
4874
5555
  ] }) }, msg.id);
4875
5556
  } }) }),
4876
- pendingApproval && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, marginBottom: 1, children: [
4877
- /* @__PURE__ */ jsxs(Text, { color: "yellow", bold: true, children: [
5557
+ pendingApproval && /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, marginBottom: 1, children: [
5558
+ /* @__PURE__ */ jsxs2(Text2, { color: "yellow", bold: true, children: [
4878
5559
  "\u26A0\uFE0F APPROVAL NEEDED: ",
4879
5560
  pendingApproval.toolName,
4880
5561
  " (",
4881
5562
  pendingApproval.riskLevel,
4882
5563
  " risk)"
4883
5564
  ] }),
4884
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: Object.entries(pendingApproval.toolInput).slice(0, 2).map(([k, v]) => `${k}=${typeof v === "string" ? v.slice(0, 50) : JSON.stringify(v).slice(0, 50)}`).join(", ") }),
4885
- /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginTop: 1, children: approvalOptions.map((opt, idx) => /* @__PURE__ */ jsxs(Text, { color: idx === approvalSelectedIndex ? "cyan" : "gray", children: [
5565
+ /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: Object.entries(pendingApproval.toolInput).slice(0, 2).map(([k, v]) => `${k}=${typeof v === "string" ? v.slice(0, 50) : JSON.stringify(v).slice(0, 50)}`).join(", ") }),
5566
+ /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", marginTop: 1, children: approvalOptions.map((opt, idx) => /* @__PURE__ */ jsxs2(Text2, { color: idx === approvalSelectedIndex ? "cyan" : "gray", children: [
4886
5567
  idx === approvalSelectedIndex ? "\u2192 " : " ",
4887
5568
  opt.label
4888
5569
  ] }, opt.decision)) }),
4889
- /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191\u2193 to select, Enter to confirm, or type /y /n /ya" }) })
5570
+ /* @__PURE__ */ jsx2(Box2, { marginTop: 1, children: /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "\u2191\u2193 to select, Enter to confirm, or type /y /n /ya" }) })
4890
5571
  ] }),
4891
- isProcessing ? /* @__PURE__ */ jsxs(Box, { children: [
4892
- /* @__PURE__ */ jsx(Text, { color: THEME.status.running, children: /* @__PURE__ */ jsx(Spinner, { type: "dots" }) }),
4893
- /* @__PURE__ */ jsxs(Text, { color: THEME.text.muted, children: [
5572
+ isProcessing ? /* @__PURE__ */ jsxs2(Box2, { children: [
5573
+ /* @__PURE__ */ jsx2(Text2, { color: THEME.status.running, children: /* @__PURE__ */ jsx2(Spinner, { type: "dots" }) }),
5574
+ /* @__PURE__ */ jsxs2(Text2, { color: THEME.text.muted, children: [
4894
5575
  " ",
4895
5576
  currentStatus,
4896
- elapsedTime > 0 && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
5577
+ elapsedTime > 0 && /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
4897
5578
  " (",
4898
5579
  elapsedTime,
4899
5580
  "s)"
4900
5581
  ] })
4901
5582
  ] })
4902
- ] }) : /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
4903
- showCommandHints && input.startsWith("/") && /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: [
5583
+ ] }) : /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
5584
+ showCommandHints && input.startsWith("/") && /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: [
4904
5585
  "/target <ip>",
4905
5586
  "/start",
4906
5587
  "/stop",
@@ -4911,9 +5592,9 @@ var App = ({ autoApprove = false, target }) => {
4911
5592
  "/exit",
4912
5593
  pendingApproval ? "/y /n /ya" : ""
4913
5594
  ].filter((cmd) => cmd && cmd.toLowerCase().includes(input.toLowerCase().slice(1))).slice(0, 5).join(" \u2502 ") }) }),
4914
- /* @__PURE__ */ jsxs(Box, { children: [
4915
- /* @__PURE__ */ jsx(Text, { color: mode === "agent" ? THEME.status.success : "yellow", children: mode === "agent" ? "\u2728 " : "$ " }),
4916
- /* @__PURE__ */ jsx(
5595
+ /* @__PURE__ */ jsxs2(Box2, { children: [
5596
+ /* @__PURE__ */ jsx2(Text2, { color: mode === "agent" ? THEME.status.success : "yellow", children: mode === "agent" ? "\u2728 " : "$ " }),
5597
+ /* @__PURE__ */ jsx2(
4917
5598
  TextInput,
4918
5599
  {
4919
5600
  value: input,
@@ -4927,8 +5608,8 @@ var App = ({ autoApprove = false, target }) => {
4927
5608
  )
4928
5609
  ] })
4929
5610
  ] }),
4930
- /* @__PURE__ */ jsxs(Box, { marginTop: 1, justifyContent: "space-between", children: [
4931
- /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
5611
+ /* @__PURE__ */ jsxs2(Box2, { marginTop: 1, justifyContent: "space-between", children: [
5612
+ /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
4932
5613
  mode === "agent" ? "\u{1F916}" : "$",
4933
5614
  " ",
4934
5615
  state.target.primary || "No target",
@@ -4940,7 +5621,7 @@ var App = ({ autoApprove = false, target }) => {
4940
5621
  tokenUsage.total > 0 && `${(tokenUsage.total / 1e3).toFixed(1)}k tokens \u2502`,
4941
5622
  state.currentPhase !== AGENT_STATUS.IDLE && ` ${state.currentPhase} \u2502`
4942
5623
  ] }),
4943
- /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
5624
+ /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
4944
5625
  "Ctrl+X mode \u2502 /help \u2502 Ctrl+C ",
4945
5626
  isProcessing ? "stop" : "exit"
4946
5627
  ] })
@@ -4951,7 +5632,7 @@ var app_default = App;
4951
5632
 
4952
5633
  // src/index.tsx
4953
5634
  import chalk from "chalk";
4954
- import { jsx as jsx2 } from "react/jsx-runtime";
5635
+ import { jsx as jsx3 } from "react/jsx-runtime";
4955
5636
  var program = new Command();
4956
5637
  program.name("pentesting").version(APP_VERSION).description(APP_DESCRIPTION).option("--dangerously-skip-permissions", "Skip all permission prompts (dangerous!)").option("-t, --target <target>", "Set initial target");
4957
5638
  program.command("interactive", { isDefault: true }).alias("i").description("Start interactive TUI mode").action(() => {
@@ -4965,7 +5646,7 @@ program.command("interactive", { isDefault: true }).alias("i").description("Star
4965
5646
  }
4966
5647
  console.log(chalk.hex(THEME.text.accent)("Starting Pentest interactive mode...\n"));
4967
5648
  const { waitUntilExit } = render(
4968
- /* @__PURE__ */ jsx2(
5649
+ /* @__PURE__ */ jsx3(
4969
5650
  app_default,
4970
5651
  {
4971
5652
  autoApprove: skipPermissions,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pentesting",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Autonomous Penetration Testing AI Agent",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",