@pensar/apex 0.0.13 → 0.0.15

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.
@@ -43280,54 +43280,9 @@ Create this POC, test it, then retry document_finding.`,
43280
43280
  };
43281
43281
  const safeTitle = finding2.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").substring(0, 50);
43282
43282
  const findingId = `${timestamp.split("T")[0]}-${safeTitle}`;
43283
- const filename = `${findingId}.md`;
43283
+ const filename = `${findingId}.json`;
43284
43284
  const filepath = join2(session.findingsPath, filename);
43285
- const markdown = `# ${finding2.title}
43286
-
43287
- **Severity:** ${finding2.severity}
43288
- **Target:** ${session.target}
43289
- **Date:** ${timestamp}
43290
- **Session:** ${session.id}
43291
- **POC:** \`${finding2.pocPath}\`
43292
-
43293
- ## Description
43294
-
43295
- ${finding2.description}
43296
-
43297
- ## Impact
43298
-
43299
- ${finding2.impact}
43300
-
43301
- ## Evidence
43302
-
43303
- \`\`\`
43304
- ${finding2.evidence}
43305
- \`\`\`
43306
-
43307
- ## Proof of Concept
43308
-
43309
- A working POC script is available at: \`${finding2.pocPath}\`
43310
-
43311
- To reproduce this vulnerability, run:
43312
- \`\`\`bash
43313
- cd ${session.rootPath}
43314
- ./${finding2.pocPath}
43315
- \`\`\`
43316
-
43317
- ## Remediation
43318
-
43319
- ${finding2.remediation}
43320
-
43321
- ${finding2.references ? `## References
43322
-
43323
- ${finding2.references}` : ""}
43324
-
43325
- ---
43326
-
43327
- *This finding was automatically documented by the Pensar penetration testing agent.*
43328
- *POC verified and available at: ${finding2.pocPath}*
43329
- `;
43330
- writeFileSync2(filepath, markdown);
43285
+ writeFileSync2(filepath, JSON.stringify(findingWithMeta, null, 2));
43331
43286
  const summaryPath = join2(session.rootPath, "findings-summary.md");
43332
43287
  const summaryEntry = `- [${finding2.severity}] ${finding2.title} - \`findings/${filename}\` - POC: \`${finding2.pocPath}\`
43333
43288
  `;
@@ -44540,6 +44495,143 @@ function saveSubagentMessages(orchestratorSession, subagentId, messages) {
44540
44495
  fs.writeFileSync(`${subagentDir}/messages.json`, JSON.stringify(messages, null, 2));
44541
44496
  }
44542
44497
 
44498
+ // node_modules/yocto-queue/index.js
44499
+ class Node {
44500
+ value;
44501
+ next;
44502
+ constructor(value) {
44503
+ this.value = value;
44504
+ }
44505
+ }
44506
+
44507
+ class Queue {
44508
+ #head;
44509
+ #tail;
44510
+ #size;
44511
+ constructor() {
44512
+ this.clear();
44513
+ }
44514
+ enqueue(value) {
44515
+ const node = new Node(value);
44516
+ if (this.#head) {
44517
+ this.#tail.next = node;
44518
+ this.#tail = node;
44519
+ } else {
44520
+ this.#head = node;
44521
+ this.#tail = node;
44522
+ }
44523
+ this.#size++;
44524
+ }
44525
+ dequeue() {
44526
+ const current = this.#head;
44527
+ if (!current) {
44528
+ return;
44529
+ }
44530
+ this.#head = this.#head.next;
44531
+ this.#size--;
44532
+ return current.value;
44533
+ }
44534
+ peek() {
44535
+ if (!this.#head) {
44536
+ return;
44537
+ }
44538
+ return this.#head.value;
44539
+ }
44540
+ clear() {
44541
+ this.#head = undefined;
44542
+ this.#tail = undefined;
44543
+ this.#size = 0;
44544
+ }
44545
+ get size() {
44546
+ return this.#size;
44547
+ }
44548
+ *[Symbol.iterator]() {
44549
+ let current = this.#head;
44550
+ while (current) {
44551
+ yield current.value;
44552
+ current = current.next;
44553
+ }
44554
+ }
44555
+ *drain() {
44556
+ while (this.#head) {
44557
+ yield this.dequeue();
44558
+ }
44559
+ }
44560
+ }
44561
+
44562
+ // node_modules/p-limit/index.js
44563
+ function pLimit(concurrency) {
44564
+ validateConcurrency(concurrency);
44565
+ const queue = new Queue;
44566
+ let activeCount = 0;
44567
+ const resumeNext = () => {
44568
+ if (activeCount < concurrency && queue.size > 0) {
44569
+ activeCount++;
44570
+ queue.dequeue()();
44571
+ }
44572
+ };
44573
+ const next = () => {
44574
+ activeCount--;
44575
+ resumeNext();
44576
+ };
44577
+ const run = async (function_, resolve2, arguments_) => {
44578
+ const result = (async () => function_(...arguments_))();
44579
+ resolve2(result);
44580
+ try {
44581
+ await result;
44582
+ } catch {}
44583
+ next();
44584
+ };
44585
+ const enqueue = (function_, resolve2, arguments_) => {
44586
+ new Promise((internalResolve) => {
44587
+ queue.enqueue(internalResolve);
44588
+ }).then(run.bind(undefined, function_, resolve2, arguments_));
44589
+ if (activeCount < concurrency) {
44590
+ resumeNext();
44591
+ }
44592
+ };
44593
+ const generator = (function_, ...arguments_) => new Promise((resolve2) => {
44594
+ enqueue(function_, resolve2, arguments_);
44595
+ });
44596
+ Object.defineProperties(generator, {
44597
+ activeCount: {
44598
+ get: () => activeCount
44599
+ },
44600
+ pendingCount: {
44601
+ get: () => queue.size
44602
+ },
44603
+ clearQueue: {
44604
+ value() {
44605
+ queue.clear();
44606
+ }
44607
+ },
44608
+ concurrency: {
44609
+ get: () => concurrency,
44610
+ set(newConcurrency) {
44611
+ validateConcurrency(newConcurrency);
44612
+ concurrency = newConcurrency;
44613
+ queueMicrotask(() => {
44614
+ while (activeCount < concurrency && queue.size > 0) {
44615
+ resumeNext();
44616
+ }
44617
+ });
44618
+ }
44619
+ },
44620
+ map: {
44621
+ async value(iterable, function_) {
44622
+ const promises = Array.from(iterable, (value, index) => this(function_, value, index));
44623
+ return Promise.all(promises);
44624
+ }
44625
+ }
44626
+ });
44627
+ return generator;
44628
+ }
44629
+ function validateConcurrency(concurrency) {
44630
+ if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {
44631
+ throw new TypeError("Expected `concurrency` to be a number from 1 and up");
44632
+ }
44633
+ }
44634
+
44543
44635
  // src/core/agent/thoroughPentestAgent/agent.ts
44544
44636
  function runAgent3(opts) {
44545
44637
  const {
@@ -44780,7 +44872,8 @@ You can spawn multiple agents in parallel - they will run concurrently.`,
44780
44872
  execute: async ({ targets }) => {
44781
44873
  try {
44782
44874
  logger?.log(`[Orchestrator] Spawning ${targets.length} pentest agents...`);
44783
- const promises = targets.map(async (targetInfo, index) => {
44875
+ const limit = pLimit(5);
44876
+ const promises = targets.map((targetInfo, index) => limit(async () => {
44784
44877
  try {
44785
44878
  const { streamResult: result } = runAgent({
44786
44879
  session,
@@ -44900,7 +44993,7 @@ Objective: ${targetInfo.objective}`,
44900
44993
  error: error46.message
44901
44994
  };
44902
44995
  }
44903
- });
44996
+ }));
44904
44997
  const results = await Promise.all(promises);
44905
44998
  const successful = results.filter((r) => r.success).length;
44906
44999
  const failed = results.filter((r) => !r.success).length;
package/build/index.js CHANGED
@@ -73392,54 +73392,9 @@ Create this POC, test it, then retry document_finding.`,
73392
73392
  };
73393
73393
  const safeTitle = finding2.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").substring(0, 50);
73394
73394
  const findingId = `${timestamp.split("T")[0]}-${safeTitle}`;
73395
- const filename = `${findingId}.md`;
73395
+ const filename = `${findingId}.json`;
73396
73396
  const filepath = join3(session.findingsPath, filename);
73397
- const markdown = `# ${finding2.title}
73398
-
73399
- **Severity:** ${finding2.severity}
73400
- **Target:** ${session.target}
73401
- **Date:** ${timestamp}
73402
- **Session:** ${session.id}
73403
- **POC:** \`${finding2.pocPath}\`
73404
-
73405
- ## Description
73406
-
73407
- ${finding2.description}
73408
-
73409
- ## Impact
73410
-
73411
- ${finding2.impact}
73412
-
73413
- ## Evidence
73414
-
73415
- \`\`\`
73416
- ${finding2.evidence}
73417
- \`\`\`
73418
-
73419
- ## Proof of Concept
73420
-
73421
- A working POC script is available at: \`${finding2.pocPath}\`
73422
-
73423
- To reproduce this vulnerability, run:
73424
- \`\`\`bash
73425
- cd ${session.rootPath}
73426
- ./${finding2.pocPath}
73427
- \`\`\`
73428
-
73429
- ## Remediation
73430
-
73431
- ${finding2.remediation}
73432
-
73433
- ${finding2.references ? `## References
73434
-
73435
- ${finding2.references}` : ""}
73436
-
73437
- ---
73438
-
73439
- *This finding was automatically documented by the Pensar penetration testing agent.*
73440
- *POC verified and available at: ${finding2.pocPath}*
73441
- `;
73442
- writeFileSync3(filepath, markdown);
73397
+ writeFileSync3(filepath, JSON.stringify(findingWithMeta, null, 2));
73443
73398
  const summaryPath = join3(session.rootPath, "findings-summary.md");
73444
73399
  const summaryEntry = `- [${finding2.severity}] ${finding2.title} - \`findings/${filename}\` - POC: \`${finding2.pocPath}\`
73445
73400
  `;
@@ -77546,6 +77501,143 @@ You MUST provide the details final report using create_attack_surface_report too
77546
77501
  return { streamResult, session };
77547
77502
  }
77548
77503
 
77504
+ // node_modules/yocto-queue/index.js
77505
+ class Node {
77506
+ value;
77507
+ next;
77508
+ constructor(value) {
77509
+ this.value = value;
77510
+ }
77511
+ }
77512
+
77513
+ class Queue {
77514
+ #head;
77515
+ #tail;
77516
+ #size;
77517
+ constructor() {
77518
+ this.clear();
77519
+ }
77520
+ enqueue(value) {
77521
+ const node = new Node(value);
77522
+ if (this.#head) {
77523
+ this.#tail.next = node;
77524
+ this.#tail = node;
77525
+ } else {
77526
+ this.#head = node;
77527
+ this.#tail = node;
77528
+ }
77529
+ this.#size++;
77530
+ }
77531
+ dequeue() {
77532
+ const current = this.#head;
77533
+ if (!current) {
77534
+ return;
77535
+ }
77536
+ this.#head = this.#head.next;
77537
+ this.#size--;
77538
+ return current.value;
77539
+ }
77540
+ peek() {
77541
+ if (!this.#head) {
77542
+ return;
77543
+ }
77544
+ return this.#head.value;
77545
+ }
77546
+ clear() {
77547
+ this.#head = undefined;
77548
+ this.#tail = undefined;
77549
+ this.#size = 0;
77550
+ }
77551
+ get size() {
77552
+ return this.#size;
77553
+ }
77554
+ *[Symbol.iterator]() {
77555
+ let current = this.#head;
77556
+ while (current) {
77557
+ yield current.value;
77558
+ current = current.next;
77559
+ }
77560
+ }
77561
+ *drain() {
77562
+ while (this.#head) {
77563
+ yield this.dequeue();
77564
+ }
77565
+ }
77566
+ }
77567
+
77568
+ // node_modules/p-limit/index.js
77569
+ function pLimit(concurrency) {
77570
+ validateConcurrency(concurrency);
77571
+ const queue = new Queue;
77572
+ let activeCount = 0;
77573
+ const resumeNext = () => {
77574
+ if (activeCount < concurrency && queue.size > 0) {
77575
+ activeCount++;
77576
+ queue.dequeue()();
77577
+ }
77578
+ };
77579
+ const next = () => {
77580
+ activeCount--;
77581
+ resumeNext();
77582
+ };
77583
+ const run = async (function_, resolve4, arguments_) => {
77584
+ const result = (async () => function_(...arguments_))();
77585
+ resolve4(result);
77586
+ try {
77587
+ await result;
77588
+ } catch {}
77589
+ next();
77590
+ };
77591
+ const enqueue = (function_, resolve4, arguments_) => {
77592
+ new Promise((internalResolve) => {
77593
+ queue.enqueue(internalResolve);
77594
+ }).then(run.bind(undefined, function_, resolve4, arguments_));
77595
+ if (activeCount < concurrency) {
77596
+ resumeNext();
77597
+ }
77598
+ };
77599
+ const generator = (function_, ...arguments_) => new Promise((resolve4) => {
77600
+ enqueue(function_, resolve4, arguments_);
77601
+ });
77602
+ Object.defineProperties(generator, {
77603
+ activeCount: {
77604
+ get: () => activeCount
77605
+ },
77606
+ pendingCount: {
77607
+ get: () => queue.size
77608
+ },
77609
+ clearQueue: {
77610
+ value() {
77611
+ queue.clear();
77612
+ }
77613
+ },
77614
+ concurrency: {
77615
+ get: () => concurrency,
77616
+ set(newConcurrency) {
77617
+ validateConcurrency(newConcurrency);
77618
+ concurrency = newConcurrency;
77619
+ queueMicrotask(() => {
77620
+ while (activeCount < concurrency && queue.size > 0) {
77621
+ resumeNext();
77622
+ }
77623
+ });
77624
+ }
77625
+ },
77626
+ map: {
77627
+ async value(iterable, function_) {
77628
+ const promises = Array.from(iterable, (value, index) => this(function_, value, index));
77629
+ return Promise.all(promises);
77630
+ }
77631
+ }
77632
+ });
77633
+ return generator;
77634
+ }
77635
+ function validateConcurrency(concurrency) {
77636
+ if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {
77637
+ throw new TypeError("Expected `concurrency` to be a number from 1 and up");
77638
+ }
77639
+ }
77640
+
77549
77641
  // src/core/agent/thoroughPentestAgent/agent.ts
77550
77642
  function runAgent3(opts) {
77551
77643
  const {
@@ -77786,7 +77878,8 @@ You can spawn multiple agents in parallel - they will run concurrently.`,
77786
77878
  execute: async ({ targets }) => {
77787
77879
  try {
77788
77880
  logger?.log(`[Orchestrator] Spawning ${targets.length} pentest agents...`);
77789
- const promises = targets.map(async (targetInfo, index) => {
77881
+ const limit = pLimit(5);
77882
+ const promises = targets.map((targetInfo, index) => limit(async () => {
77790
77883
  try {
77791
77884
  const { streamResult: result } = runAgent({
77792
77885
  session,
@@ -77906,7 +77999,7 @@ Objective: ${targetInfo.objective}`,
77906
77999
  error: error46.message
77907
78000
  };
77908
78001
  }
77909
- });
78002
+ }));
77910
78003
  const results = await Promise.all(promises);
77911
78004
  const successful = results.filter((r) => r.success).length;
77912
78005
  const failed = results.filter((r) => !r.success).length;
@@ -42026,54 +42026,9 @@ Create this POC, test it, then retry document_finding.`,
42026
42026
  };
42027
42027
  const safeTitle = finding2.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").substring(0, 50);
42028
42028
  const findingId = `${timestamp.split("T")[0]}-${safeTitle}`;
42029
- const filename = `${findingId}.md`;
42029
+ const filename = `${findingId}.json`;
42030
42030
  const filepath = join3(session.findingsPath, filename);
42031
- const markdown = `# ${finding2.title}
42032
-
42033
- **Severity:** ${finding2.severity}
42034
- **Target:** ${session.target}
42035
- **Date:** ${timestamp}
42036
- **Session:** ${session.id}
42037
- **POC:** \`${finding2.pocPath}\`
42038
-
42039
- ## Description
42040
-
42041
- ${finding2.description}
42042
-
42043
- ## Impact
42044
-
42045
- ${finding2.impact}
42046
-
42047
- ## Evidence
42048
-
42049
- \`\`\`
42050
- ${finding2.evidence}
42051
- \`\`\`
42052
-
42053
- ## Proof of Concept
42054
-
42055
- A working POC script is available at: \`${finding2.pocPath}\`
42056
-
42057
- To reproduce this vulnerability, run:
42058
- \`\`\`bash
42059
- cd ${session.rootPath}
42060
- ./${finding2.pocPath}
42061
- \`\`\`
42062
-
42063
- ## Remediation
42064
-
42065
- ${finding2.remediation}
42066
-
42067
- ${finding2.references ? `## References
42068
-
42069
- ${finding2.references}` : ""}
42070
-
42071
- ---
42072
-
42073
- *This finding was automatically documented by the Pensar penetration testing agent.*
42074
- *POC verified and available at: ${finding2.pocPath}*
42075
- `;
42076
- writeFileSync3(filepath, markdown);
42031
+ writeFileSync3(filepath, JSON.stringify(findingWithMeta, null, 2));
42077
42032
  const summaryPath = join3(session.rootPath, "findings-summary.md");
42078
42033
  const summaryEntry = `- [${finding2.severity}] ${finding2.title} - \`findings/${filename}\` - POC: \`${finding2.pocPath}\`
42079
42034
  `;
package/build/swarm.js CHANGED
@@ -42026,54 +42026,9 @@ Create this POC, test it, then retry document_finding.`,
42026
42026
  };
42027
42027
  const safeTitle = finding2.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").substring(0, 50);
42028
42028
  const findingId = `${timestamp.split("T")[0]}-${safeTitle}`;
42029
- const filename = `${findingId}.md`;
42029
+ const filename = `${findingId}.json`;
42030
42030
  const filepath = join3(session.findingsPath, filename);
42031
- const markdown = `# ${finding2.title}
42032
-
42033
- **Severity:** ${finding2.severity}
42034
- **Target:** ${session.target}
42035
- **Date:** ${timestamp}
42036
- **Session:** ${session.id}
42037
- **POC:** \`${finding2.pocPath}\`
42038
-
42039
- ## Description
42040
-
42041
- ${finding2.description}
42042
-
42043
- ## Impact
42044
-
42045
- ${finding2.impact}
42046
-
42047
- ## Evidence
42048
-
42049
- \`\`\`
42050
- ${finding2.evidence}
42051
- \`\`\`
42052
-
42053
- ## Proof of Concept
42054
-
42055
- A working POC script is available at: \`${finding2.pocPath}\`
42056
-
42057
- To reproduce this vulnerability, run:
42058
- \`\`\`bash
42059
- cd ${session.rootPath}
42060
- ./${finding2.pocPath}
42061
- \`\`\`
42062
-
42063
- ## Remediation
42064
-
42065
- ${finding2.remediation}
42066
-
42067
- ${finding2.references ? `## References
42068
-
42069
- ${finding2.references}` : ""}
42070
-
42071
- ---
42072
-
42073
- *This finding was automatically documented by the Pensar penetration testing agent.*
42074
- *POC verified and available at: ${finding2.pocPath}*
42075
- `;
42076
- writeFileSync3(filepath, markdown);
42031
+ writeFileSync3(filepath, JSON.stringify(findingWithMeta, null, 2));
42077
42032
  const summaryPath = join3(session.rootPath, "findings-summary.md");
42078
42033
  const summaryEntry = `- [${finding2.severity}] ${finding2.title} - \`findings/${filename}\` - POC: \`${finding2.pocPath}\`
42079
42034
  `;
@@ -42435,6 +42390,145 @@ Remember to follow a systematic methodology and explain your reasoning for each
42435
42390
  }
42436
42391
  // scripts/swarm.ts
42437
42392
  import { readFileSync as readFileSync4 } from "fs";
42393
+
42394
+ // node_modules/yocto-queue/index.js
42395
+ class Node {
42396
+ value;
42397
+ next;
42398
+ constructor(value) {
42399
+ this.value = value;
42400
+ }
42401
+ }
42402
+
42403
+ class Queue {
42404
+ #head;
42405
+ #tail;
42406
+ #size;
42407
+ constructor() {
42408
+ this.clear();
42409
+ }
42410
+ enqueue(value) {
42411
+ const node = new Node(value);
42412
+ if (this.#head) {
42413
+ this.#tail.next = node;
42414
+ this.#tail = node;
42415
+ } else {
42416
+ this.#head = node;
42417
+ this.#tail = node;
42418
+ }
42419
+ this.#size++;
42420
+ }
42421
+ dequeue() {
42422
+ const current = this.#head;
42423
+ if (!current) {
42424
+ return;
42425
+ }
42426
+ this.#head = this.#head.next;
42427
+ this.#size--;
42428
+ return current.value;
42429
+ }
42430
+ peek() {
42431
+ if (!this.#head) {
42432
+ return;
42433
+ }
42434
+ return this.#head.value;
42435
+ }
42436
+ clear() {
42437
+ this.#head = undefined;
42438
+ this.#tail = undefined;
42439
+ this.#size = 0;
42440
+ }
42441
+ get size() {
42442
+ return this.#size;
42443
+ }
42444
+ *[Symbol.iterator]() {
42445
+ let current = this.#head;
42446
+ while (current) {
42447
+ yield current.value;
42448
+ current = current.next;
42449
+ }
42450
+ }
42451
+ *drain() {
42452
+ while (this.#head) {
42453
+ yield this.dequeue();
42454
+ }
42455
+ }
42456
+ }
42457
+
42458
+ // node_modules/p-limit/index.js
42459
+ function pLimit(concurrency) {
42460
+ validateConcurrency(concurrency);
42461
+ const queue = new Queue;
42462
+ let activeCount = 0;
42463
+ const resumeNext = () => {
42464
+ if (activeCount < concurrency && queue.size > 0) {
42465
+ activeCount++;
42466
+ queue.dequeue()();
42467
+ }
42468
+ };
42469
+ const next = () => {
42470
+ activeCount--;
42471
+ resumeNext();
42472
+ };
42473
+ const run = async (function_, resolve2, arguments_) => {
42474
+ const result = (async () => function_(...arguments_))();
42475
+ resolve2(result);
42476
+ try {
42477
+ await result;
42478
+ } catch {}
42479
+ next();
42480
+ };
42481
+ const enqueue = (function_, resolve2, arguments_) => {
42482
+ new Promise((internalResolve) => {
42483
+ queue.enqueue(internalResolve);
42484
+ }).then(run.bind(undefined, function_, resolve2, arguments_));
42485
+ if (activeCount < concurrency) {
42486
+ resumeNext();
42487
+ }
42488
+ };
42489
+ const generator = (function_, ...arguments_) => new Promise((resolve2) => {
42490
+ enqueue(function_, resolve2, arguments_);
42491
+ });
42492
+ Object.defineProperties(generator, {
42493
+ activeCount: {
42494
+ get: () => activeCount
42495
+ },
42496
+ pendingCount: {
42497
+ get: () => queue.size
42498
+ },
42499
+ clearQueue: {
42500
+ value() {
42501
+ queue.clear();
42502
+ }
42503
+ },
42504
+ concurrency: {
42505
+ get: () => concurrency,
42506
+ set(newConcurrency) {
42507
+ validateConcurrency(newConcurrency);
42508
+ concurrency = newConcurrency;
42509
+ queueMicrotask(() => {
42510
+ while (activeCount < concurrency && queue.size > 0) {
42511
+ resumeNext();
42512
+ }
42513
+ });
42514
+ }
42515
+ },
42516
+ map: {
42517
+ async value(iterable, function_) {
42518
+ const promises = Array.from(iterable, (value, index) => this(function_, value, index));
42519
+ return Promise.all(promises);
42520
+ }
42521
+ }
42522
+ });
42523
+ return generator;
42524
+ }
42525
+ function validateConcurrency(concurrency) {
42526
+ if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {
42527
+ throw new TypeError("Expected `concurrency` to be a number from 1 and up");
42528
+ }
42529
+ }
42530
+
42531
+ // scripts/swarm.ts
42438
42532
  var TargetSchema = exports_external.array(exports_external.object({
42439
42533
  target: exports_external.string().describe("The target to perform a pentest on"),
42440
42534
  objective: exports_external.string().describe("The objective of the pentest")
@@ -42478,7 +42572,8 @@ async function swarm(options) {
42478
42572
  }
42479
42573
  const session = createSession("swarm", "Multi-target swarm pentest");
42480
42574
  const results = [];
42481
- const promises = targetsArray.map(async (target, idx) => {
42575
+ const limit = pLimit(5);
42576
+ const promises = targetsArray.map((target, idx) => limit(async () => {
42482
42577
  if (!silent) {
42483
42578
  console.log("=".repeat(80));
42484
42579
  console.log(`[${idx + 1}/${targetsArray.length}] Starting pentest for: ${target.target}`);
@@ -42518,8 +42613,8 @@ async function swarm(options) {
42518
42613
  error: error46.message
42519
42614
  });
42520
42615
  }
42521
- });
42522
- await Promise.all(promises);
42616
+ }));
42617
+ await Promise.allSettled(promises);
42523
42618
  if (!silent) {
42524
42619
  console.log("=".repeat(80));
42525
42620
  console.log("SWARM PENTEST SUMMARY");
@@ -42616,7 +42711,9 @@ async function main() {
42616
42711
  objective: session.objective
42617
42712
  }, null, 2));
42618
42713
  } catch (error46) {
42619
- console.error("Fatal error:", error46.message);
42714
+ if (!silent) {
42715
+ console.error("Fatal error:", error46.message);
42716
+ }
42620
42717
  process.exit(1);
42621
42718
  }
42622
42719
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pensar/apex",
3
- "version": "0.0.13",
3
+ "version": "0.0.15",
4
4
  "description": "AI-powered penetration testing CLI tool with terminal UI",
5
5
  "module": "src/tui/index.tsx",
6
6
  "main": "build/index.js",
@@ -59,6 +59,7 @@
59
59
  "@opentui/react": "0.1.26",
60
60
  "ai": "^5.0.68",
61
61
  "marked": "^16.4.0",
62
+ "p-limit": "^7.2.0",
62
63
  "react": "^19.2.0",
63
64
  "sharp": "^0.34.4",
64
65
  "zod": "^4.1.12"