@pensar/apex 0.0.27 → 0.0.28-canary.0

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/bin/pensar.js CHANGED
@@ -48,17 +48,29 @@ if (command === "benchmark") {
48
48
 
49
49
  // Import and run quicktest
50
50
  await import(quicktestPath);
51
- } else if (command === "--version" || command === "-v") {
51
+ } else if (command === "pentest") {
52
+ // Run pentest CLI
53
+ const pentestPath = join(__dirname, "..", "build", "pentest.js");
54
+
55
+ // Remove "pentest" from args and pass the rest to pentest script
56
+ process.argv = [process.argv[0], pentestPath, ...args.slice(1)];
57
+
58
+ // Import and run pentest
59
+ await import(pentestPath);
60
+ } else if (command === "version" || command === "--version" || command === "-v") {
52
61
  // Show version
53
62
  console.log(`v${version}`);
54
- } else if (command === "--help" || command === "-h") {
63
+ } else if (command === "help" || command === "--help" || command === "-h") {
55
64
  // Show help
56
65
  console.log("Pensar - AI-Powered Penetration Testing CLI");
57
66
  console.log();
58
67
  console.log("Usage:");
59
68
  console.log(" pensar Launch the TUI (Terminal User Interface)");
69
+ console.log(" pensar help Show this help message");
70
+ console.log(" pensar version Show version number");
60
71
  console.log(" pensar benchmark Run the benchmark CLI");
61
72
  console.log(" pensar quicktest Run a quick penetration test");
73
+ console.log(" pensar pentest Run a comprehensive penetration test");
62
74
  console.log(
63
75
  " pensar swarm Run parallel pentests on multiple targets"
64
76
  );
@@ -80,7 +92,7 @@ if (command === "benchmark") {
80
92
  console.log();
81
93
  console.log("Quicktest Usage:");
82
94
  console.log(
83
- " pensar quicktest --target <target> --objective <objective> [--model <model>]"
95
+ " pensar quicktest --target <target> --objective <objective> [options]"
84
96
  );
85
97
  console.log();
86
98
  console.log("Quicktest Options:");
@@ -93,9 +105,34 @@ if (command === "benchmark") {
93
105
  console.log(
94
106
  " --model <model> AI model to use (default: claude-sonnet-4-5)"
95
107
  );
108
+ console.log(
109
+ " --headers <mode> Header mode: none, default, custom (default: default)"
110
+ );
111
+ console.log(
112
+ " --header <name:value> Add custom header (requires --headers custom)"
113
+ );
114
+ console.log();
115
+ console.log("Pentest Usage:");
116
+ console.log(
117
+ " pensar pentest --target <target> [options]"
118
+ );
119
+ console.log();
120
+ console.log("Pentest Options:");
121
+ console.log(
122
+ " --target <target> Target domain or organization (required)"
123
+ );
124
+ console.log(
125
+ " --model <model> AI model to use (default: claude-sonnet-4-5)"
126
+ );
127
+ console.log(
128
+ " --headers <mode> Header mode: none, default, custom (default: default)"
129
+ );
130
+ console.log(
131
+ " --header <name:value> Add custom header (requires --headers custom)"
132
+ );
96
133
  console.log();
97
134
  console.log("Swarm Usage:");
98
- console.log(" pensar swarm <targets> [--model <model>]");
135
+ console.log(" pensar swarm <targets> [options]");
99
136
  console.log();
100
137
  console.log("Swarm Arguments:");
101
138
  console.log(" <targets> JSON string or path to JSON file");
@@ -104,36 +141,43 @@ if (command === "benchmark") {
104
141
  console.log(
105
142
  " --model <model> AI model to use (default: claude-sonnet-4-5)"
106
143
  );
144
+ console.log(
145
+ " --headers <mode> Header mode: none, default, custom (default: default)"
146
+ );
147
+ console.log(
148
+ " --header <name:value> Add custom header (requires --headers custom)"
149
+ );
107
150
  console.log();
108
- console.log("Targets format (JSON array):");
109
- console.log(" [");
110
- console.log(" {");
111
- console.log(' "target": "api.example.com",');
112
- console.log(' "objective": "Test API for injection vulnerabilities"');
113
- console.log(" },");
114
- console.log(" {");
115
- console.log(' "target": "admin.example.com",');
116
- console.log(' "objective": "Test admin panel for auth bypass"');
117
- console.log(" }");
118
- console.log(" ]");
151
+ console.log("Header Modes (for quicktest, pentest, swarm):");
152
+ console.log(
153
+ " none No custom headers added to requests"
154
+ );
155
+ console.log(
156
+ " default Add 'User-Agent: pensar-apex' to all offensive requests"
157
+ );
158
+ console.log(
159
+ " custom Use custom headers defined with --header flag"
160
+ );
119
161
  console.log();
120
162
  console.log("Examples:");
121
163
  console.log(" pensar");
122
164
  console.log(" pensar benchmark /path/to/vulnerable-app");
123
165
  console.log(" pensar benchmark /path/to/app main develop");
124
166
  console.log(" pensar benchmark /path/to/app --all-branches --limit 3");
125
- console.log(" pensar benchmark /path/to/app --model gpt-4o");
126
167
  console.log(
127
168
  " pensar quicktest --target http://localhost:3000 --objective 'Find SQL injection'"
128
169
  );
129
170
  console.log(
130
- " pensar quicktest --target 192.168.1.100 --objective 'Test auth bypass' --model gpt-4o"
171
+ " pensar quicktest --target api.example.com --objective 'API testing' --headers custom --header 'User-Agent: pensar_client123'"
172
+ );
173
+ console.log(
174
+ " pensar pentest --target example.com"
131
175
  );
132
- console.log(" pensar swarm targets.json");
133
- console.log(" pensar swarm targets.json --model gpt-4o");
134
176
  console.log(
135
- ' pensar swarm \'[{"target":"api.example.com","objective":"Test API"}]\''
177
+ " pensar pentest --target example.com --headers custom --header 'User-Agent: pensar_client123'"
136
178
  );
179
+ console.log(" pensar swarm targets.json");
180
+ console.log(" pensar swarm targets.json --headers none");
137
181
  } else if (args.length === 0) {
138
182
  // No command specified, run the TUI
139
183
  const appPath = join(__dirname, "..", "build", "index.js");
@@ -62994,7 +62994,7 @@ var require_dist_cjs77 = __commonJS((exports) => {
62994
62994
 
62995
62995
  // node_modules/@smithy/util-waiter/dist-cjs/index.js
62996
62996
  var require_dist_cjs78 = __commonJS((exports) => {
62997
- var sleep = (seconds) => {
62997
+ var sleep2 = (seconds) => {
62998
62998
  return new Promise((resolve3) => setTimeout(resolve3, seconds * 1000));
62999
62999
  };
63000
63000
  var waiterServiceDefaults = {
@@ -63061,7 +63061,7 @@ var require_dist_cjs78 = __commonJS((exports) => {
63061
63061
  if (Date.now() + delay2 * 1000 > waitUntil) {
63062
63062
  return { state: exports.WaiterState.TIMEOUT, observedResponses };
63063
63063
  }
63064
- await sleep(delay2);
63064
+ await sleep2(delay2);
63065
63065
  const { state: state2, reason: reason2 } = await acceptorChecks(client, input);
63066
63066
  if (reason2) {
63067
63067
  const message = createMessageFromResponse(reason2);
@@ -121929,6 +121929,69 @@ import {
121929
121929
  } from "fs";
121930
121930
  import { join } from "path";
121931
121931
  import { homedir } from "os";
121932
+
121933
+ // src/core/services/rateLimiter/index.ts
121934
+ function sleep(ms) {
121935
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
121936
+ }
121937
+
121938
+ class RateLimiter {
121939
+ tokens;
121940
+ lastRefillTime;
121941
+ rps;
121942
+ bucketSize;
121943
+ msPerToken;
121944
+ queue;
121945
+ constructor(config2) {
121946
+ this.rps = config2?.requestsPerSecond;
121947
+ this.bucketSize = this.rps ? 1 : 0;
121948
+ this.tokens = this.bucketSize;
121949
+ this.lastRefillTime = performance.now();
121950
+ this.msPerToken = this.rps ? 1000 / this.rps : undefined;
121951
+ this.queue = Promise.resolve();
121952
+ }
121953
+ async acquireSlot() {
121954
+ if (!this.rps || !this.msPerToken)
121955
+ return;
121956
+ const previousPromise = this.queue;
121957
+ let resolveCurrentRequest;
121958
+ this.queue = new Promise((resolve2) => {
121959
+ resolveCurrentRequest = resolve2;
121960
+ });
121961
+ await previousPromise;
121962
+ try {
121963
+ const now2 = performance.now();
121964
+ this.refill(now2);
121965
+ if (this.tokens < 1) {
121966
+ const waitTime = (1 - this.tokens) * this.msPerToken;
121967
+ await sleep(waitTime);
121968
+ const nowAfterSleep = performance.now();
121969
+ this.refill(nowAfterSleep);
121970
+ }
121971
+ this.tokens -= 1;
121972
+ } finally {
121973
+ resolveCurrentRequest();
121974
+ }
121975
+ }
121976
+ refill(now2) {
121977
+ if (this.tokens >= this.bucketSize) {
121978
+ this.lastRefillTime = now2;
121979
+ return;
121980
+ }
121981
+ const elapsed = now2 - this.lastRefillTime;
121982
+ const tokensToAdd = elapsed / this.msPerToken;
121983
+ this.tokens = Math.min(this.bucketSize, this.tokens + tokensToAdd);
121984
+ this.lastRefillTime = now2;
121985
+ }
121986
+ isEnabled() {
121987
+ return this.rps !== undefined;
121988
+ }
121989
+ }
121990
+
121991
+ // src/core/agent/sessions/index.ts
121992
+ var DEFAULT_OFFENSIVE_HEADERS = {
121993
+ "User-Agent": "pensar-apex"
121994
+ };
121932
121995
  function generateSessionId(prefix) {
121933
121996
  const timestamp = Date.now().toString(36);
121934
121997
  return `${prefix ? `${prefix}-` : ""}${timestamp}`;
@@ -121939,7 +122002,7 @@ function getPensarDir() {
121939
122002
  function getExecutionsDir() {
121940
122003
  return join(getPensarDir(), "executions");
121941
122004
  }
121942
- function createSession(target, objective, prefix) {
122005
+ function createSession(target, objective, prefix, config2) {
121943
122006
  const sessionId = generateSessionId(prefix);
121944
122007
  const rootPath = join(getExecutionsDir(), sessionId);
121945
122008
  const findingsPath = join(rootPath, "findings");
@@ -121957,8 +122020,12 @@ function createSession(target, objective, prefix) {
121957
122020
  logsPath,
121958
122021
  target,
121959
122022
  objective: objective ?? "",
121960
- startTime: new Date().toISOString()
122023
+ startTime: new Date().toISOString(),
122024
+ config: config2
121961
122025
  };
122026
+ if (config2?.rateLimiter) {
122027
+ session._rateLimiter = new RateLimiter(config2.rateLimiter);
122028
+ }
121962
122029
  const metadataPath = join(rootPath, "session.json");
121963
122030
  writeFileSync(metadataPath, JSON.stringify(session, null, 2));
121964
122031
  const readmePath = join(rootPath, "README.md");
@@ -121992,6 +122059,19 @@ function ensureDirectoryExists(path) {
121992
122059
  mkdirSync(path, { recursive: true });
121993
122060
  }
121994
122061
  }
122062
+ function getOffensiveHeaders(session) {
122063
+ const config2 = session.config?.offensiveHeaders;
122064
+ if (!config2 || config2.mode === "none") {
122065
+ return;
122066
+ }
122067
+ if (config2.mode === "default") {
122068
+ return DEFAULT_OFFENSIVE_HEADERS;
122069
+ }
122070
+ if (config2.mode === "custom" && config2.headers) {
122071
+ return config2.headers;
122072
+ }
122073
+ return;
122074
+ }
121995
122075
 
121996
122076
  // src/core/agent/benchmark/tools.ts
121997
122077
  import { writeFileSync as writeFileSync9 } from "fs";
@@ -126153,9 +126233,10 @@ function runAgent(opts) {
126153
126233
  silent,
126154
126234
  authConfig,
126155
126235
  toolOverride,
126156
- messages
126236
+ messages,
126237
+ sessionConfig
126157
126238
  } = opts;
126158
- const session = opts.session || createSession(target, objective);
126239
+ const session = opts.session || createSession(target, objective, undefined, sessionConfig);
126159
126240
  const pocsPath = join3(session.rootPath, "pocs");
126160
126241
  if (!existsSync5(pocsPath)) {
126161
126242
  mkdirSync4(pocsPath, { recursive: true });
@@ -128627,7 +128708,53 @@ ${note}
128627
128708
  }
128628
128709
  });
128629
128710
  }
128711
+ function wrapCommandWithHeaders(command, headers) {
128712
+ const userAgent = headers["User-Agent"];
128713
+ if (!userAgent)
128714
+ return command;
128715
+ let wrapped = command;
128716
+ if (command.includes("curl") && !command.includes("User-Agent") && !command.includes("-A")) {
128717
+ wrapped = wrapped.replace(/\bcurl(\s+)/g, `curl -A "${userAgent}" $1`);
128718
+ }
128719
+ if (command.includes("nikto") && !command.includes("-useragent")) {
128720
+ wrapped = wrapped.replace(/\bnikto\s+/, `nikto -useragent "${userAgent}" `);
128721
+ }
128722
+ if (command.includes("nmap") && command.includes("--script") && /--script[= ](.*?http.*?)/.test(command) && !command.includes("http.useragent")) {
128723
+ if (command.includes("--script-args")) {
128724
+ wrapped = wrapped.replace(/--script-args\s+([^\s]+)/, `--script-args $1,http.useragent="${userAgent}"`);
128725
+ } else {
128726
+ wrapped = `${wrapped} --script-args http.useragent="${userAgent}"`;
128727
+ }
128728
+ }
128729
+ if (command.includes("gobuster") && !command.includes("-a ") && !command.includes("--useragent")) {
128730
+ wrapped = wrapped.replace(/\bgobuster\s+/, `gobuster -a "${userAgent}" `);
128731
+ }
128732
+ if (command.includes("ffuf") && !command.includes("User-Agent:")) {
128733
+ wrapped = wrapped.replace(/\bffuf\s+/, `ffuf -H "User-Agent: ${userAgent}" `);
128734
+ }
128735
+ if (command.includes("sqlmap") && !command.includes("--user-agent")) {
128736
+ wrapped = wrapped.replace(/\bsqlmap\s+/, `sqlmap --user-agent="${userAgent}" `);
128737
+ }
128738
+ if (command.includes("wfuzz") && !command.includes("-H") && !command.includes("User-Agent")) {
128739
+ wrapped = wrapped.replace(/\bwfuzz\s+/, `wfuzz -H "User-Agent: ${userAgent}" `);
128740
+ }
128741
+ if (command.includes("dirb") && !command.includes("-a")) {
128742
+ wrapped = wrapped.replace(/\bdirb\s+/, `dirb -a "${userAgent}" `);
128743
+ }
128744
+ if (command.includes("wpscan") && !command.includes("--user-agent")) {
128745
+ wrapped = wrapped.replace(/\bwpscan\s+/, `wpscan --user-agent "${userAgent}" `);
128746
+ }
128747
+ if (command.includes("nuclei") && !command.includes("-H")) {
128748
+ wrapped = wrapped.replace(/\bnuclei\s+/, `nuclei -H "User-Agent: ${userAgent}" `);
128749
+ }
128750
+ if (command.includes("httpx") && !command.includes("-H")) {
128751
+ wrapped = wrapped.replace(/\bhttpx\s+/, `httpx -H "User-Agent: ${userAgent}" `);
128752
+ }
128753
+ return wrapped;
128754
+ }
128630
128755
  function createPentestTools(session, model, toolOverride) {
128756
+ const offensiveHeaders = getOffensiveHeaders(session);
128757
+ const rateLimiter = session._rateLimiter;
128631
128758
  const executeCommand = tool({
128632
128759
  name: "execute_command",
128633
128760
  description: `Execute a shell command for penetration testing activities.
@@ -128672,6 +128799,9 @@ IMPORTANT: Always analyze results and adjust your approach based on findings.`,
128672
128799
  inputSchema: ExecuteCommandInput,
128673
128800
  execute: async ({ command, timeout = 30000, toolCallDescription }) => {
128674
128801
  try {
128802
+ if (rateLimiter) {
128803
+ await rateLimiter.acquireSlot();
128804
+ }
128675
128805
  if (toolOverride?.execute_command) {
128676
128806
  return toolOverride.execute_command({
128677
128807
  command,
@@ -128679,7 +128809,8 @@ IMPORTANT: Always analyze results and adjust your approach based on findings.`,
128679
128809
  toolCallDescription
128680
128810
  });
128681
128811
  }
128682
- const { stdout, stderr } = await execAsync3(command, {
128812
+ const finalCommand = offensiveHeaders ? wrapCommandWithHeaders(command, offensiveHeaders) : command;
128813
+ const { stdout, stderr } = await execAsync3(finalCommand, {
128683
128814
  timeout,
128684
128815
  maxBuffer: 10 * 1024 * 1024
128685
128816
  });
@@ -128689,7 +128820,7 @@ IMPORTANT: Always analyze results and adjust your approach based on findings.`,
128689
128820
 
128690
128821
  (truncated) call the command again with grep / tail to paginate the response` || "(no output)",
128691
128822
  stderr: stderr || "",
128692
- command,
128823
+ command: finalCommand,
128693
128824
  error: ""
128694
128825
  };
128695
128826
  } catch (error46) {
@@ -128727,6 +128858,9 @@ COMMON TESTING PATTERNS:
128727
128858
  inputSchema: HttpRequestInput,
128728
128859
  execute: async ({ url: url2, method, headers, body, followRedirects, timeout, toolCallDescription }) => {
128729
128860
  try {
128861
+ if (rateLimiter) {
128862
+ await rateLimiter.acquireSlot();
128863
+ }
128730
128864
  if (toolOverride?.http_request) {
128731
128865
  return toolOverride.http_request({
128732
128866
  url: url2,
@@ -128742,7 +128876,10 @@ COMMON TESTING PATTERNS:
128742
128876
  const timeoutId = setTimeout(() => controller.abort(), timeout);
128743
128877
  const response = await fetch(url2, {
128744
128878
  method,
128745
- headers: headers || {},
128879
+ headers: {
128880
+ ...offensiveHeaders || {},
128881
+ ...headers || {}
128882
+ },
128746
128883
  body: body || undefined,
128747
128884
  redirect: followRedirects ? "follow" : "manual",
128748
128885
  signal: controller.signal
@@ -128961,6 +129098,125 @@ You MUST provide the details final report using create_attack_surface_report too
128961
129098
 
128962
129099
  // src/core/messages/index.ts
128963
129100
  import fs from "fs";
129101
+
129102
+ // src/core/messages/types.ts
129103
+ var ToolMessageObject = exports_external.object({
129104
+ role: exports_external.literal("tool"),
129105
+ status: exports_external.enum(["pending", "completed"]),
129106
+ toolCallId: exports_external.string(),
129107
+ content: exports_external.string(),
129108
+ args: exports_external.record(exports_external.string(), exports_external.any()),
129109
+ toolName: exports_external.string(),
129110
+ createdAt: exports_external.coerce.date()
129111
+ });
129112
+ var SystemModelMessageObject = exports_external.object({
129113
+ role: exports_external.literal("system"),
129114
+ content: exports_external.string(),
129115
+ createdAt: exports_external.coerce.date(),
129116
+ providerOptions: exports_external.record(exports_external.string(), exports_external.any()).optional()
129117
+ });
129118
+ var TextPartObject = exports_external.object({
129119
+ type: exports_external.literal("text"),
129120
+ text: exports_external.string(),
129121
+ providerOptions: exports_external.record(exports_external.string(), exports_external.any()).optional()
129122
+ });
129123
+ var FilePartObject = exports_external.object({
129124
+ type: exports_external.literal("file"),
129125
+ data: exports_external.union([
129126
+ exports_external.string(),
129127
+ exports_external.instanceof(Uint8Array),
129128
+ exports_external.instanceof(ArrayBuffer),
129129
+ exports_external.instanceof(Buffer),
129130
+ exports_external.url()
129131
+ ]),
129132
+ filename: exports_external.string().optional(),
129133
+ mediaType: exports_external.string(),
129134
+ providerOptions: exports_external.record(exports_external.string(), exports_external.any()).optional()
129135
+ });
129136
+ var ReasoningPartObject = exports_external.object({
129137
+ type: exports_external.literal("reasoning"),
129138
+ text: exports_external.string(),
129139
+ providerOptions: exports_external.record(exports_external.string(), exports_external.any()).optional()
129140
+ });
129141
+ var ToolCallPartObject = exports_external.object({
129142
+ type: exports_external.literal("tool-call"),
129143
+ toolCallId: exports_external.string(),
129144
+ toolName: exports_external.string(),
129145
+ input: exports_external.unknown(),
129146
+ providerOptions: exports_external.record(exports_external.string(), exports_external.any()).optional(),
129147
+ providerExecuted: exports_external.boolean().optional()
129148
+ });
129149
+ var ToolResultOutputObject = exports_external.discriminatedUnion("type", [
129150
+ exports_external.object({
129151
+ type: exports_external.literal("text"),
129152
+ value: exports_external.string()
129153
+ }),
129154
+ exports_external.object({
129155
+ type: exports_external.literal("json"),
129156
+ value: exports_external.any()
129157
+ }),
129158
+ exports_external.object({
129159
+ type: exports_external.literal("error-text"),
129160
+ value: exports_external.string()
129161
+ }),
129162
+ exports_external.object({
129163
+ type: exports_external.literal("error-json"),
129164
+ value: exports_external.any()
129165
+ }),
129166
+ exports_external.object({
129167
+ type: exports_external.literal("content"),
129168
+ value: exports_external.array(exports_external.discriminatedUnion("type", [
129169
+ exports_external.object({
129170
+ type: exports_external.literal("text"),
129171
+ text: exports_external.string()
129172
+ }),
129173
+ exports_external.object({
129174
+ type: exports_external.literal("media"),
129175
+ data: exports_external.string(),
129176
+ mediaType: exports_external.string()
129177
+ })
129178
+ ]))
129179
+ })
129180
+ ]);
129181
+ var ToolResultPartObject = exports_external.object({
129182
+ type: exports_external.literal("tool-result"),
129183
+ toolCallId: exports_external.string(),
129184
+ toolName: exports_external.string(),
129185
+ output: ToolResultOutputObject,
129186
+ providerOptions: exports_external.record(exports_external.string(), exports_external.any()).optional()
129187
+ });
129188
+ var AssistantModelMessageObject = exports_external.object({
129189
+ role: exports_external.literal("assistant"),
129190
+ content: exports_external.union([
129191
+ exports_external.string(),
129192
+ exports_external.array(exports_external.discriminatedUnion("type", [
129193
+ TextPartObject,
129194
+ FilePartObject,
129195
+ ReasoningPartObject,
129196
+ ToolCallPartObject,
129197
+ ToolResultPartObject
129198
+ ]))
129199
+ ]),
129200
+ createdAt: exports_external.coerce.date(),
129201
+ providerOptions: exports_external.record(exports_external.string(), exports_external.any()).optional()
129202
+ });
129203
+ var UserModelMessageObject = exports_external.object({
129204
+ role: exports_external.literal("user"),
129205
+ content: exports_external.union([
129206
+ exports_external.string(),
129207
+ exports_external.array(exports_external.discriminatedUnion("type", [TextPartObject, FilePartObject]))
129208
+ ]),
129209
+ createdAt: exports_external.coerce.date(),
129210
+ providerOptions: exports_external.record(exports_external.string(), exports_external.any()).optional()
129211
+ });
129212
+ var ModelMessageObject = exports_external.discriminatedUnion("role", [
129213
+ SystemModelMessageObject,
129214
+ UserModelMessageObject,
129215
+ AssistantModelMessageObject,
129216
+ ToolMessageObject
129217
+ ]);
129218
+
129219
+ // src/core/messages/index.ts
128964
129220
  function saveSubagentMessages(orchestratorSession, subagentId, messages) {
128965
129221
  const subagentDir = `${orchestratorSession.rootPath}/subagents/${subagentId}`;
128966
129222
  if (!fs.existsSync(`${orchestratorSession.rootPath}/subagents`)) {
@@ -128982,12 +129238,13 @@ function runAgent3(opts) {
128982
129238
  model,
128983
129239
  onStepFinish,
128984
129240
  abortSignal,
129241
+ sessionConfig,
128985
129242
  onSubagentSpawn,
128986
129243
  onSubagentMessage,
128987
129244
  onSubagentComplete,
128988
129245
  session: sessionProp
128989
129246
  } = opts;
128990
- const session = sessionProp || createSession(target);
129247
+ const session = sessionProp || createSession(target, undefined, undefined, sessionConfig);
128991
129248
  const logger = new Logger(session);
128992
129249
  logger.log(`Created thorough pentest session: ${session.id}`);
128993
129250
  logger.log(`Session path: ${session.rootPath}`);