@pensar/apex 0.0.90 → 0.0.91-canary.53063f8d
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/build/index.js +673 -533
- package/package.json +1 -1
package/build/index.js
CHANGED
|
@@ -31971,7 +31971,7 @@ var package_default2;
|
|
|
31971
31971
|
var init_package = __esm(() => {
|
|
31972
31972
|
package_default2 = {
|
|
31973
31973
|
name: "@pensar/apex",
|
|
31974
|
-
version: "0.0.
|
|
31974
|
+
version: "0.0.91-canary.53063f8d",
|
|
31975
31975
|
description: "AI-powered penetration testing CLI tool with terminal UI",
|
|
31976
31976
|
module: "src/tui/index.tsx",
|
|
31977
31977
|
main: "build/index.js",
|
|
@@ -89342,10 +89342,21 @@ var init_session = __esm(() => {
|
|
|
89342
89342
|
};
|
|
89343
89343
|
});
|
|
89344
89344
|
|
|
89345
|
+
// src/lib/cwe/types.ts
|
|
89346
|
+
var CweEntrySchema;
|
|
89347
|
+
var init_types2 = __esm(() => {
|
|
89348
|
+
init_zod();
|
|
89349
|
+
CweEntrySchema = exports_external.object({
|
|
89350
|
+
id: exports_external.string().regex(/^CWE-\d+$/, "Must be CWE-<number> format"),
|
|
89351
|
+
reasoning: exports_external.string().describe("Why this CWE applies to the observed vulnerability")
|
|
89352
|
+
});
|
|
89353
|
+
});
|
|
89354
|
+
|
|
89345
89355
|
// src/core/report/schemas.ts
|
|
89346
89356
|
var PentestReportFindingSchema, PentestReportSchema, REPORT_VERSION = "1.0";
|
|
89347
89357
|
var init_schemas3 = __esm(() => {
|
|
89348
89358
|
init_zod();
|
|
89359
|
+
init_types2();
|
|
89349
89360
|
PentestReportFindingSchema = exports_external.object({
|
|
89350
89361
|
title: exports_external.string(),
|
|
89351
89362
|
severity: exports_external.enum(["CRITICAL", "HIGH", "MEDIUM", "LOW"]),
|
|
@@ -89355,7 +89366,8 @@ var init_schemas3 = __esm(() => {
|
|
|
89355
89366
|
endpoint: exports_external.string(),
|
|
89356
89367
|
pocPath: exports_external.string(),
|
|
89357
89368
|
remediation: exports_external.string(),
|
|
89358
|
-
references: exports_external.string().optional()
|
|
89369
|
+
references: exports_external.string().optional(),
|
|
89370
|
+
cwes: exports_external.array(CweEntrySchema).optional()
|
|
89359
89371
|
});
|
|
89360
89372
|
PentestReportSchema = exports_external.object({
|
|
89361
89373
|
version: exports_external.string().regex(/^1\.\d+$/),
|
|
@@ -89469,6 +89481,12 @@ function renderFinding(finding, metadata) {
|
|
|
89469
89481
|
finding.evidence,
|
|
89470
89482
|
"```",
|
|
89471
89483
|
"",
|
|
89484
|
+
...finding.cwes?.length ? [
|
|
89485
|
+
"## CWE Classification",
|
|
89486
|
+
"",
|
|
89487
|
+
...finding.cwes.map((cwe) => `- **${cwe.id}** — ${cwe.reasoning}`),
|
|
89488
|
+
""
|
|
89489
|
+
] : [],
|
|
89472
89490
|
"## POC",
|
|
89473
89491
|
"",
|
|
89474
89492
|
`Path: \`${finding.pocPath}\``,
|
|
@@ -89508,44 +89526,22 @@ import {
|
|
|
89508
89526
|
readdirSync as readdirSync2
|
|
89509
89527
|
} from "fs";
|
|
89510
89528
|
import { join as join4 } from "path";
|
|
89511
|
-
function
|
|
89512
|
-
const
|
|
89513
|
-
if (
|
|
89514
|
-
return
|
|
89515
|
-
|
|
89516
|
-
|
|
89517
|
-
|
|
89518
|
-
|
|
89519
|
-
|
|
89520
|
-
type: "tool-call",
|
|
89521
|
-
toolCallId: part.toolCallId,
|
|
89522
|
-
toolName: part.toolName,
|
|
89523
|
-
input: part.args ?? part.input
|
|
89524
|
-
};
|
|
89525
|
-
}
|
|
89526
|
-
if (part.type === "tool-result") {
|
|
89527
|
-
return {
|
|
89528
|
-
type: "tool-result",
|
|
89529
|
-
toolCallId: part.toolCallId,
|
|
89530
|
-
toolName: part.toolName,
|
|
89531
|
-
output: part.result ?? part.output
|
|
89532
|
-
};
|
|
89533
|
-
}
|
|
89534
|
-
return {
|
|
89535
|
-
type: "text",
|
|
89536
|
-
text: part.text ?? ""
|
|
89537
|
-
};
|
|
89538
|
-
});
|
|
89539
|
-
return { role: m2.role, content: mapped };
|
|
89529
|
+
function loadSubagentMessages(session, agentName) {
|
|
89530
|
+
const filePath = join4(session.rootPath, SUBAGENTS_DIR, `${agentName}.json`);
|
|
89531
|
+
if (!existsSync8(filePath))
|
|
89532
|
+
return [];
|
|
89533
|
+
try {
|
|
89534
|
+
const data = JSON.parse(readFileSync3(filePath, "utf-8"));
|
|
89535
|
+
return data.messages;
|
|
89536
|
+
} catch {
|
|
89537
|
+
return [];
|
|
89540
89538
|
}
|
|
89541
|
-
return { role: m2.role, content: String(m2.content) };
|
|
89542
89539
|
}
|
|
89543
89540
|
function saveSubagentData(session, data) {
|
|
89544
89541
|
const subagentsDir = join4(session.rootPath, SUBAGENTS_DIR);
|
|
89545
89542
|
mkdirSync2(subagentsDir, { recursive: true });
|
|
89546
89543
|
let toolCallCount = 0;
|
|
89547
89544
|
let stepCount = 0;
|
|
89548
|
-
const savedMessages = [];
|
|
89549
89545
|
for (const msg of data.messages) {
|
|
89550
89546
|
if (msg.role === "assistant") {
|
|
89551
89547
|
stepCount++;
|
|
@@ -89556,12 +89552,10 @@ function saveSubagentData(session, data) {
|
|
|
89556
89552
|
}
|
|
89557
89553
|
}
|
|
89558
89554
|
}
|
|
89559
|
-
savedMessages.push(mapToSavedMessage(msg));
|
|
89560
89555
|
}
|
|
89561
|
-
const now2 = new Date;
|
|
89562
89556
|
const savedData = {
|
|
89563
89557
|
agentName: data.agentName,
|
|
89564
|
-
timestamp:
|
|
89558
|
+
timestamp: new Date().toISOString(),
|
|
89565
89559
|
target: data.target,
|
|
89566
89560
|
objective: data.objective,
|
|
89567
89561
|
vulnerabilityClass: data.vulnerabilityClass,
|
|
@@ -89570,16 +89564,24 @@ function saveSubagentData(session, data) {
|
|
|
89570
89564
|
findingsCount: data.findingsCount ?? 0,
|
|
89571
89565
|
status: data.status,
|
|
89572
89566
|
error: data.error,
|
|
89573
|
-
messages:
|
|
89567
|
+
messages: data.messages
|
|
89574
89568
|
};
|
|
89575
|
-
|
|
89576
|
-
const filename = `${data.agentName}-${ts}.json`;
|
|
89577
|
-
writeFileSync2(join4(subagentsDir, filename), JSON.stringify(savedData, null, 2));
|
|
89569
|
+
writeFileSync2(join4(subagentsDir, `${data.agentName}.json`), JSON.stringify(savedData, null, 2));
|
|
89578
89570
|
}
|
|
89579
89571
|
function writeAgentManifest(session, entries2) {
|
|
89580
89572
|
const manifestPath = join4(session.rootPath, MANIFEST_FILE);
|
|
89581
89573
|
writeFileSync2(manifestPath, JSON.stringify(entries2, null, 2));
|
|
89582
89574
|
}
|
|
89575
|
+
function readAgentManifest(session) {
|
|
89576
|
+
const manifestPath = join4(session.rootPath, MANIFEST_FILE);
|
|
89577
|
+
if (!existsSync8(manifestPath))
|
|
89578
|
+
return [];
|
|
89579
|
+
try {
|
|
89580
|
+
return JSON.parse(readFileSync3(manifestPath, "utf-8"));
|
|
89581
|
+
} catch {
|
|
89582
|
+
return [];
|
|
89583
|
+
}
|
|
89584
|
+
}
|
|
89583
89585
|
function buildManifestEntries(targets) {
|
|
89584
89586
|
return targets.map((t2, i) => ({
|
|
89585
89587
|
id: `pentest-agent-${i + 1}`,
|
|
@@ -89592,18 +89594,31 @@ function buildManifestEntries(targets) {
|
|
|
89592
89594
|
}));
|
|
89593
89595
|
}
|
|
89594
89596
|
function finalizeManifest(session, entries2, results) {
|
|
89595
|
-
const finalManifest = entries2.map((entry, i) =>
|
|
89596
|
-
|
|
89597
|
-
|
|
89598
|
-
|
|
89599
|
-
|
|
89597
|
+
const finalManifest = entries2.map((entry, i) => {
|
|
89598
|
+
if (entry.status === "completed")
|
|
89599
|
+
return entry;
|
|
89600
|
+
return {
|
|
89601
|
+
...entry,
|
|
89602
|
+
status: results[i] != null ? "completed" : "failed",
|
|
89603
|
+
completedAt: new Date().toISOString()
|
|
89604
|
+
};
|
|
89605
|
+
});
|
|
89600
89606
|
writeAgentManifest(session, finalManifest);
|
|
89601
89607
|
}
|
|
89608
|
+
function updateManifestEntryStatus(session, agentId, status) {
|
|
89609
|
+
const manifest = readAgentManifest(session);
|
|
89610
|
+
const updated = manifest.map((e) => e.id === agentId ? { ...e, status, completedAt: new Date().toISOString() } : e);
|
|
89611
|
+
writeAgentManifest(session, updated);
|
|
89612
|
+
}
|
|
89613
|
+
function getCompletedAgentIds(session) {
|
|
89614
|
+
const manifest = readAgentManifest(session);
|
|
89615
|
+
return new Set(manifest.filter((e) => e.id.startsWith("pentest-agent-") && e.status === "completed").map((e) => e.id));
|
|
89616
|
+
}
|
|
89602
89617
|
function parseSubagentFilename(filename) {
|
|
89603
89618
|
if (filename.startsWith("attack-surface-agent")) {
|
|
89604
89619
|
return { agentType: "attack-surface", name: "Attack Surface Discovery" };
|
|
89605
89620
|
}
|
|
89606
|
-
const pentestMatch = filename.match(/^pentest-agent-(\d+)
|
|
89621
|
+
const pentestMatch = filename.match(/^pentest-agent-(\d+)/);
|
|
89607
89622
|
if (pentestMatch) {
|
|
89608
89623
|
return {
|
|
89609
89624
|
agentType: "pentest",
|
|
@@ -89655,7 +89670,8 @@ function convertMessagesToUI(messages, baseTime) {
|
|
|
89655
89670
|
createdAt
|
|
89656
89671
|
});
|
|
89657
89672
|
} else if (part.type === "tool-call") {
|
|
89658
|
-
const
|
|
89673
|
+
const input = part.input;
|
|
89674
|
+
const toolDescription = typeof input?.toolCallDescription === "string" ? input.toolCallDescription : part.toolName || "tool";
|
|
89659
89675
|
const result = part.toolCallId ? toolResults.get(part.toolCallId) : undefined;
|
|
89660
89676
|
uiMessages.push({
|
|
89661
89677
|
role: "tool",
|
|
@@ -89663,7 +89679,7 @@ function convertMessagesToUI(messages, baseTime) {
|
|
|
89663
89679
|
createdAt,
|
|
89664
89680
|
toolCallId: part.toolCallId,
|
|
89665
89681
|
toolName: part.toolName,
|
|
89666
|
-
args:
|
|
89682
|
+
args: input,
|
|
89667
89683
|
result,
|
|
89668
89684
|
status: "completed"
|
|
89669
89685
|
});
|
|
@@ -89674,8 +89690,7 @@ function convertMessagesToUI(messages, baseTime) {
|
|
|
89674
89690
|
return uiMessages;
|
|
89675
89691
|
}
|
|
89676
89692
|
function convertModelMessagesToUI(messages) {
|
|
89677
|
-
|
|
89678
|
-
return convertMessagesToUI(saved, new Date);
|
|
89693
|
+
return convertMessagesToUI(messages, new Date);
|
|
89679
89694
|
}
|
|
89680
89695
|
function loadSubagents(rootPath) {
|
|
89681
89696
|
const subagentsPath = join4(rootPath, SUBAGENTS_DIR);
|
|
@@ -89683,11 +89698,7 @@ function loadSubagents(rootPath) {
|
|
|
89683
89698
|
const agentNameIndex = new Map;
|
|
89684
89699
|
if (existsSync8(subagentsPath)) {
|
|
89685
89700
|
const files = readdirSync2(subagentsPath).filter((f) => f.endsWith(".json"));
|
|
89686
|
-
files.sort(
|
|
89687
|
-
const timeA = a.match(/\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}/)?.[0] || "";
|
|
89688
|
-
const timeB = b2.match(/\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}/)?.[0] || "";
|
|
89689
|
-
return timeA.localeCompare(timeB);
|
|
89690
|
-
});
|
|
89701
|
+
files.sort();
|
|
89691
89702
|
for (const file2 of files) {
|
|
89692
89703
|
if (file2.startsWith("orchestrator-"))
|
|
89693
89704
|
continue;
|
|
@@ -89711,9 +89722,9 @@ function loadSubagents(rootPath) {
|
|
|
89711
89722
|
}
|
|
89712
89723
|
break;
|
|
89713
89724
|
}
|
|
89714
|
-
|
|
89725
|
+
agentNameIndex.set(data.agentName, subagents.length);
|
|
89715
89726
|
subagents.push({
|
|
89716
|
-
id:
|
|
89727
|
+
id: data.agentName,
|
|
89717
89728
|
name: data.agentName === "attack-surface-agent" ? "Attack Surface Discovery" : name26,
|
|
89718
89729
|
type: agentType,
|
|
89719
89730
|
target: data.target || "Unknown",
|
|
@@ -89721,7 +89732,6 @@ function loadSubagents(rootPath) {
|
|
|
89721
89732
|
createdAt: timestamp,
|
|
89722
89733
|
status
|
|
89723
89734
|
});
|
|
89724
|
-
agentNameIndex.set(data.agentName, idx);
|
|
89725
89735
|
} catch (e) {
|
|
89726
89736
|
console.error(`Failed to load subagent file ${file2}:`, e);
|
|
89727
89737
|
}
|
|
@@ -89769,6 +89779,116 @@ function loadSubagents(rootPath) {
|
|
|
89769
89779
|
var SUBAGENTS_DIR = "subagents", MANIFEST_FILE = "agent-manifest.json";
|
|
89770
89780
|
var init_persistence = () => {};
|
|
89771
89781
|
|
|
89782
|
+
// src/core/session/loader.ts
|
|
89783
|
+
import { join as join5 } from "path";
|
|
89784
|
+
import { existsSync as existsSync9, readFileSync as readFileSync4 } from "fs";
|
|
89785
|
+
function loadAttackSurfaceResults(rootPath) {
|
|
89786
|
+
const resultsPath = join5(rootPath, "attack-surface-results.json");
|
|
89787
|
+
if (!existsSync9(resultsPath)) {
|
|
89788
|
+
return null;
|
|
89789
|
+
}
|
|
89790
|
+
try {
|
|
89791
|
+
return JSON.parse(readFileSync4(resultsPath, "utf-8"));
|
|
89792
|
+
} catch (e) {
|
|
89793
|
+
console.error("Failed to load attack surface results:", e);
|
|
89794
|
+
return null;
|
|
89795
|
+
}
|
|
89796
|
+
}
|
|
89797
|
+
function hasReport(rootPath) {
|
|
89798
|
+
const reportPath = join5(rootPath, REPORT_FILENAME_MD);
|
|
89799
|
+
return existsSync9(reportPath);
|
|
89800
|
+
}
|
|
89801
|
+
function createDiscoveryFromLogs(rootPath, session) {
|
|
89802
|
+
const logPath = join5(rootPath, "logs", "streamlined-pentest.log");
|
|
89803
|
+
if (!existsSync9(logPath)) {
|
|
89804
|
+
return null;
|
|
89805
|
+
}
|
|
89806
|
+
try {
|
|
89807
|
+
const logContent = readFileSync4(logPath, "utf-8");
|
|
89808
|
+
const lines = logContent.split(`
|
|
89809
|
+
`).filter(Boolean);
|
|
89810
|
+
const messages = [];
|
|
89811
|
+
for (const line of lines) {
|
|
89812
|
+
const match = line.match(/^(\d{4}-\d{2}-\d{2}T[\d:.]+Z) - \[(\w+)\] (.+)$/);
|
|
89813
|
+
if (!match)
|
|
89814
|
+
continue;
|
|
89815
|
+
const [, timestamp, _level, content] = match;
|
|
89816
|
+
const createdAt = new Date(timestamp);
|
|
89817
|
+
if (content.startsWith("[Tool]")) {
|
|
89818
|
+
const toolMatch = content.match(/\[Tool\] (\w+): (.+)/);
|
|
89819
|
+
if (toolMatch) {
|
|
89820
|
+
messages.push({
|
|
89821
|
+
role: "tool",
|
|
89822
|
+
content: `✓ ${toolMatch[2]}`,
|
|
89823
|
+
createdAt,
|
|
89824
|
+
toolName: toolMatch[1],
|
|
89825
|
+
status: "completed"
|
|
89826
|
+
});
|
|
89827
|
+
}
|
|
89828
|
+
} else if (content.startsWith("[Step")) {
|
|
89829
|
+
const stepMatch = content.match(/\[Step \d+\] (.+)/);
|
|
89830
|
+
if (stepMatch) {
|
|
89831
|
+
messages.push({
|
|
89832
|
+
role: "assistant",
|
|
89833
|
+
content: stepMatch[1],
|
|
89834
|
+
createdAt
|
|
89835
|
+
});
|
|
89836
|
+
}
|
|
89837
|
+
}
|
|
89838
|
+
}
|
|
89839
|
+
if (messages.length === 0) {
|
|
89840
|
+
return null;
|
|
89841
|
+
}
|
|
89842
|
+
return {
|
|
89843
|
+
id: "discovery-from-logs",
|
|
89844
|
+
name: "Attack Surface Discovery",
|
|
89845
|
+
type: "attack-surface",
|
|
89846
|
+
target: session.targets[0] || "Unknown",
|
|
89847
|
+
messages,
|
|
89848
|
+
createdAt: new Date(session.time.created),
|
|
89849
|
+
status: "completed"
|
|
89850
|
+
};
|
|
89851
|
+
} catch (e) {
|
|
89852
|
+
console.error("Failed to parse logs:", e);
|
|
89853
|
+
return null;
|
|
89854
|
+
}
|
|
89855
|
+
}
|
|
89856
|
+
async function loadSessionState(session) {
|
|
89857
|
+
const rootPath = session.rootPath;
|
|
89858
|
+
let subagents = loadSubagents(rootPath);
|
|
89859
|
+
const hasAttackSurfaceAgent = subagents.some((s) => s.type === "attack-surface");
|
|
89860
|
+
if (!hasAttackSurfaceAgent) {
|
|
89861
|
+
const discoveryAgent = createDiscoveryFromLogs(rootPath, session);
|
|
89862
|
+
if (discoveryAgent) {
|
|
89863
|
+
subagents = [discoveryAgent, ...subagents];
|
|
89864
|
+
}
|
|
89865
|
+
}
|
|
89866
|
+
const attackSurfaceResults = loadAttackSurfaceResults(rootPath);
|
|
89867
|
+
const hasReportFile = hasReport(rootPath);
|
|
89868
|
+
const hasDiscoverySubagent = subagents.some((s) => s.type === "attack-surface");
|
|
89869
|
+
const interruptedDuringDiscovery = !attackSurfaceResults && !hasReportFile && hasDiscoverySubagent;
|
|
89870
|
+
if (interruptedDuringDiscovery) {
|
|
89871
|
+
for (let i = 0;i < subagents.length; i++) {
|
|
89872
|
+
if (subagents[i].type === "attack-surface" && subagents[i].status === "completed") {
|
|
89873
|
+
subagents[i] = { ...subagents[i], status: "paused" };
|
|
89874
|
+
}
|
|
89875
|
+
}
|
|
89876
|
+
}
|
|
89877
|
+
const isComplete = hasReportFile;
|
|
89878
|
+
return {
|
|
89879
|
+
session,
|
|
89880
|
+
subagents,
|
|
89881
|
+
attackSurfaceResults,
|
|
89882
|
+
isComplete,
|
|
89883
|
+
hasReport: hasReportFile,
|
|
89884
|
+
interruptedDuringDiscovery
|
|
89885
|
+
};
|
|
89886
|
+
}
|
|
89887
|
+
var init_loader = __esm(() => {
|
|
89888
|
+
init_persistence();
|
|
89889
|
+
init_report();
|
|
89890
|
+
});
|
|
89891
|
+
|
|
89772
89892
|
// src/core/agents/specialized/attackSurface/prompts.ts
|
|
89773
89893
|
var SYSTEM = `You are an autonomous attack surface analysis agent. Your mission is to comprehensively map the attack surface of a target and produce a structured report of all discovered assets and pentest objectives.
|
|
89774
89894
|
|
|
@@ -90220,7 +90340,7 @@ function loadAttackSurfaceResults2(resultsPath) {
|
|
|
90220
90340
|
const data = readFileSync6(resultsPath, "utf-8");
|
|
90221
90341
|
return JSON.parse(data);
|
|
90222
90342
|
}
|
|
90223
|
-
var
|
|
90343
|
+
var init_types3 = () => {};
|
|
90224
90344
|
|
|
90225
90345
|
// src/core/ai/index.ts
|
|
90226
90346
|
var init_ai2 = __esm(() => {
|
|
@@ -90333,7 +90453,7 @@ var init_zod_compat = __esm(() => {
|
|
|
90333
90453
|
|
|
90334
90454
|
// node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
|
|
90335
90455
|
var LATEST_PROTOCOL_VERSION = "2025-11-25", SUPPORTED_PROTOCOL_VERSIONS, RELATED_TASK_META_KEY = "io.modelcontextprotocol/related-task", JSONRPC_VERSION = "2.0", AssertObjectSchema, ProgressTokenSchema, CursorSchema, TaskCreationParamsSchema, TaskMetadataSchema, RelatedTaskMetadataSchema, RequestMetaSchema, BaseRequestParamsSchema, TaskAugmentedRequestParamsSchema, isTaskAugmentedRequestParams = (value) => TaskAugmentedRequestParamsSchema.safeParse(value).success, RequestSchema, NotificationsParamsSchema, NotificationSchema, ResultSchema, RequestIdSchema, JSONRPCRequestSchema, isJSONRPCRequest = (value) => JSONRPCRequestSchema.safeParse(value).success, JSONRPCNotificationSchema, isJSONRPCNotification = (value) => JSONRPCNotificationSchema.safeParse(value).success, JSONRPCResultResponseSchema, isJSONRPCResultResponse = (value) => JSONRPCResultResponseSchema.safeParse(value).success, ErrorCode, JSONRPCErrorResponseSchema, isJSONRPCErrorResponse = (value) => JSONRPCErrorResponseSchema.safeParse(value).success, JSONRPCMessageSchema, JSONRPCResponseSchema, EmptyResultSchema, CancelledNotificationParamsSchema, CancelledNotificationSchema, IconSchema, IconsSchema, BaseMetadataSchema, ImplementationSchema, FormElicitationCapabilitySchema, ElicitationCapabilitySchema, ClientTasksCapabilitySchema, ServerTasksCapabilitySchema, ClientCapabilitiesSchema, InitializeRequestParamsSchema, InitializeRequestSchema, ServerCapabilitiesSchema, InitializeResultSchema, InitializedNotificationSchema, PingRequestSchema, ProgressSchema, ProgressNotificationParamsSchema, ProgressNotificationSchema, PaginatedRequestParamsSchema, PaginatedRequestSchema, PaginatedResultSchema, TaskStatusSchema, TaskSchema, CreateTaskResultSchema, TaskStatusNotificationParamsSchema, TaskStatusNotificationSchema, GetTaskRequestSchema, GetTaskResultSchema, GetTaskPayloadRequestSchema, GetTaskPayloadResultSchema, ListTasksRequestSchema, ListTasksResultSchema, CancelTaskRequestSchema, CancelTaskResultSchema, ResourceContentsSchema, TextResourceContentsSchema, Base64Schema, BlobResourceContentsSchema, RoleSchema, AnnotationsSchema, ResourceSchema, ResourceTemplateSchema, ListResourcesRequestSchema, ListResourcesResultSchema, ListResourceTemplatesRequestSchema, ListResourceTemplatesResultSchema, ResourceRequestParamsSchema, ReadResourceRequestParamsSchema, ReadResourceRequestSchema, ReadResourceResultSchema, ResourceListChangedNotificationSchema, SubscribeRequestParamsSchema, SubscribeRequestSchema, UnsubscribeRequestParamsSchema, UnsubscribeRequestSchema, ResourceUpdatedNotificationParamsSchema, ResourceUpdatedNotificationSchema, PromptArgumentSchema, PromptSchema, ListPromptsRequestSchema, ListPromptsResultSchema, GetPromptRequestParamsSchema, GetPromptRequestSchema, TextContentSchema, ImageContentSchema, AudioContentSchema, ToolUseContentSchema, EmbeddedResourceSchema, ResourceLinkSchema, ContentBlockSchema, PromptMessageSchema, GetPromptResultSchema, PromptListChangedNotificationSchema, ToolAnnotationsSchema, ToolExecutionSchema, ToolSchema, ListToolsRequestSchema, ListToolsResultSchema, CallToolResultSchema, CompatibilityCallToolResultSchema, CallToolRequestParamsSchema, CallToolRequestSchema, ToolListChangedNotificationSchema, ListChangedOptionsBaseSchema, LoggingLevelSchema, SetLevelRequestParamsSchema, SetLevelRequestSchema, LoggingMessageNotificationParamsSchema, LoggingMessageNotificationSchema, ModelHintSchema, ModelPreferencesSchema, ToolChoiceSchema, ToolResultContentSchema, SamplingContentSchema, SamplingMessageContentBlockSchema, SamplingMessageSchema, CreateMessageRequestParamsSchema, CreateMessageRequestSchema, CreateMessageResultSchema, CreateMessageResultWithToolsSchema, BooleanSchemaSchema, StringSchemaSchema, NumberSchemaSchema, UntitledSingleSelectEnumSchemaSchema, TitledSingleSelectEnumSchemaSchema, LegacyTitledEnumSchemaSchema, SingleSelectEnumSchemaSchema, UntitledMultiSelectEnumSchemaSchema, TitledMultiSelectEnumSchemaSchema, MultiSelectEnumSchemaSchema, EnumSchemaSchema, PrimitiveSchemaDefinitionSchema, ElicitRequestFormParamsSchema, ElicitRequestURLParamsSchema, ElicitRequestParamsSchema, ElicitRequestSchema, ElicitationCompleteNotificationParamsSchema, ElicitationCompleteNotificationSchema, ElicitResultSchema, ResourceTemplateReferenceSchema, PromptReferenceSchema, CompleteRequestParamsSchema, CompleteRequestSchema, CompleteResultSchema, RootSchema, ListRootsRequestSchema, ListRootsResultSchema, RootsListChangedNotificationSchema, ClientRequestSchema, ClientNotificationSchema, ClientResultSchema, ServerRequestSchema, ServerNotificationSchema, ServerResultSchema, McpError, UrlElicitationRequiredError;
|
|
90336
|
-
var
|
|
90456
|
+
var init_types4 = __esm(() => {
|
|
90337
90457
|
init_v4();
|
|
90338
90458
|
SUPPORTED_PROTOCOL_VERSIONS = [LATEST_PROTOCOL_VERSION, "2025-06-18", "2025-03-26", "2024-11-05", "2024-10-07"];
|
|
90339
90459
|
AssertObjectSchema = custom2((v2) => v2 !== null && (typeof v2 === "object" || typeof v2 === "function"));
|
|
@@ -92234,7 +92354,7 @@ function mergeCapabilities(base, additional) {
|
|
|
92234
92354
|
var DEFAULT_REQUEST_TIMEOUT_MSEC = 60000;
|
|
92235
92355
|
var init_protocol = __esm(() => {
|
|
92236
92356
|
init_zod_compat();
|
|
92237
|
-
|
|
92357
|
+
init_types4();
|
|
92238
92358
|
init_zod_json_schema_compat();
|
|
92239
92359
|
});
|
|
92240
92360
|
|
|
@@ -104284,7 +104404,7 @@ class ExperimentalClientTasks {
|
|
|
104284
104404
|
}
|
|
104285
104405
|
}
|
|
104286
104406
|
var init_client = __esm(() => {
|
|
104287
|
-
|
|
104407
|
+
init_types4();
|
|
104288
104408
|
});
|
|
104289
104409
|
|
|
104290
104410
|
// node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
|
|
@@ -104367,7 +104487,7 @@ function getSupportedElicitationModes(capabilities) {
|
|
|
104367
104487
|
var Client;
|
|
104368
104488
|
var init_client2 = __esm(() => {
|
|
104369
104489
|
init_protocol();
|
|
104370
|
-
|
|
104490
|
+
init_types4();
|
|
104371
104491
|
init_ajv_provider();
|
|
104372
104492
|
init_zod_compat();
|
|
104373
104493
|
init_client();
|
|
@@ -105282,7 +105402,7 @@ function serializeMessage(message) {
|
|
|
105282
105402
|
`;
|
|
105283
105403
|
}
|
|
105284
105404
|
var init_stdio = __esm(() => {
|
|
105285
|
-
|
|
105405
|
+
init_types4();
|
|
105286
105406
|
});
|
|
105287
105407
|
|
|
105288
105408
|
// node_modules/@modelcontextprotocol/sdk/dist/esm/client/stdio.js
|
|
@@ -105634,9 +105754,10 @@ class PlaywrightMcpSession {
|
|
|
105634
105754
|
}
|
|
105635
105755
|
function createBrowserTools(targetUrl, evidenceDir, mode = "pentest", logger, abortSignal, headless) {
|
|
105636
105756
|
const session = new PlaywrightMcpSession(headless ?? defaultHeadless);
|
|
105637
|
-
|
|
105638
|
-
session.disconnect().catch(() => {});
|
|
105639
|
-
|
|
105757
|
+
if (abortSignal) {
|
|
105758
|
+
const onAbort = () => session.disconnect().catch(() => {});
|
|
105759
|
+
abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
105760
|
+
}
|
|
105640
105761
|
if (!existsSync11(evidenceDir)) {
|
|
105641
105762
|
mkdirSync3(evidenceDir, { recursive: true });
|
|
105642
105763
|
}
|
|
@@ -107192,7 +107313,7 @@ function getSeverityFromScore(score) {
|
|
|
107192
107313
|
return "HIGH";
|
|
107193
107314
|
return "CRITICAL";
|
|
107194
107315
|
}
|
|
107195
|
-
var
|
|
107316
|
+
var init_types5 = () => {};
|
|
107196
107317
|
|
|
107197
107318
|
// src/lib/cvss/macrovector-scores.ts
|
|
107198
107319
|
var MACROVECTOR_LOOKUP, METRIC_LEVELS, MAX_SEVERITY, STEP = 0.1, EPSILON;
|
|
@@ -107766,7 +107887,7 @@ function getScoreType(metrics) {
|
|
|
107766
107887
|
}
|
|
107767
107888
|
var BASE_METRICS, THREAT_METRICS, ENVIRONMENTAL_METRICS, SUPPLEMENTAL_METRICS;
|
|
107768
107889
|
var init_calculator = __esm(() => {
|
|
107769
|
-
|
|
107890
|
+
init_types5();
|
|
107770
107891
|
init_macrovector_scores();
|
|
107771
107892
|
BASE_METRICS = [
|
|
107772
107893
|
"AV",
|
|
@@ -107803,7 +107924,7 @@ var init_calculator = __esm(() => {
|
|
|
107803
107924
|
|
|
107804
107925
|
// src/lib/cvss/index.ts
|
|
107805
107926
|
var init_cvss = __esm(() => {
|
|
107806
|
-
|
|
107927
|
+
init_types5();
|
|
107807
107928
|
init_calculator();
|
|
107808
107929
|
init_macrovector_scores();
|
|
107809
107930
|
});
|
|
@@ -107828,7 +107949,8 @@ async function scoreFindingWithCVSS(input, model, authConfig, abortSignal) {
|
|
|
107828
107949
|
vectorString: cvssResult.vectorString,
|
|
107829
107950
|
metrics: cvssResult.metrics,
|
|
107830
107951
|
scoreType: cvssResult.scoreType,
|
|
107831
|
-
reasoning: assessment.reasoning
|
|
107952
|
+
reasoning: assessment.reasoning,
|
|
107953
|
+
cwes: assessment.cwes
|
|
107832
107954
|
};
|
|
107833
107955
|
}
|
|
107834
107956
|
function truncateField(value, limit) {
|
|
@@ -108012,11 +108134,45 @@ var CVSSMetricsOutputSchema, CVSS_SCORER_SYSTEM_PROMPT = `You are a CVSS 4.0 sco
|
|
|
108012
108134
|
6. Assess impact on both the vulnerable system AND potential subsequent systems
|
|
108013
108135
|
7. Since a POC exists and confirmed the vulnerability, E should typically be 'A'
|
|
108014
108136
|
|
|
108015
|
-
Always provide brief reasoning explaining your key decisions
|
|
108137
|
+
Always provide brief reasoning explaining your key decisions.
|
|
108138
|
+
|
|
108139
|
+
## CWE Assignment Guidelines
|
|
108140
|
+
|
|
108141
|
+
In addition to CVSS metrics, assign one or more CWE identifiers to the finding. For each CWE, provide a brief reasoning explaining why it applies.
|
|
108142
|
+
|
|
108143
|
+
### Common CWE Mappings
|
|
108144
|
+
|
|
108145
|
+
| Vulnerability Class | Primary CWE | Related CWEs |
|
|
108146
|
+
|---------------------|------------|--------------|
|
|
108147
|
+
| SQL Injection | CWE-89 | CWE-564 (Hibernate), CWE-943 (NoSQL) |
|
|
108148
|
+
| Cross-Site Scripting (XSS) | CWE-79 | CWE-80 (Basic XSS), CWE-87 (Alt XSS) |
|
|
108149
|
+
| Command/OS Injection | CWE-78 | CWE-77 (Command Injection) |
|
|
108150
|
+
| Code Injection / RCE | CWE-94 | CWE-95 (Eval Injection), CWE-96 (Static Code Injection) |
|
|
108151
|
+
| IDOR / Access Control | CWE-639 | CWE-284 (Improper Access Control), CWE-862 (Missing AuthZ) |
|
|
108152
|
+
| SSRF | CWE-918 | — |
|
|
108153
|
+
| Path Traversal / LFI | CWE-22 | CWE-23 (Relative Path), CWE-36 (Absolute Path) |
|
|
108154
|
+
| XXE | CWE-611 | CWE-776 (Recursive Entity) |
|
|
108155
|
+
| SSTI | CWE-1336 | CWE-94 (Code Injection) |
|
|
108156
|
+
| CSRF | CWE-352 | — |
|
|
108157
|
+
| Deserialization | CWE-502 | — |
|
|
108158
|
+
| Open Redirect | CWE-601 | — |
|
|
108159
|
+
| Information Disclosure | CWE-200 | CWE-209 (Error Messages), CWE-532 (Log Files) |
|
|
108160
|
+
| Authentication Bypass | CWE-287 | CWE-306 (Missing Auth) |
|
|
108161
|
+
| Cryptographic Issues | CWE-327 | CWE-328 (Weak Hash), CWE-330 (Insufficient Randomness) |
|
|
108162
|
+
|
|
108163
|
+
### CWE Assignment Rules
|
|
108164
|
+
|
|
108165
|
+
1. Assign the **most specific applicable CWE(s)** — prefer CWE-89 (SQL Injection) over CWE-74 (generic Injection).
|
|
108166
|
+
2. Use the standard \`CWE-<number>\` format (e.g., CWE-89, not "CWE 89" or "89").
|
|
108167
|
+
3. Assign **1-3 CWEs** per finding. Multiple CWEs are appropriate when the vulnerability spans categories (e.g., an IDOR that also leaks PII: CWE-639 + CWE-200).
|
|
108168
|
+
4. Order CWEs by relevance — the primary weakness first.
|
|
108169
|
+
5. When the vulnerability class is provided, use it as a strong hint but verify against the evidence.
|
|
108170
|
+
6. For each CWE, provide a specific reasoning explaining why it applies to *this* finding — not a generic definition of the CWE.`, MAX_EVIDENCE_CHARS = 1e4, MAX_DESCRIPTION_CHARS = 3000, MAX_IMPACT_CHARS = 2000;
|
|
108016
108171
|
var init_cvssScorer = __esm(() => {
|
|
108017
108172
|
init_zod();
|
|
108018
108173
|
init_ai2();
|
|
108019
108174
|
init_cvss();
|
|
108175
|
+
init_types2();
|
|
108020
108176
|
CVSSMetricsOutputSchema = exports_external.object({
|
|
108021
108177
|
metrics: exports_external.object({
|
|
108022
108178
|
AV: exports_external.enum(["N", "A", "L", "P"]).describe("Attack Vector: N=Network (remotely exploitable), A=Adjacent network, L=Local access required, P=Physical access required"),
|
|
@@ -108032,7 +108188,8 @@ var init_cvssScorer = __esm(() => {
|
|
|
108032
108188
|
SA: exports_external.enum(["H", "L", "N"]).describe("Availability Impact on Subsequent Systems: H=High, L=Low, N=None"),
|
|
108033
108189
|
E: exports_external.enum(["A", "P", "U"]).describe("Exploit Maturity: A=Attacked (working exploit exists), P=POC available, U=Unreported")
|
|
108034
108190
|
}),
|
|
108035
|
-
reasoning: exports_external.string().describe("Brief explanation (2-3 sentences) of the key factors that influenced the metric choices")
|
|
108191
|
+
reasoning: exports_external.string().describe("Brief explanation (2-3 sentences) of the key factors that influenced the metric choices"),
|
|
108192
|
+
cwes: exports_external.array(CweEntrySchema).describe("CWE classifications for this vulnerability, most specific first")
|
|
108036
108193
|
});
|
|
108037
108194
|
});
|
|
108038
108195
|
|
|
@@ -108057,7 +108214,8 @@ FINDING STRUCTURE:
|
|
|
108057
108214
|
- Impact: Business and technical consequences if exploited
|
|
108058
108215
|
- Evidence: Commands run, responses received, proof of exploitation
|
|
108059
108216
|
- Remediation: Specific, actionable steps to fix
|
|
108060
|
-
- References: CVE, CWE, OWASP, or security advisories
|
|
108217
|
+
- References: CVE, CWE, OWASP, or security advisories
|
|
108218
|
+
- Vulnerability Class: The class of vulnerability (e.g., sqli, xss, command-injection) — improves CWE accuracy`,
|
|
108061
108219
|
inputSchema: documentVulnerabilityInputSchema,
|
|
108062
108220
|
execute: async (input) => {
|
|
108063
108221
|
try {
|
|
@@ -108082,7 +108240,8 @@ FINDING STRUCTURE:
|
|
|
108082
108240
|
impact: input.impact,
|
|
108083
108241
|
evidence: evidenceForPrompt,
|
|
108084
108242
|
endpoint: input.endpoint,
|
|
108085
|
-
remediation: input.remediation
|
|
108243
|
+
remediation: input.remediation,
|
|
108244
|
+
vulnerabilityClass: input.vulnerabilityClass
|
|
108086
108245
|
},
|
|
108087
108246
|
agentMessages: []
|
|
108088
108247
|
}, ctx4.model, ctx4.authConfig, ctx4.abortSignal);
|
|
@@ -108115,6 +108274,7 @@ FINDING STRUCTURE:
|
|
|
108115
108274
|
sessionId: session.id,
|
|
108116
108275
|
target: session.targets[0],
|
|
108117
108276
|
...evidenceFilePath && { evidenceFile: evidenceFilePath },
|
|
108277
|
+
cwes: cvssResult.cwes,
|
|
108118
108278
|
cvss: {
|
|
108119
108279
|
score: cvssResult.score,
|
|
108120
108280
|
severity: cvssResult.severity,
|
|
@@ -108144,6 +108304,10 @@ FINDING STRUCTURE:
|
|
|
108144
108304
|
**Score Type:** ${cvssResult.scoreType}
|
|
108145
108305
|
|
|
108146
108306
|
**Reasoning:** ${cvssResult.reasoning}`;
|
|
108307
|
+
const cweSection = cvssResult.cwes?.length ? `## CWE Classification
|
|
108308
|
+
|
|
108309
|
+
${cvssResult.cwes.map((cwe) => `- **${cwe.id}** — ${cwe.reasoning}`).join(`
|
|
108310
|
+
`)}` : "";
|
|
108147
108311
|
const evidenceSection = evidenceFilePath ? `## Evidence
|
|
108148
108312
|
|
|
108149
108313
|
\`\`\`
|
|
@@ -108175,7 +108339,9 @@ ${finding.impact}
|
|
|
108175
108339
|
|
|
108176
108340
|
${cvssSection}
|
|
108177
108341
|
|
|
108178
|
-
${
|
|
108342
|
+
${cweSection ? `${cweSection}
|
|
108343
|
+
|
|
108344
|
+
` : ""}${evidenceSection}
|
|
108179
108345
|
|
|
108180
108346
|
## POC
|
|
108181
108347
|
|
|
@@ -108195,7 +108361,8 @@ ${finding.references}` : ""}
|
|
|
108195
108361
|
`;
|
|
108196
108362
|
writeFileSync7(mdPath, markdown);
|
|
108197
108363
|
const summaryPath = join11(session.rootPath, "findings-summary.md");
|
|
108198
|
-
const
|
|
108364
|
+
const cweTag = cvssResult.cwes?.length ? ` (${cvssResult.cwes.map((c) => c.id).join(", ")})` : "";
|
|
108365
|
+
const summaryEntry = `- [${finding.severity}] (CVSS ${cvssResult.score})${cweTag} ${finding.title} - \`findings/${mdFilename}\`
|
|
108199
108366
|
`;
|
|
108200
108367
|
try {
|
|
108201
108368
|
appendFileSync2(summaryPath, summaryEntry);
|
|
@@ -108248,6 +108415,7 @@ var init_documentFinding = __esm(() => {
|
|
|
108248
108415
|
pocPath: exports_external.string().describe("Relative path to the POC script (e.g., pocs/poc_sqli.sh)"),
|
|
108249
108416
|
remediation: exports_external.string().describe("Steps to fix the issue"),
|
|
108250
108417
|
references: exports_external.string().optional().describe("CVE, CWE, or related references"),
|
|
108418
|
+
vulnerabilityClass: exports_external.string().optional().describe("The class of vulnerability (e.g., sqli, xss, command-injection, idor, ssrf, path-traversal, crypto, cve)"),
|
|
108251
108419
|
toolCallDescription: exports_external.string().describe("A concise, human-readable description of what this tool call is doing (e.g., 'Documenting SQL injection finding')")
|
|
108252
108420
|
});
|
|
108253
108421
|
FALLBACK_CVSS = {
|
|
@@ -108269,7 +108437,8 @@ var init_documentFinding = __esm(() => {
|
|
|
108269
108437
|
E: "A"
|
|
108270
108438
|
},
|
|
108271
108439
|
scoreType: "CVSS-BT",
|
|
108272
|
-
reasoning: "CVSS scoring unavailable — using conservative MEDIUM default."
|
|
108440
|
+
reasoning: "CVSS scoring unavailable — using conservative MEDIUM default.",
|
|
108441
|
+
cwes: []
|
|
108273
108442
|
};
|
|
108274
108443
|
});
|
|
108275
108444
|
|
|
@@ -108451,9 +108620,17 @@ function runScript(runner, scriptPath, timeout, abortSignal) {
|
|
|
108451
108620
|
let stderr = "";
|
|
108452
108621
|
let killed = false;
|
|
108453
108622
|
let resolved = false;
|
|
108623
|
+
let abortCleanup;
|
|
108624
|
+
if (abortSignal) {
|
|
108625
|
+
const handler = () => killProcess();
|
|
108626
|
+
abortSignal.addEventListener("abort", handler, { once: true });
|
|
108627
|
+
abortCleanup = () => abortSignal.removeEventListener("abort", handler);
|
|
108628
|
+
}
|
|
108454
108629
|
const safeResolve = (result) => {
|
|
108455
108630
|
if (!resolved) {
|
|
108456
108631
|
resolved = true;
|
|
108632
|
+
clearTimeout(timeoutTimer);
|
|
108633
|
+
abortCleanup?.();
|
|
108457
108634
|
resolve4(result);
|
|
108458
108635
|
}
|
|
108459
108636
|
};
|
|
@@ -108487,18 +108664,11 @@ function runScript(runner, scriptPath, timeout, abortSignal) {
|
|
|
108487
108664
|
stderr += data.toString();
|
|
108488
108665
|
});
|
|
108489
108666
|
child.on("close", (code) => {
|
|
108490
|
-
clearTimeout(timeoutTimer);
|
|
108491
108667
|
safeResolve({ stdout, stderr, exitCode: code ?? 1 });
|
|
108492
108668
|
});
|
|
108493
108669
|
child.on("error", (err) => {
|
|
108494
|
-
clearTimeout(timeoutTimer);
|
|
108495
108670
|
safeResolve({ stdout, stderr, exitCode: 1 });
|
|
108496
108671
|
});
|
|
108497
|
-
if (abortSignal) {
|
|
108498
|
-
const handler = () => killProcess();
|
|
108499
|
-
abortSignal.addEventListener("abort", handler, { once: true });
|
|
108500
|
-
child.on("close", () => abortSignal.removeEventListener("abort", handler));
|
|
108501
|
-
}
|
|
108502
108672
|
});
|
|
108503
108673
|
}
|
|
108504
108674
|
var MAX_POC_ATTEMPTS = 3, createPocInputSchema;
|
|
@@ -108733,6 +108903,23 @@ search with flags or a more specific directory if results are truncated.`,
|
|
|
108733
108903
|
});
|
|
108734
108904
|
let stdout = "";
|
|
108735
108905
|
let stderr = "";
|
|
108906
|
+
let resolved = false;
|
|
108907
|
+
let abortCleanup;
|
|
108908
|
+
if (ctx4.abortSignal) {
|
|
108909
|
+
const abortHandler = () => child.kill("SIGTERM");
|
|
108910
|
+
ctx4.abortSignal.addEventListener("abort", abortHandler, {
|
|
108911
|
+
once: true
|
|
108912
|
+
});
|
|
108913
|
+
abortCleanup = () => ctx4.abortSignal.removeEventListener("abort", abortHandler);
|
|
108914
|
+
}
|
|
108915
|
+
const safeResolve = (result) => {
|
|
108916
|
+
if (resolved)
|
|
108917
|
+
return;
|
|
108918
|
+
resolved = true;
|
|
108919
|
+
clearTimeout(timeout);
|
|
108920
|
+
abortCleanup?.();
|
|
108921
|
+
resolve4(result);
|
|
108922
|
+
};
|
|
108736
108923
|
const timeout = setTimeout(() => {
|
|
108737
108924
|
child.kill("SIGTERM");
|
|
108738
108925
|
}, 30000);
|
|
@@ -108743,7 +108930,6 @@ search with flags or a more specific directory if results are truncated.`,
|
|
|
108743
108930
|
stderr += data.toString();
|
|
108744
108931
|
});
|
|
108745
108932
|
child.on("close", (code) => {
|
|
108746
|
-
clearTimeout(timeout);
|
|
108747
108933
|
const noMatch = code === 1 && stderr === "";
|
|
108748
108934
|
const matchCount = stdout ? stdout.trimEnd().split(`
|
|
108749
108935
|
`).length : 0;
|
|
@@ -108751,7 +108937,7 @@ search with flags or a more specific directory if results are truncated.`,
|
|
|
108751
108937
|
const output = truncated ? `${stdout.substring(0, 50000)}
|
|
108752
108938
|
|
|
108753
108939
|
(truncated — narrow your search)` : stdout || "(no matches)";
|
|
108754
|
-
|
|
108940
|
+
safeResolve({
|
|
108755
108941
|
success: code === 0 || noMatch,
|
|
108756
108942
|
error: noMatch || code === 0 ? "" : stderr || `Exit code: ${code}`,
|
|
108757
108943
|
output,
|
|
@@ -108760,8 +108946,7 @@ search with flags or a more specific directory if results are truncated.`,
|
|
|
108760
108946
|
});
|
|
108761
108947
|
});
|
|
108762
108948
|
child.on("error", (err) => {
|
|
108763
|
-
|
|
108764
|
-
resolve4({
|
|
108949
|
+
safeResolve({
|
|
108765
108950
|
success: false,
|
|
108766
108951
|
error: err.message,
|
|
108767
108952
|
output: "",
|
|
@@ -108769,15 +108954,6 @@ search with flags or a more specific directory if results are truncated.`,
|
|
|
108769
108954
|
command
|
|
108770
108955
|
});
|
|
108771
108956
|
});
|
|
108772
|
-
if (ctx4.abortSignal) {
|
|
108773
|
-
const abortHandler = () => child.kill("SIGTERM");
|
|
108774
|
-
ctx4.abortSignal.addEventListener("abort", abortHandler, {
|
|
108775
|
-
once: true
|
|
108776
|
-
});
|
|
108777
|
-
child.on("close", () => {
|
|
108778
|
-
ctx4.abortSignal.removeEventListener("abort", abortHandler);
|
|
108779
|
-
});
|
|
108780
|
-
}
|
|
108781
108957
|
});
|
|
108782
108958
|
}
|
|
108783
108959
|
});
|
|
@@ -110904,7 +111080,7 @@ For each app you identified, spawn a coding agent with a detailed objective. The
|
|
|
110904
111080
|
|
|
110905
111081
|
// src/core/agents/specialized/whiteboxAttackSurface/types.ts
|
|
110906
111082
|
var RiskScoreBreakdownSchema, RiskScoreSchema, EndpointSchema, AppSchema, WhiteboxAttackSurfaceResultSchema;
|
|
110907
|
-
var
|
|
111083
|
+
var init_types6 = __esm(() => {
|
|
110908
111084
|
init_zod();
|
|
110909
111085
|
RiskScoreBreakdownSchema = exports_external.object({
|
|
110910
111086
|
exposure: exports_external.number().min(0).max(3).describe("Exposure Level (0-3): 3=Public no auth, 2=Standard user login, 1=Privileged/admin access, 0=Private/internal-only"),
|
|
@@ -110978,7 +111154,7 @@ var init_agent2 = __esm(() => {
|
|
|
110978
111154
|
init_dist5();
|
|
110979
111155
|
init_dist5();
|
|
110980
111156
|
init_offensiveSecurityAgent();
|
|
110981
|
-
|
|
111157
|
+
init_types6();
|
|
110982
111158
|
WhiteboxAttackSurfaceAgent = class WhiteboxAttackSurfaceAgent extends OffensiveSecurityAgent {
|
|
110983
111159
|
constructor(opts) {
|
|
110984
111160
|
const {
|
|
@@ -193873,7 +194049,7 @@ function createInitialOperatorState(initialMode = "manual", requireApproval = tr
|
|
|
193873
194049
|
};
|
|
193874
194050
|
}
|
|
193875
194051
|
var OPERATOR_STAGES, OperatorSettingsObject2;
|
|
193876
|
-
var
|
|
194052
|
+
var init_types7 = __esm(() => {
|
|
193877
194053
|
init_zod();
|
|
193878
194054
|
OPERATOR_STAGES = {
|
|
193879
194055
|
setup: {
|
|
@@ -194071,11 +194247,11 @@ var init_approvalGate = __esm(() => {
|
|
|
194071
194247
|
|
|
194072
194248
|
// src/core/operator/stageManager.ts
|
|
194073
194249
|
var init_stageManager = __esm(() => {
|
|
194074
|
-
|
|
194250
|
+
init_types7();
|
|
194075
194251
|
});
|
|
194076
194252
|
// src/core/operator/index.ts
|
|
194077
194253
|
var init_operator = __esm(() => {
|
|
194078
|
-
|
|
194254
|
+
init_types7();
|
|
194079
194255
|
init_toolClassifier();
|
|
194080
194256
|
init_approvalGate();
|
|
194081
194257
|
init_stageManager();
|
|
@@ -194125,6 +194301,7 @@ var init_offensiveSecurityAgent = __esm(() => {
|
|
|
194125
194301
|
resolveResult;
|
|
194126
194302
|
subagentId;
|
|
194127
194303
|
persistentShell;
|
|
194304
|
+
abortSignal;
|
|
194128
194305
|
_session;
|
|
194129
194306
|
static async create(input) {
|
|
194130
194307
|
let session = input.session;
|
|
@@ -194146,6 +194323,7 @@ var init_offensiveSecurityAgent = __esm(() => {
|
|
|
194146
194323
|
constructor(input) {
|
|
194147
194324
|
this._session = input.session;
|
|
194148
194325
|
this.subagentId = input.subagentId;
|
|
194326
|
+
this.abortSignal = input.abortSignal;
|
|
194149
194327
|
if (!input.sandbox) {
|
|
194150
194328
|
this.persistentShell = new PersistentShell({
|
|
194151
194329
|
cwd: input.session.rootPath
|
|
@@ -194309,6 +194487,9 @@ var init_offensiveSecurityAgent = __esm(() => {
|
|
|
194309
194487
|
}
|
|
194310
194488
|
}
|
|
194311
194489
|
this.persistentShell?.dispose();
|
|
194490
|
+
if (this.abortSignal?.aborted) {
|
|
194491
|
+
throw new DOMException("Agent aborted by user", "AbortError");
|
|
194492
|
+
}
|
|
194312
194493
|
if (this.resolveResult) {
|
|
194313
194494
|
return this.resolveResult(this.streamResult);
|
|
194314
194495
|
}
|
|
@@ -194392,7 +194573,7 @@ var BlackboxAttackSurfaceAgent;
|
|
|
194392
194573
|
var init_blackboxAgent = __esm(() => {
|
|
194393
194574
|
init_dist5();
|
|
194394
194575
|
init_utils2();
|
|
194395
|
-
|
|
194576
|
+
init_types3();
|
|
194396
194577
|
init_offensiveSecurityAgent();
|
|
194397
194578
|
BlackboxAttackSurfaceAgent = class BlackboxAttackSurfaceAgent extends OffensiveSecurityAgent {
|
|
194398
194579
|
constructor(opts) {
|
|
@@ -194417,6 +194598,7 @@ var init_blackboxAgent = __esm(() => {
|
|
|
194417
194598
|
onStepFinish,
|
|
194418
194599
|
abortSignal,
|
|
194419
194600
|
attackSurfaceRegistry,
|
|
194601
|
+
messages: opts.messages,
|
|
194420
194602
|
activeTools: [
|
|
194421
194603
|
"execute_command",
|
|
194422
194604
|
"document_asset",
|
|
@@ -194692,7 +194874,8 @@ var init_agent4 = __esm(() => {
|
|
|
194692
194874
|
onStepFinish,
|
|
194693
194875
|
abortSignal,
|
|
194694
194876
|
sandbox,
|
|
194695
|
-
findingsRegistry
|
|
194877
|
+
findingsRegistry,
|
|
194878
|
+
messages
|
|
194696
194879
|
} = opts;
|
|
194697
194880
|
super({
|
|
194698
194881
|
system: buildSystemPrompt(session),
|
|
@@ -194705,6 +194888,7 @@ var init_agent4 = __esm(() => {
|
|
|
194705
194888
|
abortSignal,
|
|
194706
194889
|
sandbox,
|
|
194707
194890
|
findingsRegistry,
|
|
194891
|
+
messages,
|
|
194708
194892
|
activeTools: [
|
|
194709
194893
|
"execute_command",
|
|
194710
194894
|
"http_request",
|
|
@@ -194814,7 +194998,7 @@ var EXECUTION_METRICS_FILENAME = "execution-metrics.json";
|
|
|
194814
194998
|
var init_execution_metrics = () => {};
|
|
194815
194999
|
|
|
194816
195000
|
// src/core/utils/concurrency.ts
|
|
194817
|
-
async function runWithBoundedConcurrency(items, concurrency, fn) {
|
|
195001
|
+
async function runWithBoundedConcurrency(items, concurrency, fn, abortSignal) {
|
|
194818
195002
|
const results = new Array(items.length).fill(null);
|
|
194819
195003
|
let nextIdx = 0;
|
|
194820
195004
|
let completed = 0;
|
|
@@ -194825,11 +195009,11 @@ async function runWithBoundedConcurrency(items, concurrency, fn) {
|
|
|
194825
195009
|
}
|
|
194826
195010
|
let active = 0;
|
|
194827
195011
|
function next() {
|
|
194828
|
-
if (completed === items.length) {
|
|
195012
|
+
if (completed >= nextIdx && (nextIdx === items.length || abortSignal?.aborted)) {
|
|
194829
195013
|
resolve4();
|
|
194830
195014
|
return;
|
|
194831
195015
|
}
|
|
194832
|
-
while (active < concurrency && nextIdx < items.length) {
|
|
195016
|
+
while (active < concurrency && nextIdx < items.length && !abortSignal?.aborted) {
|
|
194833
195017
|
const idx = nextIdx++;
|
|
194834
195018
|
active++;
|
|
194835
195019
|
fn(items[idx], idx).then((r2) => {
|
|
@@ -195369,7 +195553,7 @@ When your objective includes structured output, call \`response\` with your fina
|
|
|
195369
195553
|
var init_whiteboxAttackSurface = __esm(() => {
|
|
195370
195554
|
init_zod();
|
|
195371
195555
|
init_agent3();
|
|
195372
|
-
|
|
195556
|
+
init_types6();
|
|
195373
195557
|
init_riskScoring();
|
|
195374
195558
|
AppInfoSchema = exports_external.object({
|
|
195375
195559
|
name: exports_external.string().describe("Application or service name"),
|
|
@@ -195419,10 +195603,21 @@ async function runPentestSwarm(input) {
|
|
|
195419
195603
|
concurrency = DEFAULT_CONCURRENCY4,
|
|
195420
195604
|
onStepFinish
|
|
195421
195605
|
} = input;
|
|
195422
|
-
const
|
|
195606
|
+
const completedIds = getCompletedAgentIds(session);
|
|
195607
|
+
const existingManifest = readAgentManifest(session);
|
|
195608
|
+
const freshEntries = buildManifestEntries(targets);
|
|
195609
|
+
const manifestEntries = freshEntries.map((fresh) => {
|
|
195610
|
+
const existing = existingManifest.find((e2) => e2.id === fresh.id);
|
|
195611
|
+
if (existing && existing.status === "completed")
|
|
195612
|
+
return existing;
|
|
195613
|
+
return fresh;
|
|
195614
|
+
});
|
|
195423
195615
|
writeAgentManifest(session, manifestEntries);
|
|
195424
195616
|
const results = await runWithBoundedConcurrency(targets, concurrency, async (target, index) => {
|
|
195425
195617
|
const subagentId = `pentest-agent-${index + 1}`;
|
|
195618
|
+
if (completedIds.has(subagentId))
|
|
195619
|
+
return null;
|
|
195620
|
+
const previousMessages = loadSubagentMessages(session, subagentId);
|
|
195426
195621
|
let lastMessages = [];
|
|
195427
195622
|
const handleStepFinish = (e2) => {
|
|
195428
195623
|
if (e2.response.messages) {
|
|
@@ -195456,7 +195651,8 @@ async function runPentestSwarm(input) {
|
|
|
195456
195651
|
authConfig,
|
|
195457
195652
|
abortSignal,
|
|
195458
195653
|
findingsRegistry,
|
|
195459
|
-
onStepFinish: handleStepFinish
|
|
195654
|
+
onStepFinish: handleStepFinish,
|
|
195655
|
+
messages: previousMessages.length > 0 ? previousMessages : undefined
|
|
195460
195656
|
});
|
|
195461
195657
|
const result = await agent.consume({
|
|
195462
195658
|
onError: (e2) => onError?.(e2),
|
|
@@ -195468,8 +195664,9 @@ async function runPentestSwarm(input) {
|
|
|
195468
195664
|
objective: target.objectives.join("; "),
|
|
195469
195665
|
status: "completed",
|
|
195470
195666
|
findingsCount: result.findings.length,
|
|
195471
|
-
messages: lastMessages
|
|
195667
|
+
messages: [...previousMessages, ...lastMessages]
|
|
195472
195668
|
});
|
|
195669
|
+
updateManifestEntryStatus(session, subagentId, "completed");
|
|
195473
195670
|
subagentCallbacks?.onSubagentComplete?.({
|
|
195474
195671
|
subagentId,
|
|
195475
195672
|
input: { target: target.target, objectives: target.objectives },
|
|
@@ -195483,8 +195680,9 @@ async function runPentestSwarm(input) {
|
|
|
195483
195680
|
objective: target.objectives.join("; "),
|
|
195484
195681
|
status: "failed",
|
|
195485
195682
|
error: error40 instanceof Error ? error40.message : String(error40),
|
|
195486
|
-
messages: lastMessages
|
|
195683
|
+
messages: [...previousMessages, ...lastMessages]
|
|
195487
195684
|
});
|
|
195685
|
+
updateManifestEntryStatus(session, subagentId, "failed");
|
|
195488
195686
|
subagentCallbacks?.onSubagentComplete?.({
|
|
195489
195687
|
subagentId,
|
|
195490
195688
|
input: { target: target.target, objectives: target.objectives },
|
|
@@ -195492,7 +195690,7 @@ async function runPentestSwarm(input) {
|
|
|
195492
195690
|
});
|
|
195493
195691
|
throw error40;
|
|
195494
195692
|
}
|
|
195495
|
-
});
|
|
195693
|
+
}, abortSignal);
|
|
195496
195694
|
finalizeManifest(session, manifestEntries, results);
|
|
195497
195695
|
return results;
|
|
195498
195696
|
}
|
|
@@ -195510,7 +195708,13 @@ async function runPentestWorkflow(input) {
|
|
|
195510
195708
|
try {
|
|
195511
195709
|
const mode = cwd ? "whitebox" : "blackbox";
|
|
195512
195710
|
let swarmTargets;
|
|
195513
|
-
|
|
195711
|
+
const existingResults = loadAttackSurfaceResults(session.rootPath);
|
|
195712
|
+
if (existingResults?.targets && existingResults.targets.length > 0) {
|
|
195713
|
+
swarmTargets = existingResults.targets.map((t3) => ({
|
|
195714
|
+
target: t3.target,
|
|
195715
|
+
objectives: [t3.objective]
|
|
195716
|
+
}));
|
|
195717
|
+
} else if (mode === "whitebox") {
|
|
195514
195718
|
swarmTargets = await runWhiteboxPhase({
|
|
195515
195719
|
codebasePath: cwd,
|
|
195516
195720
|
baseTarget: target,
|
|
@@ -195532,6 +195736,9 @@ async function runPentestWorkflow(input) {
|
|
|
195532
195736
|
onStepFinish
|
|
195533
195737
|
});
|
|
195534
195738
|
}
|
|
195739
|
+
if (abortSignal?.aborted) {
|
|
195740
|
+
throw new DOMException("Pentest aborted by user", "AbortError");
|
|
195741
|
+
}
|
|
195535
195742
|
if (swarmTargets.length === 0) {
|
|
195536
195743
|
const report2 = buildPentestReport([], {
|
|
195537
195744
|
target,
|
|
@@ -195555,17 +195762,23 @@ async function runPentestWorkflow(input) {
|
|
|
195555
195762
|
authConfig,
|
|
195556
195763
|
abortSignal
|
|
195557
195764
|
});
|
|
195558
|
-
|
|
195559
|
-
|
|
195560
|
-
|
|
195561
|
-
|
|
195562
|
-
|
|
195563
|
-
|
|
195564
|
-
|
|
195565
|
-
|
|
195566
|
-
|
|
195567
|
-
|
|
195568
|
-
|
|
195765
|
+
const completedCount = getCompletedAgentIds(session).size;
|
|
195766
|
+
if (completedCount < swarmTargets.length) {
|
|
195767
|
+
await runPentestSwarm({
|
|
195768
|
+
targets: swarmTargets,
|
|
195769
|
+
model,
|
|
195770
|
+
session,
|
|
195771
|
+
authConfig,
|
|
195772
|
+
abortSignal,
|
|
195773
|
+
findingsRegistry,
|
|
195774
|
+
subagentCallbacks: callbacks?.subagentCallbacks,
|
|
195775
|
+
onError: (e2) => callbacks?.onError?.(e2),
|
|
195776
|
+
onStepFinish
|
|
195777
|
+
});
|
|
195778
|
+
}
|
|
195779
|
+
if (abortSignal?.aborted) {
|
|
195780
|
+
throw new DOMException("Pentest aborted by user", "AbortError");
|
|
195781
|
+
}
|
|
195569
195782
|
const findings = loadFindings2(session.findingsPath);
|
|
195570
195783
|
const report = buildPentestReport(findings, {
|
|
195571
195784
|
target,
|
|
@@ -195677,6 +195890,7 @@ var init_pentest = __esm(() => {
|
|
|
195677
195890
|
init_report();
|
|
195678
195891
|
init_persistence();
|
|
195679
195892
|
init_execution_metrics();
|
|
195893
|
+
init_loader();
|
|
195680
195894
|
init_whiteboxAttackSurface();
|
|
195681
195895
|
});
|
|
195682
195896
|
|
|
@@ -272284,7 +272498,7 @@ var useTerminalDimensions = () => {
|
|
|
272284
272498
|
};
|
|
272285
272499
|
|
|
272286
272500
|
// src/tui/index.tsx
|
|
272287
|
-
var
|
|
272501
|
+
var import_react87 = __toESM(require_react(), 1);
|
|
272288
272502
|
|
|
272289
272503
|
// src/tui/components/footer.tsx
|
|
272290
272504
|
import os6 from "os";
|
|
@@ -273755,7 +273969,7 @@ function CommandProvider({
|
|
|
273755
273969
|
}
|
|
273756
273970
|
|
|
273757
273971
|
// src/tui/components/commands/sessions-display.tsx
|
|
273758
|
-
var
|
|
273972
|
+
var import_react24 = __toESM(require_react(), 1);
|
|
273759
273973
|
|
|
273760
273974
|
// src/tui/context/focus.tsx
|
|
273761
273975
|
var import_react18 = __toESM(require_react(), 1);
|
|
@@ -273824,10 +274038,29 @@ function openSessionReport(sessionRootPath) {
|
|
|
273824
274038
|
}
|
|
273825
274039
|
}
|
|
273826
274040
|
|
|
274041
|
+
// src/tui/context/dimensions.tsx
|
|
274042
|
+
var import_react19 = __toESM(require_react(), 1);
|
|
274043
|
+
var DimensionsContext = import_react19.createContext(null);
|
|
274044
|
+
function TerminalDimensionsProvider({
|
|
274045
|
+
children
|
|
274046
|
+
}) {
|
|
274047
|
+
const dimensions = useTerminalDimensions();
|
|
274048
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(DimensionsContext.Provider, {
|
|
274049
|
+
value: dimensions,
|
|
274050
|
+
children
|
|
274051
|
+
}, undefined, false, undefined, this);
|
|
274052
|
+
}
|
|
274053
|
+
function useDimensions() {
|
|
274054
|
+
const ctx3 = import_react19.useContext(DimensionsContext);
|
|
274055
|
+
if (!ctx3)
|
|
274056
|
+
throw new Error("useDimensions() must be used within <TerminalDimensionsProvider>");
|
|
274057
|
+
return ctx3;
|
|
274058
|
+
}
|
|
274059
|
+
|
|
273827
274060
|
// src/tui/context/dialog.tsx
|
|
273828
|
-
var
|
|
274061
|
+
var import_react22 = __toESM(require_react(), 1);
|
|
273829
274062
|
function Dialog({ size = "medium", onClose, children }) {
|
|
273830
|
-
const dimensions =
|
|
274063
|
+
const dimensions = useDimensions();
|
|
273831
274064
|
const renderer = useRenderer();
|
|
273832
274065
|
const { colors: themeColors } = useTheme();
|
|
273833
274066
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
@@ -273862,14 +274095,14 @@ function Dialog({ size = "medium", onClose, children }) {
|
|
|
273862
274095
|
}, undefined, false, undefined, this)
|
|
273863
274096
|
}, undefined, false, undefined, this);
|
|
273864
274097
|
}
|
|
273865
|
-
var DialogContext =
|
|
274098
|
+
var DialogContext = import_react22.createContext(null);
|
|
273866
274099
|
function DialogProvider({ children }) {
|
|
273867
|
-
const [stack, setStack] =
|
|
273868
|
-
const [size, setSize] =
|
|
273869
|
-
const [externalDialogOpen, setExternalDialogOpen] =
|
|
274100
|
+
const [stack, setStack] = import_react22.useState([]);
|
|
274101
|
+
const [size, setSize] = import_react22.useState("medium");
|
|
274102
|
+
const [externalDialogOpen, setExternalDialogOpen] = import_react22.useState(false);
|
|
273870
274103
|
const renderer = useRenderer();
|
|
273871
|
-
const focusRef =
|
|
273872
|
-
const refocus =
|
|
274104
|
+
const focusRef = import_react22.useRef(null);
|
|
274105
|
+
const refocus = import_react22.useCallback(() => {
|
|
273873
274106
|
setTimeout(() => {
|
|
273874
274107
|
const focus = focusRef.current;
|
|
273875
274108
|
if (!focus)
|
|
@@ -273891,7 +274124,7 @@ function DialogProvider({ children }) {
|
|
|
273891
274124
|
focus.focus();
|
|
273892
274125
|
}, 1);
|
|
273893
274126
|
}, [renderer]);
|
|
273894
|
-
const clear =
|
|
274127
|
+
const clear = import_react22.useCallback(() => {
|
|
273895
274128
|
for (const item of stack) {
|
|
273896
274129
|
if (item.onClose)
|
|
273897
274130
|
item.onClose();
|
|
@@ -273900,7 +274133,7 @@ function DialogProvider({ children }) {
|
|
|
273900
274133
|
setStack([]);
|
|
273901
274134
|
refocus();
|
|
273902
274135
|
}, [stack, refocus]);
|
|
273903
|
-
const replace =
|
|
274136
|
+
const replace = import_react22.useCallback((element, onClose) => {
|
|
273904
274137
|
if (stack.length === 0) {
|
|
273905
274138
|
focusRef.current = renderer.currentFocusedRenderable;
|
|
273906
274139
|
}
|
|
@@ -273945,7 +274178,7 @@ function DialogProvider({ children }) {
|
|
|
273945
274178
|
}, undefined, true, undefined, this);
|
|
273946
274179
|
}
|
|
273947
274180
|
function useDialog() {
|
|
273948
|
-
const value =
|
|
274181
|
+
const value = import_react22.useContext(DialogContext);
|
|
273949
274182
|
if (!value) {
|
|
273950
274183
|
throw new Error("useDialog must be used within a DialogProvider");
|
|
273951
274184
|
}
|
|
@@ -274010,7 +274243,7 @@ function findChildById(scrollBox, id) {
|
|
|
274010
274243
|
// src/tui/hooks/use-sessions-list.ts
|
|
274011
274244
|
init_session();
|
|
274012
274245
|
init_report();
|
|
274013
|
-
var
|
|
274246
|
+
var import_react23 = __toESM(require_react(), 1);
|
|
274014
274247
|
import { existsSync as existsSync7, readdirSync } from "fs";
|
|
274015
274248
|
import { join as join3 } from "path";
|
|
274016
274249
|
function countFindings(findingsPath) {
|
|
@@ -274026,10 +274259,10 @@ function checkHasReport(rootPath) {
|
|
|
274026
274259
|
return existsSync7(join3(rootPath, REPORT_FILENAME_MD));
|
|
274027
274260
|
}
|
|
274028
274261
|
function useSessionsList() {
|
|
274029
|
-
const [allSessions, setAllSessions] =
|
|
274030
|
-
const [loading, setLoading] =
|
|
274031
|
-
const [searchTerm, setSearchTerm] =
|
|
274032
|
-
const loadSessions =
|
|
274262
|
+
const [allSessions, setAllSessions] = import_react23.useState([]);
|
|
274263
|
+
const [loading, setLoading] = import_react23.useState(true);
|
|
274264
|
+
const [searchTerm, setSearchTerm] = import_react23.useState("");
|
|
274265
|
+
const loadSessions = import_react23.useCallback(async () => {
|
|
274033
274266
|
setLoading(true);
|
|
274034
274267
|
try {
|
|
274035
274268
|
const enriched = [];
|
|
@@ -274052,10 +274285,10 @@ function useSessionsList() {
|
|
|
274052
274285
|
setLoading(false);
|
|
274053
274286
|
}
|
|
274054
274287
|
}, []);
|
|
274055
|
-
|
|
274288
|
+
import_react23.useEffect(() => {
|
|
274056
274289
|
loadSessions();
|
|
274057
274290
|
}, [loadSessions]);
|
|
274058
|
-
const deleteSession =
|
|
274291
|
+
const deleteSession = import_react23.useCallback(async (id) => {
|
|
274059
274292
|
await sessions.remove({ sessionId: id });
|
|
274060
274293
|
await loadSessions();
|
|
274061
274294
|
}, [loadSessions]);
|
|
@@ -274114,10 +274347,10 @@ function useSessionsList() {
|
|
|
274114
274347
|
function SessionsDisplay({ onClose }) {
|
|
274115
274348
|
const { colors: colors2 } = useTheme();
|
|
274116
274349
|
const { refocusPrompt } = useFocus();
|
|
274117
|
-
const [selectedIndex, setSelectedIndex] =
|
|
274118
|
-
const [statusMessage, setStatusMessage] =
|
|
274350
|
+
const [selectedIndex, setSelectedIndex] = import_react24.useState(0);
|
|
274351
|
+
const [statusMessage, setStatusMessage] = import_react24.useState("");
|
|
274119
274352
|
const route = useRoute();
|
|
274120
|
-
const scroll =
|
|
274353
|
+
const scroll = import_react24.useRef(null);
|
|
274121
274354
|
const {
|
|
274122
274355
|
groupedSessions,
|
|
274123
274356
|
visualOrderSessions,
|
|
@@ -274133,7 +274366,7 @@ function SessionsDisplay({ onClose }) {
|
|
|
274133
274366
|
setTimeout(() => setStatusMessage(""), 2000);
|
|
274134
274367
|
}
|
|
274135
274368
|
}
|
|
274136
|
-
|
|
274369
|
+
import_react24.useEffect(() => {
|
|
274137
274370
|
if (visualOrderSessions.length > 0 && selectedIndex >= visualOrderSessions.length) {
|
|
274138
274371
|
setSelectedIndex(visualOrderSessions.length - 1);
|
|
274139
274372
|
} else if (visualOrderSessions.length === 0) {
|
|
@@ -274169,7 +274402,7 @@ function SessionsDisplay({ onClose }) {
|
|
|
274169
274402
|
setTimeout(() => setStatusMessage(""), 2000);
|
|
274170
274403
|
return;
|
|
274171
274404
|
}
|
|
274172
|
-
const isOperator = currentSelection.config?.mode === "operator" || currentSelection.hasOperatorState;
|
|
274405
|
+
const isOperator = currentSelection.config?.mode === "operator" || !currentSelection.config?.mode && currentSelection.hasOperatorState;
|
|
274173
274406
|
refocusPrompt();
|
|
274174
274407
|
onClose();
|
|
274175
274408
|
route.navigate({
|
|
@@ -274215,6 +274448,11 @@ function SessionsDisplay({ onClose }) {
|
|
|
274215
274448
|
const currentSelection = visualOrderSessions[selectedIndex];
|
|
274216
274449
|
if (!currentSelection)
|
|
274217
274450
|
return;
|
|
274451
|
+
if (!currentSelection.hasReport) {
|
|
274452
|
+
setStatusMessage("No report available");
|
|
274453
|
+
setTimeout(() => setStatusMessage(""), 2000);
|
|
274454
|
+
return;
|
|
274455
|
+
}
|
|
274218
274456
|
openReport(currentSelection.id);
|
|
274219
274457
|
return;
|
|
274220
274458
|
}
|
|
@@ -274318,6 +274556,7 @@ function SessionsDisplay({ onClose }) {
|
|
|
274318
274556
|
});
|
|
274319
274557
|
const mode = session.config?.mode || "auto";
|
|
274320
274558
|
const modeBadge = mode === "operator" ? "[operator]" : "[auto]";
|
|
274559
|
+
const statusBadge = session.hasReport ? "✓" : "…";
|
|
274321
274560
|
const findingsText = session.findingsCount > 0 ? `${session.findingsCount} finding${session.findingsCount > 1 ? "s" : ""}` : "";
|
|
274322
274561
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
274323
274562
|
id: session.id,
|
|
@@ -274342,6 +274581,10 @@ function SessionsDisplay({ onClose }) {
|
|
|
274342
274581
|
fg: isSelected ? colors2.text : colors2.textMuted,
|
|
274343
274582
|
children: session.name
|
|
274344
274583
|
}, undefined, false, undefined, this),
|
|
274584
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
274585
|
+
fg: session.hasReport ? colors2.primary : colors2.textMuted,
|
|
274586
|
+
children: statusBadge
|
|
274587
|
+
}, undefined, false, undefined, this),
|
|
274345
274588
|
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
274346
274589
|
fg: mode === "operator" ? colors2.primary : colors2.textMuted,
|
|
274347
274590
|
children: modeBadge
|
|
@@ -274405,7 +274648,7 @@ function SessionsDisplay({ onClose }) {
|
|
|
274405
274648
|
}
|
|
274406
274649
|
|
|
274407
274650
|
// src/tui/components/commands/config-dialog.tsx
|
|
274408
|
-
var
|
|
274651
|
+
var import_react27 = __toESM(require_react(), 1);
|
|
274409
274652
|
|
|
274410
274653
|
// src/tui/components/alert-dialog.tsx
|
|
274411
274654
|
function AlertDialog({
|
|
@@ -274418,7 +274661,7 @@ function AlertDialog({
|
|
|
274418
274661
|
size = "medium"
|
|
274419
274662
|
}) {
|
|
274420
274663
|
const { colors: colors2 } = useTheme();
|
|
274421
|
-
const dimensions =
|
|
274664
|
+
const dimensions = useDimensions();
|
|
274422
274665
|
const renderer = useRenderer();
|
|
274423
274666
|
useKeyboard((key) => {
|
|
274424
274667
|
if (!open)
|
|
@@ -274492,8 +274735,8 @@ function AlertDialog({
|
|
|
274492
274735
|
init_config2();
|
|
274493
274736
|
function ConfigDialog() {
|
|
274494
274737
|
const route = useRoute();
|
|
274495
|
-
const [open, setOpen] =
|
|
274496
|
-
|
|
274738
|
+
const [open, setOpen] = import_react27.useState(false);
|
|
274739
|
+
import_react27.useEffect(() => {
|
|
274497
274740
|
if (route.data.type === "base" && route.data.path === "config") {
|
|
274498
274741
|
setOpen(true);
|
|
274499
274742
|
} else {
|
|
@@ -274507,8 +274750,8 @@ function ConfigDialog() {
|
|
|
274507
274750
|
path: "home"
|
|
274508
274751
|
});
|
|
274509
274752
|
};
|
|
274510
|
-
const [appConfig, setAppConfig] =
|
|
274511
|
-
|
|
274753
|
+
const [appConfig, setAppConfig] = import_react27.useState(null);
|
|
274754
|
+
import_react27.useEffect(() => {
|
|
274512
274755
|
async function getConfig() {
|
|
274513
274756
|
const _appConfig = await config2.get();
|
|
274514
274757
|
setAppConfig(_appConfig);
|
|
@@ -274583,11 +274826,11 @@ var import_react38 = __toESM(require_react(), 1);
|
|
|
274583
274826
|
|
|
274584
274827
|
// src/tui/context/config.tsx
|
|
274585
274828
|
init_config2();
|
|
274586
|
-
var
|
|
274587
|
-
var ctx3 =
|
|
274829
|
+
var import_react28 = __toESM(require_react(), 1);
|
|
274830
|
+
var ctx3 = import_react28.createContext(null);
|
|
274588
274831
|
function ConfigProvider({ children, config: config3 }) {
|
|
274589
|
-
const [appConfig, setAppConfig] =
|
|
274590
|
-
const value =
|
|
274832
|
+
const [appConfig, setAppConfig] = import_react28.useState(config3);
|
|
274833
|
+
const value = import_react28.useMemo(() => ({
|
|
274591
274834
|
data: appConfig,
|
|
274592
274835
|
update: async (newConfig) => {
|
|
274593
274836
|
await config2.update(newConfig);
|
|
@@ -274607,7 +274850,7 @@ function ConfigProvider({ children, config: config3 }) {
|
|
|
274607
274850
|
}, undefined, false, undefined, this);
|
|
274608
274851
|
}
|
|
274609
274852
|
var useConfig = () => {
|
|
274610
|
-
const config3 =
|
|
274853
|
+
const config3 = import_react28.useContext(ctx3);
|
|
274611
274854
|
if (!config3) {
|
|
274612
274855
|
throw new Error("useConfig must be called within a ConfigProvider");
|
|
274613
274856
|
}
|
|
@@ -274615,10 +274858,10 @@ var useConfig = () => {
|
|
|
274615
274858
|
};
|
|
274616
274859
|
|
|
274617
274860
|
// src/tui/components/chat/home-view.tsx
|
|
274618
|
-
var
|
|
274861
|
+
var import_react33 = __toESM(require_react(), 1);
|
|
274619
274862
|
|
|
274620
274863
|
// src/tui/components/chat/petri-animation.tsx
|
|
274621
|
-
var
|
|
274864
|
+
var import_react29 = __toESM(require_react(), 1);
|
|
274622
274865
|
|
|
274623
274866
|
// src/tui/components/chat/lib/play-core/num.ts
|
|
274624
274867
|
function clamp(x2, min, max) {
|
|
@@ -274714,8 +274957,8 @@ function stopGlobalTick2() {
|
|
|
274714
274957
|
}
|
|
274715
274958
|
}
|
|
274716
274959
|
function useGlobalTick2() {
|
|
274717
|
-
const [, setTick] =
|
|
274718
|
-
|
|
274960
|
+
const [, setTick] = import_react29.useState(0);
|
|
274961
|
+
import_react29.useEffect(() => {
|
|
274719
274962
|
const listener = () => setTick((t2) => t2 + 1);
|
|
274720
274963
|
globalListeners2.add(listener);
|
|
274721
274964
|
startGlobalTick2();
|
|
@@ -274740,19 +274983,19 @@ function PetriAnimation({
|
|
|
274740
274983
|
height = 0.4,
|
|
274741
274984
|
width = "100%"
|
|
274742
274985
|
}) {
|
|
274743
|
-
const dimensions =
|
|
274986
|
+
const dimensions = useDimensions();
|
|
274744
274987
|
const tick = useGlobalTick2();
|
|
274745
274988
|
const { colors: colors2 } = useTheme();
|
|
274746
|
-
const simulationRef =
|
|
274747
|
-
const [frame, setFrame] =
|
|
274748
|
-
const gradientColors =
|
|
274749
|
-
const actualHeight =
|
|
274989
|
+
const simulationRef = import_react29.useRef(null);
|
|
274990
|
+
const [frame, setFrame] = import_react29.useState([]);
|
|
274991
|
+
const gradientColors = import_react29.useMemo(() => generateGradient(colors2.primary, 9), [colors2.primary]);
|
|
274992
|
+
const actualHeight = import_react29.useMemo(() => {
|
|
274750
274993
|
if (typeof height === "number" && height <= 1) {
|
|
274751
274994
|
return Math.floor(dimensions.height * height);
|
|
274752
274995
|
}
|
|
274753
274996
|
return typeof height === "number" ? height : Math.floor(dimensions.height * 0.4);
|
|
274754
274997
|
}, [height, dimensions.height]);
|
|
274755
|
-
const actualWidth =
|
|
274998
|
+
const actualWidth = import_react29.useMemo(() => {
|
|
274756
274999
|
if (typeof width === "number" && width <= 1) {
|
|
274757
275000
|
return Math.floor(dimensions.width * width);
|
|
274758
275001
|
}
|
|
@@ -274761,7 +275004,7 @@ function PetriAnimation({
|
|
|
274761
275004
|
}
|
|
274762
275005
|
return typeof width === "number" ? width : dimensions.width;
|
|
274763
275006
|
}, [width, dimensions.width]);
|
|
274764
|
-
|
|
275007
|
+
import_react29.useEffect(() => {
|
|
274765
275008
|
if (actualWidth <= 0 || actualHeight <= 0)
|
|
274766
275009
|
return;
|
|
274767
275010
|
if (!simulationRef.current) {
|
|
@@ -274770,7 +275013,7 @@ function PetriAnimation({
|
|
|
274770
275013
|
simulationRef.current.resize(actualWidth, actualHeight);
|
|
274771
275014
|
}
|
|
274772
275015
|
}, [actualWidth, actualHeight]);
|
|
274773
|
-
|
|
275016
|
+
import_react29.useEffect(() => {
|
|
274774
275017
|
if (simulationRef.current) {
|
|
274775
275018
|
simulationRef.current.step();
|
|
274776
275019
|
setFrame(simulationRef.current.render());
|
|
@@ -274796,7 +275039,7 @@ function getRowColor(rowIdx, totalRows, gradient) {
|
|
|
274796
275039
|
}
|
|
274797
275040
|
|
|
274798
275041
|
// src/tui/components/shared/prompt-input.tsx
|
|
274799
|
-
var
|
|
275042
|
+
var import_react31 = __toESM(require_react(), 1);
|
|
274800
275043
|
|
|
274801
275044
|
// src/tui/components/shared/prompt-input-logic.ts
|
|
274802
275045
|
function filterSuggestions(inputValue, options, maxSuggestions) {
|
|
@@ -274917,13 +275160,13 @@ function shouldResetHistory(historyIndex, isNavigatingHistory) {
|
|
|
274917
275160
|
}
|
|
274918
275161
|
|
|
274919
275162
|
// src/tui/components/shared/use-paste-extmarks.ts
|
|
274920
|
-
var
|
|
275163
|
+
var import_react30 = __toESM(require_react(), 1);
|
|
274921
275164
|
var LARGE_PASTE_MIN_LINES = 5;
|
|
274922
275165
|
var LARGE_PASTE_MIN_CHARS = 500;
|
|
274923
275166
|
function usePasteExtmarks(textareaRef) {
|
|
274924
|
-
const countRef =
|
|
274925
|
-
const typeIdRef =
|
|
274926
|
-
const dataRef =
|
|
275167
|
+
const countRef = import_react30.useRef(0);
|
|
275168
|
+
const typeIdRef = import_react30.useRef(-1);
|
|
275169
|
+
const dataRef = import_react30.useRef(new Map);
|
|
274927
275170
|
const clearPaste = () => {
|
|
274928
275171
|
textareaRef.current?.extmarks.clear();
|
|
274929
275172
|
countRef.current = 0;
|
|
@@ -274993,7 +275236,7 @@ var chatKeyBindings = [
|
|
|
274993
275236
|
{ name: "return", shift: true, action: "newline" },
|
|
274994
275237
|
{ name: "linefeed", shift: true, action: "newline" }
|
|
274995
275238
|
];
|
|
274996
|
-
var PromptInput =
|
|
275239
|
+
var PromptInput = import_react31.forwardRef(function PromptInput2({
|
|
274997
275240
|
width,
|
|
274998
275241
|
minHeight = 1,
|
|
274999
275242
|
maxHeight = 6,
|
|
@@ -275018,31 +275261,31 @@ var PromptInput = import_react30.forwardRef(function PromptInput2({
|
|
|
275018
275261
|
const { colors: colors2 } = useTheme();
|
|
275019
275262
|
const { inputValue, setInputValue } = useInput();
|
|
275020
275263
|
const { registerPromptRef } = useFocus();
|
|
275021
|
-
const textareaRef =
|
|
275022
|
-
const [selectedSuggestionIndex, setSelectedSuggestionIndex] =
|
|
275023
|
-
const [historyIndex, setHistoryIndex] =
|
|
275024
|
-
const savedInputRef =
|
|
275025
|
-
const historyRef =
|
|
275264
|
+
const textareaRef = import_react31.useRef(null);
|
|
275265
|
+
const [selectedSuggestionIndex, setSelectedSuggestionIndex] = import_react31.useState(-1);
|
|
275266
|
+
const [historyIndex, setHistoryIndex] = import_react31.useState(-1);
|
|
275267
|
+
const savedInputRef = import_react31.useRef("");
|
|
275268
|
+
const historyRef = import_react31.useRef(commandHistory);
|
|
275026
275269
|
historyRef.current = commandHistory;
|
|
275027
|
-
const isNavigatingHistoryRef =
|
|
275028
|
-
const selectedIndexRef =
|
|
275029
|
-
const suggestionsRef =
|
|
275030
|
-
const onCommandExecuteRef =
|
|
275270
|
+
const isNavigatingHistoryRef = import_react31.useRef(false);
|
|
275271
|
+
const selectedIndexRef = import_react31.useRef(selectedSuggestionIndex);
|
|
275272
|
+
const suggestionsRef = import_react31.useRef([]);
|
|
275273
|
+
const onCommandExecuteRef = import_react31.useRef(onCommandExecute);
|
|
275031
275274
|
onCommandExecuteRef.current = onCommandExecute;
|
|
275032
|
-
const onSubmitRef =
|
|
275275
|
+
const onSubmitRef = import_react31.useRef(onSubmit);
|
|
275033
275276
|
onSubmitRef.current = onSubmit;
|
|
275034
275277
|
const { handlePaste, resolveText, clearPaste } = usePasteExtmarks(textareaRef);
|
|
275035
|
-
const suggestions =
|
|
275036
|
-
|
|
275278
|
+
const suggestions = import_react31.useMemo(() => enableAutocomplete ? filterSuggestions(inputValue, autocompleteOptions, maxSuggestions) : [], [enableAutocomplete, autocompleteOptions, inputValue, maxSuggestions]);
|
|
275279
|
+
import_react31.useEffect(() => {
|
|
275037
275280
|
suggestionsRef.current = suggestions;
|
|
275038
275281
|
}, [suggestions]);
|
|
275039
|
-
|
|
275282
|
+
import_react31.useEffect(() => {
|
|
275040
275283
|
selectedIndexRef.current = selectedSuggestionIndex;
|
|
275041
275284
|
}, [selectedSuggestionIndex]);
|
|
275042
|
-
|
|
275285
|
+
import_react31.useEffect(() => {
|
|
275043
275286
|
setSelectedSuggestionIndex(suggestions.length > 0 ? 0 : -1);
|
|
275044
275287
|
}, [suggestions.length]);
|
|
275045
|
-
const imperativeRef =
|
|
275288
|
+
const imperativeRef = import_react31.useRef({
|
|
275046
275289
|
focus: () => textareaRef.current?.focus(),
|
|
275047
275290
|
blur: () => textareaRef.current?.blur(),
|
|
275048
275291
|
reset: () => {
|
|
@@ -275059,11 +275302,11 @@ var PromptInput = import_react30.forwardRef(function PromptInput2({
|
|
|
275059
275302
|
getValue: () => inputValue,
|
|
275060
275303
|
getTextareaRef: () => textareaRef.current
|
|
275061
275304
|
});
|
|
275062
|
-
|
|
275305
|
+
import_react31.useEffect(() => {
|
|
275063
275306
|
imperativeRef.current.getValue = () => inputValue;
|
|
275064
275307
|
}, [inputValue]);
|
|
275065
|
-
|
|
275066
|
-
|
|
275308
|
+
import_react31.useImperativeHandle(ref, () => imperativeRef.current, []);
|
|
275309
|
+
import_react31.useEffect(() => {
|
|
275067
275310
|
registerPromptRef(imperativeRef.current);
|
|
275068
275311
|
return () => registerPromptRef(null);
|
|
275069
275312
|
}, [registerPromptRef]);
|
|
@@ -275279,41 +275522,41 @@ function getEntries() {
|
|
|
275279
275522
|
// src/tui/components/chat/home-view.tsx
|
|
275280
275523
|
function HomeView({ onNavigate, onStartSession }) {
|
|
275281
275524
|
const { colors: colors2 } = useTheme();
|
|
275282
|
-
const dimensions =
|
|
275525
|
+
const dimensions = useDimensions();
|
|
275283
275526
|
const config3 = useConfig();
|
|
275284
275527
|
const route = useRoute();
|
|
275285
275528
|
const { executeCommand, autocompleteOptions, resolveSkillContent, skills } = useCommand();
|
|
275286
275529
|
const { setInputValue } = useInput();
|
|
275287
275530
|
const { promptRef } = useFocus();
|
|
275288
275531
|
const { externalDialogOpen, stack } = useDialog();
|
|
275289
|
-
const [hintMessage, setHintMessage] =
|
|
275290
|
-
const [commandHistory, setCommandHistory] =
|
|
275291
|
-
|
|
275532
|
+
const [hintMessage, setHintMessage] = import_react33.useState(null);
|
|
275533
|
+
const [commandHistory, setCommandHistory] = import_react33.useState(getEntries);
|
|
275534
|
+
import_react33.useEffect(() => {
|
|
275292
275535
|
load().then(setCommandHistory);
|
|
275293
275536
|
}, []);
|
|
275294
|
-
const launchOperator =
|
|
275537
|
+
const launchOperator = import_react33.useCallback((message, options) => {
|
|
275295
275538
|
route.navigate({
|
|
275296
275539
|
type: "operator",
|
|
275297
275540
|
initialMessage: message,
|
|
275298
275541
|
initialConfig: { requireApproval: options?.requireApproval ?? true }
|
|
275299
275542
|
});
|
|
275300
275543
|
}, [route]);
|
|
275301
|
-
const pushHistory =
|
|
275544
|
+
const pushHistory = import_react33.useCallback((entry) => {
|
|
275302
275545
|
push(entry).then(() => setCommandHistory([...getEntries()]));
|
|
275303
275546
|
}, []);
|
|
275304
|
-
const handleSubmit =
|
|
275547
|
+
const handleSubmit = import_react33.useCallback((value) => {
|
|
275305
275548
|
if (!value.trim())
|
|
275306
275549
|
return;
|
|
275307
275550
|
pushHistory(value.trim());
|
|
275308
275551
|
launchOperator(value.trim());
|
|
275309
275552
|
}, [launchOperator, pushHistory]);
|
|
275310
|
-
|
|
275553
|
+
import_react33.useEffect(() => {
|
|
275311
275554
|
if (!hintMessage)
|
|
275312
275555
|
return;
|
|
275313
275556
|
const timer = setTimeout(() => setHintMessage(null), 3000);
|
|
275314
275557
|
return () => clearTimeout(timer);
|
|
275315
275558
|
}, [hintMessage]);
|
|
275316
|
-
const handleCommandExecute =
|
|
275559
|
+
const handleCommandExecute = import_react33.useCallback(async (command) => {
|
|
275317
275560
|
const trimmed = command.trim();
|
|
275318
275561
|
pushHistory(trimmed);
|
|
275319
275562
|
const parts = trimmed.replace(/^\/+/, "").split(/\s+/);
|
|
@@ -278177,7 +278420,7 @@ function ToastItem({
|
|
|
278177
278420
|
}
|
|
278178
278421
|
function ToastContainer() {
|
|
278179
278422
|
const { toasts, dismiss } = useToast();
|
|
278180
|
-
const dims =
|
|
278423
|
+
const dims = useDimensions();
|
|
278181
278424
|
if (toasts.length === 0)
|
|
278182
278425
|
return null;
|
|
278183
278426
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
@@ -278198,11 +278441,11 @@ function ToastContainer() {
|
|
|
278198
278441
|
}
|
|
278199
278442
|
|
|
278200
278443
|
// src/tui/components/error-boundary.tsx
|
|
278201
|
-
var
|
|
278444
|
+
var import_react52 = __toESM(require_react(), 1);
|
|
278202
278445
|
var MAX_ERRORS = 3;
|
|
278203
278446
|
var ERROR_WINDOW_MS = 5000;
|
|
278204
278447
|
|
|
278205
|
-
class ErrorBoundaryInner extends
|
|
278448
|
+
class ErrorBoundaryInner extends import_react52.default.Component {
|
|
278206
278449
|
state = {
|
|
278207
278450
|
hasError: false,
|
|
278208
278451
|
errorTimestamps: [],
|
|
@@ -278233,10 +278476,10 @@ class ErrorBoundaryInner extends import_react53.default.Component {
|
|
|
278233
278476
|
}
|
|
278234
278477
|
function ErrorBoundary2({ children }) {
|
|
278235
278478
|
const { toast } = useToast();
|
|
278236
|
-
const handleError =
|
|
278479
|
+
const handleError = import_react52.useCallback((message) => {
|
|
278237
278480
|
toast(message, "error");
|
|
278238
278481
|
}, [toast]);
|
|
278239
|
-
return
|
|
278482
|
+
return import_react52.default.createElement(ErrorBoundaryInner, { onError: handleError }, children);
|
|
278240
278483
|
}
|
|
278241
278484
|
|
|
278242
278485
|
// src/tui/index.tsx
|
|
@@ -278347,16 +278590,16 @@ function ShortcutsDialog({
|
|
|
278347
278590
|
}
|
|
278348
278591
|
|
|
278349
278592
|
// src/tui/components/commands/help-dialog.tsx
|
|
278350
|
-
var
|
|
278593
|
+
var import_react54 = __toESM(require_react(), 1);
|
|
278351
278594
|
function HelpDialog() {
|
|
278352
278595
|
const { colors: colors2 } = useTheme();
|
|
278353
278596
|
const { commands: commands2 } = useCommand();
|
|
278354
278597
|
const route = useRoute();
|
|
278355
|
-
const dimensions =
|
|
278356
|
-
const [selectedIndex, setSelectedIndex] =
|
|
278357
|
-
const [showDetail, setShowDetail] =
|
|
278358
|
-
const scrollboxRef =
|
|
278359
|
-
const commandsByCategory =
|
|
278598
|
+
const dimensions = useDimensions();
|
|
278599
|
+
const [selectedIndex, setSelectedIndex] = import_react54.useState(0);
|
|
278600
|
+
const [showDetail, setShowDetail] = import_react54.useState(false);
|
|
278601
|
+
const scrollboxRef = import_react54.useRef(null);
|
|
278602
|
+
const commandsByCategory = import_react54.useMemo(() => {
|
|
278360
278603
|
const grouped = {};
|
|
278361
278604
|
for (const cmd of commands2) {
|
|
278362
278605
|
const category = cmd.category || "Other";
|
|
@@ -278367,15 +278610,15 @@ function HelpDialog() {
|
|
|
278367
278610
|
}
|
|
278368
278611
|
return grouped;
|
|
278369
278612
|
}, [commands2]);
|
|
278370
|
-
const flatCommands =
|
|
278613
|
+
const flatCommands = import_react54.useMemo(() => {
|
|
278371
278614
|
return commands2;
|
|
278372
278615
|
}, [commands2]);
|
|
278373
|
-
|
|
278616
|
+
import_react54.useEffect(() => {
|
|
278374
278617
|
if (selectedIndex >= flatCommands.length) {
|
|
278375
278618
|
setSelectedIndex(Math.max(0, flatCommands.length - 1));
|
|
278376
278619
|
}
|
|
278377
278620
|
}, [flatCommands.length, selectedIndex]);
|
|
278378
|
-
|
|
278621
|
+
import_react54.useEffect(() => {
|
|
278379
278622
|
scrollToIndex(scrollboxRef.current, selectedIndex, flatCommands, (cmd) => cmd.name);
|
|
278380
278623
|
}, [selectedIndex, flatCommands]);
|
|
278381
278624
|
const handleClose = () => {
|
|
@@ -278810,24 +279053,24 @@ function ModelsDisplay() {
|
|
|
278810
279053
|
}
|
|
278811
279054
|
|
|
278812
279055
|
// src/tui/components/commands/auth-flow.tsx
|
|
278813
|
-
var
|
|
279056
|
+
var import_react57 = __toESM(require_react(), 1);
|
|
278814
279057
|
init_config2();
|
|
278815
279058
|
function AuthFlow({ onClose }) {
|
|
278816
279059
|
const { colors: colors2 } = useTheme();
|
|
278817
279060
|
const appConfig = useConfig();
|
|
278818
279061
|
const isConnected = !!(appConfig.data.accessToken || appConfig.data.pensarAPIKey);
|
|
278819
|
-
const [step, setStep] =
|
|
278820
|
-
const [error40, setError] =
|
|
278821
|
-
const [authMode, setAuthMode] =
|
|
278822
|
-
const [deviceInfo, setDeviceInfo] =
|
|
278823
|
-
const [legacyDeviceInfo, setLegacyDeviceInfo] =
|
|
278824
|
-
const [workspaces, setWorkspaces] =
|
|
278825
|
-
const [selectedWorkspace, setSelectedWorkspace] =
|
|
278826
|
-
const [selectedIndex, setSelectedIndex] =
|
|
278827
|
-
const [billingUrl, setBillingUrl] =
|
|
278828
|
-
const [balance, setBalance] =
|
|
278829
|
-
const pollingRef =
|
|
278830
|
-
const cancelledRef =
|
|
279062
|
+
const [step, setStep] = import_react57.useState(isConnected ? "success" : "start");
|
|
279063
|
+
const [error40, setError] = import_react57.useState(null);
|
|
279064
|
+
const [authMode, setAuthMode] = import_react57.useState(null);
|
|
279065
|
+
const [deviceInfo, setDeviceInfo] = import_react57.useState(null);
|
|
279066
|
+
const [legacyDeviceInfo, setLegacyDeviceInfo] = import_react57.useState(null);
|
|
279067
|
+
const [workspaces, setWorkspaces] = import_react57.useState([]);
|
|
279068
|
+
const [selectedWorkspace, setSelectedWorkspace] = import_react57.useState(null);
|
|
279069
|
+
const [selectedIndex, setSelectedIndex] = import_react57.useState(0);
|
|
279070
|
+
const [billingUrl, setBillingUrl] = import_react57.useState(null);
|
|
279071
|
+
const [balance, setBalance] = import_react57.useState(null);
|
|
279072
|
+
const pollingRef = import_react57.useRef(null);
|
|
279073
|
+
const cancelledRef = import_react57.useRef(false);
|
|
278831
279074
|
const connectedWorkspace = appConfig.data.workspaceSlug ? { name: appConfig.data.workspaceSlug, slug: appConfig.data.workspaceSlug } : null;
|
|
278832
279075
|
const goHome = () => {
|
|
278833
279076
|
onClose();
|
|
@@ -278839,7 +279082,7 @@ function AuthFlow({ onClose }) {
|
|
|
278839
279082
|
pollingRef.current = null;
|
|
278840
279083
|
}
|
|
278841
279084
|
};
|
|
278842
|
-
|
|
279085
|
+
import_react57.useEffect(() => {
|
|
278843
279086
|
return cleanup;
|
|
278844
279087
|
}, []);
|
|
278845
279088
|
const openUrl = (url2) => {
|
|
@@ -279472,14 +279715,14 @@ function AuthFlow({ onClose }) {
|
|
|
279472
279715
|
}
|
|
279473
279716
|
|
|
279474
279717
|
// src/tui/components/commands/credits-flow.tsx
|
|
279475
|
-
var
|
|
279718
|
+
var import_react59 = __toESM(require_react(), 1);
|
|
279476
279719
|
init_tokenRefresh();
|
|
279477
279720
|
function CreditsFlow({ onOpenAuthDialog }) {
|
|
279478
279721
|
const route = useRoute();
|
|
279479
279722
|
const appConfig = useConfig();
|
|
279480
|
-
const [step, setStep] =
|
|
279481
|
-
const [credits, setCredits] =
|
|
279482
|
-
const [error40, setError] =
|
|
279723
|
+
const [step, setStep] = import_react59.useState("loading");
|
|
279724
|
+
const [credits, setCredits] = import_react59.useState(null);
|
|
279725
|
+
const [error40, setError] = import_react59.useState(null);
|
|
279483
279726
|
const creditsUrl = `${getPensarConsoleUrl()}/credits`;
|
|
279484
279727
|
const goHome = () => {
|
|
279485
279728
|
route.navigate({ type: "base", path: "home" });
|
|
@@ -279537,7 +279780,7 @@ function CreditsFlow({ onOpenAuthDialog }) {
|
|
|
279537
279780
|
setStep("display");
|
|
279538
279781
|
}
|
|
279539
279782
|
};
|
|
279540
|
-
|
|
279783
|
+
import_react59.useEffect(() => {
|
|
279541
279784
|
fetchBalance();
|
|
279542
279785
|
}, []);
|
|
279543
279786
|
useKeyboard((key) => {
|
|
@@ -279776,10 +280019,10 @@ function CreditsFlow({ onOpenAuthDialog }) {
|
|
|
279776
280019
|
}
|
|
279777
280020
|
|
|
279778
280021
|
// src/tui/context/keybinding.tsx
|
|
279779
|
-
var
|
|
280022
|
+
var import_react65 = __toESM(require_react(), 1);
|
|
279780
280023
|
|
|
279781
280024
|
// src/tui/keybindings/keybind.tsx
|
|
279782
|
-
var
|
|
280025
|
+
var import_react61 = __toESM(require_react(), 1);
|
|
279783
280026
|
|
|
279784
280027
|
// src/tui/keybindings/actions.ts
|
|
279785
280028
|
var movementActions = [
|
|
@@ -280031,7 +280274,7 @@ var allActions = [
|
|
|
280031
280274
|
var actionsByKey = new Map(allActions.map((action) => [action.key, action]));
|
|
280032
280275
|
var actionsById = new Map(allActions.map((action) => [action.id, action]));
|
|
280033
280276
|
// src/tui/keybindings/keybind.tsx
|
|
280034
|
-
var LeaderKeyContext =
|
|
280277
|
+
var LeaderKeyContext = import_react61.createContext(null);
|
|
280035
280278
|
// src/tui/keybindings/registry.ts
|
|
280036
280279
|
function createKeybindings(deps) {
|
|
280037
280280
|
const {
|
|
@@ -280212,7 +280455,7 @@ function matchesKeybind(pressed, combo) {
|
|
|
280212
280455
|
}
|
|
280213
280456
|
|
|
280214
280457
|
// src/tui/context/keybinding.tsx
|
|
280215
|
-
var KeybindingContext =
|
|
280458
|
+
var KeybindingContext = import_react65.createContext(undefined);
|
|
280216
280459
|
function KeybindingProvider({
|
|
280217
280460
|
children,
|
|
280218
280461
|
deps
|
|
@@ -280252,121 +280495,12 @@ function KeybindingProvider({
|
|
|
280252
280495
|
}
|
|
280253
280496
|
|
|
280254
280497
|
// src/tui/components/pentest/pentest.tsx
|
|
280255
|
-
var
|
|
280498
|
+
var import_react73 = __toESM(require_react(), 1);
|
|
280256
280499
|
init_report();
|
|
280257
280500
|
import { existsSync as existsSync26, readdirSync as readdirSync6, readFileSync as readFileSync12 } from "fs";
|
|
280258
280501
|
import { join as join27 } from "path";
|
|
280259
280502
|
init_session();
|
|
280260
|
-
|
|
280261
|
-
// src/core/session/loader.ts
|
|
280262
|
-
init_persistence();
|
|
280263
|
-
init_report();
|
|
280264
|
-
import { join as join5 } from "path";
|
|
280265
|
-
import { existsSync as existsSync9, readFileSync as readFileSync4 } from "fs";
|
|
280266
|
-
function loadAttackSurfaceResults(rootPath) {
|
|
280267
|
-
const resultsPath = join5(rootPath, "attack-surface-results.json");
|
|
280268
|
-
if (!existsSync9(resultsPath)) {
|
|
280269
|
-
return null;
|
|
280270
|
-
}
|
|
280271
|
-
try {
|
|
280272
|
-
return JSON.parse(readFileSync4(resultsPath, "utf-8"));
|
|
280273
|
-
} catch (e) {
|
|
280274
|
-
console.error("Failed to load attack surface results:", e);
|
|
280275
|
-
return null;
|
|
280276
|
-
}
|
|
280277
|
-
}
|
|
280278
|
-
function hasReport(rootPath) {
|
|
280279
|
-
const reportPath = join5(rootPath, REPORT_FILENAME_MD);
|
|
280280
|
-
return existsSync9(reportPath);
|
|
280281
|
-
}
|
|
280282
|
-
function createDiscoveryFromLogs(rootPath, session) {
|
|
280283
|
-
const logPath = join5(rootPath, "logs", "streamlined-pentest.log");
|
|
280284
|
-
if (!existsSync9(logPath)) {
|
|
280285
|
-
return null;
|
|
280286
|
-
}
|
|
280287
|
-
try {
|
|
280288
|
-
const logContent = readFileSync4(logPath, "utf-8");
|
|
280289
|
-
const lines = logContent.split(`
|
|
280290
|
-
`).filter(Boolean);
|
|
280291
|
-
const messages = [];
|
|
280292
|
-
for (const line of lines) {
|
|
280293
|
-
const match = line.match(/^(\d{4}-\d{2}-\d{2}T[\d:.]+Z) - \[(\w+)\] (.+)$/);
|
|
280294
|
-
if (!match)
|
|
280295
|
-
continue;
|
|
280296
|
-
const [, timestamp, _level, content] = match;
|
|
280297
|
-
const createdAt = new Date(timestamp);
|
|
280298
|
-
if (content.startsWith("[Tool]")) {
|
|
280299
|
-
const toolMatch = content.match(/\[Tool\] (\w+): (.+)/);
|
|
280300
|
-
if (toolMatch) {
|
|
280301
|
-
messages.push({
|
|
280302
|
-
role: "tool",
|
|
280303
|
-
content: `✓ ${toolMatch[2]}`,
|
|
280304
|
-
createdAt,
|
|
280305
|
-
toolName: toolMatch[1],
|
|
280306
|
-
status: "completed"
|
|
280307
|
-
});
|
|
280308
|
-
}
|
|
280309
|
-
} else if (content.startsWith("[Step")) {
|
|
280310
|
-
const stepMatch = content.match(/\[Step \d+\] (.+)/);
|
|
280311
|
-
if (stepMatch) {
|
|
280312
|
-
messages.push({
|
|
280313
|
-
role: "assistant",
|
|
280314
|
-
content: stepMatch[1],
|
|
280315
|
-
createdAt
|
|
280316
|
-
});
|
|
280317
|
-
}
|
|
280318
|
-
}
|
|
280319
|
-
}
|
|
280320
|
-
if (messages.length === 0) {
|
|
280321
|
-
return null;
|
|
280322
|
-
}
|
|
280323
|
-
return {
|
|
280324
|
-
id: "discovery-from-logs",
|
|
280325
|
-
name: "Attack Surface Discovery",
|
|
280326
|
-
type: "attack-surface",
|
|
280327
|
-
target: session.targets[0] || "Unknown",
|
|
280328
|
-
messages,
|
|
280329
|
-
createdAt: new Date(session.time.created),
|
|
280330
|
-
status: "completed"
|
|
280331
|
-
};
|
|
280332
|
-
} catch (e) {
|
|
280333
|
-
console.error("Failed to parse logs:", e);
|
|
280334
|
-
return null;
|
|
280335
|
-
}
|
|
280336
|
-
}
|
|
280337
|
-
async function loadSessionState(session) {
|
|
280338
|
-
const rootPath = session.rootPath;
|
|
280339
|
-
let subagents = loadSubagents(rootPath);
|
|
280340
|
-
const hasAttackSurfaceAgent = subagents.some((s) => s.type === "attack-surface");
|
|
280341
|
-
if (!hasAttackSurfaceAgent) {
|
|
280342
|
-
const discoveryAgent = createDiscoveryFromLogs(rootPath, session);
|
|
280343
|
-
if (discoveryAgent) {
|
|
280344
|
-
subagents = [discoveryAgent, ...subagents];
|
|
280345
|
-
}
|
|
280346
|
-
}
|
|
280347
|
-
const attackSurfaceResults = loadAttackSurfaceResults(rootPath);
|
|
280348
|
-
const hasReportFile = hasReport(rootPath);
|
|
280349
|
-
const hasDiscoverySubagent = subagents.some((s) => s.type === "attack-surface");
|
|
280350
|
-
const interruptedDuringDiscovery = !attackSurfaceResults && !hasReportFile && hasDiscoverySubagent;
|
|
280351
|
-
if (interruptedDuringDiscovery) {
|
|
280352
|
-
for (let i = 0;i < subagents.length; i++) {
|
|
280353
|
-
if (subagents[i].type === "attack-surface" && subagents[i].status === "completed") {
|
|
280354
|
-
subagents[i] = { ...subagents[i], status: "paused" };
|
|
280355
|
-
}
|
|
280356
|
-
}
|
|
280357
|
-
}
|
|
280358
|
-
const pentestSubagents = subagents.filter((s) => s.type === "pentest");
|
|
280359
|
-
const allPentestDone = pentestSubagents.length > 0 && pentestSubagents.every((s) => s.status === "completed" || s.status === "failed");
|
|
280360
|
-
const isComplete = hasReportFile || attackSurfaceResults?.summary?.analysisComplete === true && allPentestDone;
|
|
280361
|
-
return {
|
|
280362
|
-
session,
|
|
280363
|
-
subagents,
|
|
280364
|
-
attackSurfaceResults,
|
|
280365
|
-
isComplete,
|
|
280366
|
-
hasReport: hasReportFile,
|
|
280367
|
-
interruptedDuringDiscovery
|
|
280368
|
-
};
|
|
280369
|
-
}
|
|
280503
|
+
init_loader();
|
|
280370
280504
|
|
|
280371
280505
|
// src/core/api/blackboxPentest.ts
|
|
280372
280506
|
init_pentest();
|
|
@@ -280393,7 +280527,7 @@ Found ${findings.length} vulnerabilities`);
|
|
|
280393
280527
|
init_utils();
|
|
280394
280528
|
|
|
280395
280529
|
// src/tui/components/agent-display.tsx
|
|
280396
|
-
var
|
|
280530
|
+
var import_react72 = __toESM(require_react(), 1);
|
|
280397
280531
|
|
|
280398
280532
|
// node_modules/marked/lib/marked.esm.js
|
|
280399
280533
|
function L2() {
|
|
@@ -282725,14 +282859,14 @@ ${preview}${suffix}` : preview + suffix || "POC passed",
|
|
|
282725
282859
|
return null;
|
|
282726
282860
|
}
|
|
282727
282861
|
// src/tui/components/shared/ascii-spinner.tsx
|
|
282728
|
-
var
|
|
282862
|
+
var import_react66 = __toESM(require_react(), 1);
|
|
282729
282863
|
var SPINNER_FRAMES = ["/", "-", "\\", "|"];
|
|
282730
282864
|
var SPINNER_INTERVAL = 100;
|
|
282731
282865
|
function AsciiSpinner({ label, fg: fg2 }) {
|
|
282732
282866
|
const { colors: colors2 } = useTheme();
|
|
282733
282867
|
const spinnerColor = fg2 ?? colors2.info;
|
|
282734
|
-
const [frame, setFrame] =
|
|
282735
|
-
|
|
282868
|
+
const [frame, setFrame] = import_react66.useState(0);
|
|
282869
|
+
import_react66.useEffect(() => {
|
|
282736
282870
|
const interval = setInterval(() => {
|
|
282737
282871
|
setFrame((f3) => (f3 + 1) % SPINNER_FRAMES.length);
|
|
282738
282872
|
}, SPINNER_INTERVAL);
|
|
@@ -282744,7 +282878,7 @@ function AsciiSpinner({ label, fg: fg2 }) {
|
|
|
282744
282878
|
}, undefined, false, undefined, this);
|
|
282745
282879
|
}
|
|
282746
282880
|
// src/tui/components/shared/tool-renderer.tsx
|
|
282747
|
-
var
|
|
282881
|
+
var import_react67 = __toESM(require_react(), 1);
|
|
282748
282882
|
var TOOLS_WITH_LOG_WINDOW = new Set([
|
|
282749
282883
|
"execute_command",
|
|
282750
282884
|
"run_attack_surface",
|
|
@@ -282757,13 +282891,13 @@ var TOOLS_WITH_LOG_WINDOW = new Set([
|
|
|
282757
282891
|
"document_vulnerability"
|
|
282758
282892
|
]);
|
|
282759
282893
|
var DEFAULT_SUBAGENT_LOG_LINES = 5;
|
|
282760
|
-
var ToolRenderer =
|
|
282894
|
+
var ToolRenderer = import_react67.memo(function ToolRenderer2({
|
|
282761
282895
|
message,
|
|
282762
282896
|
verbose = false,
|
|
282763
282897
|
expandedLogs = false
|
|
282764
282898
|
}) {
|
|
282765
282899
|
const { colors: colors2 } = useTheme();
|
|
282766
|
-
const [showOutput, setShowOutput] =
|
|
282900
|
+
const [showOutput, setShowOutput] = import_react67.useState(false);
|
|
282767
282901
|
if (!isToolMessage(message)) {
|
|
282768
282902
|
return null;
|
|
282769
282903
|
}
|
|
@@ -282903,7 +283037,7 @@ var ToolRenderer = import_react68.memo(function ToolRenderer2({
|
|
|
282903
283037
|
]
|
|
282904
283038
|
}, undefined, true, undefined, this);
|
|
282905
283039
|
});
|
|
282906
|
-
var SubagentLogWindow =
|
|
283040
|
+
var SubagentLogWindow = import_react67.memo(function SubagentLogWindow2({
|
|
282907
283041
|
subagentId,
|
|
282908
283042
|
entry,
|
|
282909
283043
|
expandedLogs
|
|
@@ -282960,8 +283094,8 @@ var SubagentLogWindow = import_react68.memo(function SubagentLogWindow2({
|
|
|
282960
283094
|
}, undefined, true, undefined, this);
|
|
282961
283095
|
});
|
|
282962
283096
|
// src/tui/components/shared/message-renderer.tsx
|
|
282963
|
-
var
|
|
282964
|
-
var MessageRenderer =
|
|
283097
|
+
var import_react68 = __toESM(require_react(), 1);
|
|
283098
|
+
var MessageRenderer = import_react68.memo(function MessageRenderer2({
|
|
282965
283099
|
message,
|
|
282966
283100
|
isStreaming = false,
|
|
282967
283101
|
verbose = false,
|
|
@@ -282971,7 +283105,7 @@ var MessageRenderer = import_react69.memo(function MessageRenderer2({
|
|
|
282971
283105
|
}) {
|
|
282972
283106
|
const { colors: colors2 } = useTheme();
|
|
282973
283107
|
const content = typeof message.content === "string" ? message.content : JSON.stringify(message.content);
|
|
282974
|
-
const displayContent =
|
|
283108
|
+
const displayContent = import_react68.useMemo(() => message.role === "assistant" ? markdownToStyledText(content, colors2) : content, [content, message.role, colors2]);
|
|
282975
283109
|
if (isToolMessage(message)) {
|
|
282976
283110
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ToolRenderer, {
|
|
282977
283111
|
message,
|
|
@@ -283083,9 +283217,9 @@ var MessageRenderer = import_react69.memo(function MessageRenderer2({
|
|
|
283083
283217
|
}, undefined, false, undefined, this);
|
|
283084
283218
|
});
|
|
283085
283219
|
// src/tui/components/shared/approval-prompt.tsx
|
|
283086
|
-
var
|
|
283220
|
+
var import_react69 = __toESM(require_react(), 1);
|
|
283087
283221
|
// src/tui/components/shared/message-reducer.ts
|
|
283088
|
-
var
|
|
283222
|
+
var import_react71 = __toESM(require_react(), 1);
|
|
283089
283223
|
// src/tui/components/agent-display.tsx
|
|
283090
283224
|
function getStableKey(item, contextId = "root") {
|
|
283091
283225
|
if ("messages" in item) {
|
|
@@ -283161,11 +283295,11 @@ function AgentDisplay({
|
|
|
283161
283295
|
]
|
|
283162
283296
|
}, undefined, true, undefined, this);
|
|
283163
283297
|
}
|
|
283164
|
-
var SubAgentDisplay =
|
|
283298
|
+
var SubAgentDisplay = import_react72.memo(function SubAgentDisplay2({
|
|
283165
283299
|
subagent
|
|
283166
283300
|
}) {
|
|
283167
283301
|
const { colors: colors2 } = useTheme();
|
|
283168
|
-
const [open, setOpen] =
|
|
283302
|
+
const [open, setOpen] = import_react72.useState(false);
|
|
283169
283303
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
283170
283304
|
height: open ? 40 : "auto",
|
|
283171
283305
|
onMouseDown: () => setOpen(!open),
|
|
@@ -283220,11 +283354,11 @@ var SubAgentDisplay = import_react73.memo(function SubAgentDisplay2({
|
|
|
283220
283354
|
]
|
|
283221
283355
|
}, undefined, true, undefined, this);
|
|
283222
283356
|
});
|
|
283223
|
-
var AgentMessage =
|
|
283357
|
+
var AgentMessage = import_react72.memo(function AgentMessage2({
|
|
283224
283358
|
message
|
|
283225
283359
|
}) {
|
|
283226
283360
|
const { colors: colors2 } = useTheme();
|
|
283227
|
-
const dimensions =
|
|
283361
|
+
const dimensions = useDimensions();
|
|
283228
283362
|
let content = "";
|
|
283229
283363
|
if (typeof message.content === "string") {
|
|
283230
283364
|
content = message.content;
|
|
@@ -283329,8 +283463,8 @@ var AgentMessage = import_react73.memo(function AgentMessage2({
|
|
|
283329
283463
|
});
|
|
283330
283464
|
function ToolDetails({ message }) {
|
|
283331
283465
|
const { colors: colors2 } = useTheme();
|
|
283332
|
-
const [showArgs, setShowArgs] =
|
|
283333
|
-
const [showResult, setShowResult] =
|
|
283466
|
+
const [showArgs, setShowArgs] = import_react72.useState(false);
|
|
283467
|
+
const [showResult, setShowResult] = import_react72.useState(false);
|
|
283334
283468
|
if (message.role !== "tool") {
|
|
283335
283469
|
return null;
|
|
283336
283470
|
}
|
|
@@ -283436,27 +283570,27 @@ function Pentest({
|
|
|
283436
283570
|
const config3 = useConfig();
|
|
283437
283571
|
const { model, setThinking, setIsExecuting, isExecuting } = useAgent();
|
|
283438
283572
|
const { stack, externalDialogOpen } = useDialog();
|
|
283439
|
-
const [session, setSession] =
|
|
283440
|
-
const [error40, setError] =
|
|
283441
|
-
const [phase, setPhase] =
|
|
283442
|
-
const [abortController, setAbortController] =
|
|
283443
|
-
const [panelMessages, setPanelMessages] =
|
|
283444
|
-
const panelTextRef =
|
|
283445
|
-
const panelSourceRef =
|
|
283446
|
-
const [pentestAgents, setPentestAgents] =
|
|
283447
|
-
const pentestTextRefs =
|
|
283448
|
-
const [assets, setAssets] =
|
|
283449
|
-
const [viewMode, setViewMode] =
|
|
283450
|
-
const [selectedAgentId, setSelectedAgentId] =
|
|
283451
|
-
const [focusedIndex, setFocusedIndex] =
|
|
283452
|
-
const [showOrchestratorPanel, setShowOrchestratorPanel] =
|
|
283453
|
-
const [startTime, setStartTime] =
|
|
283454
|
-
const pentestAgentList =
|
|
283455
|
-
const selectedAgent =
|
|
283456
|
-
const { width: termWidth } =
|
|
283573
|
+
const [session, setSession] = import_react73.useState(null);
|
|
283574
|
+
const [error40, setError] = import_react73.useState(null);
|
|
283575
|
+
const [phase, setPhase] = import_react73.useState("loading");
|
|
283576
|
+
const [abortController, setAbortController] = import_react73.useState(null);
|
|
283577
|
+
const [panelMessages, setPanelMessages] = import_react73.useState([]);
|
|
283578
|
+
const panelTextRef = import_react73.useRef("");
|
|
283579
|
+
const panelSourceRef = import_react73.useRef(null);
|
|
283580
|
+
const [pentestAgents, setPentestAgents] = import_react73.useState({});
|
|
283581
|
+
const pentestTextRefs = import_react73.useRef({});
|
|
283582
|
+
const [assets, setAssets] = import_react73.useState([]);
|
|
283583
|
+
const [viewMode, setViewMode] = import_react73.useState("overview");
|
|
283584
|
+
const [selectedAgentId, setSelectedAgentId] = import_react73.useState(null);
|
|
283585
|
+
const [focusedIndex, setFocusedIndex] = import_react73.useState(0);
|
|
283586
|
+
const [showOrchestratorPanel, setShowOrchestratorPanel] = import_react73.useState(false);
|
|
283587
|
+
const [startTime, setStartTime] = import_react73.useState(null);
|
|
283588
|
+
const pentestAgentList = import_react73.useMemo(() => Object.values(pentestAgents).sort((a, b3) => a.createdAt.getTime() - b3.createdAt.getTime()), [pentestAgents]);
|
|
283589
|
+
const selectedAgent = import_react73.useMemo(() => selectedAgentId ? pentestAgents[selectedAgentId] ?? null : null, [pentestAgents, selectedAgentId]);
|
|
283590
|
+
const { width: termWidth } = useDimensions();
|
|
283457
283591
|
const gridAvailableWidth = showOrchestratorPanel ? Math.floor((termWidth - 4) / 2) - 2 : termWidth - ORCHESTRATOR_PANEL_WIDTH - GRID_OUTER_PADDING;
|
|
283458
283592
|
const gridColumns = Math.max(1, Math.floor((gridAvailableWidth + GRID_GAP) / (CARD_MIN_WIDTH + GRID_GAP)));
|
|
283459
|
-
|
|
283593
|
+
import_react73.useEffect(() => {
|
|
283460
283594
|
async function load2() {
|
|
283461
283595
|
try {
|
|
283462
283596
|
let s2;
|
|
@@ -283502,6 +283636,9 @@ function Pentest({
|
|
|
283502
283636
|
if (attackSurfaceAgents.some((sa) => sa.messages.length > 0)) {
|
|
283503
283637
|
setShowOrchestratorPanel(true);
|
|
283504
283638
|
}
|
|
283639
|
+
if (state.attackSurfaceResults?.summary?.analysisComplete) {
|
|
283640
|
+
setPhase("pentesting");
|
|
283641
|
+
}
|
|
283505
283642
|
startPentest(s2);
|
|
283506
283643
|
}
|
|
283507
283644
|
} else {
|
|
@@ -283514,7 +283651,7 @@ function Pentest({
|
|
|
283514
283651
|
}
|
|
283515
283652
|
load2();
|
|
283516
283653
|
}, [sessionId]);
|
|
283517
|
-
|
|
283654
|
+
import_react73.useEffect(() => {
|
|
283518
283655
|
if (!session)
|
|
283519
283656
|
return;
|
|
283520
283657
|
const assetsPath = join27(session.rootPath, "assets");
|
|
@@ -283537,12 +283674,12 @@ function Pentest({
|
|
|
283537
283674
|
const interval = setInterval(readAssets, 2000);
|
|
283538
283675
|
return () => clearInterval(interval);
|
|
283539
283676
|
}, [session]);
|
|
283540
|
-
|
|
283677
|
+
import_react73.useEffect(() => {
|
|
283541
283678
|
return () => {
|
|
283542
283679
|
abortController?.abort();
|
|
283543
283680
|
};
|
|
283544
283681
|
}, [abortController]);
|
|
283545
|
-
const ensurePentestAgent =
|
|
283682
|
+
const ensurePentestAgent = import_react73.useCallback((subagentId) => {
|
|
283546
283683
|
setPentestAgents((prev) => {
|
|
283547
283684
|
if (prev[subagentId])
|
|
283548
283685
|
return prev;
|
|
@@ -283559,7 +283696,7 @@ function Pentest({
|
|
|
283559
283696
|
};
|
|
283560
283697
|
});
|
|
283561
283698
|
}, []);
|
|
283562
|
-
const handleSubagentSpawn =
|
|
283699
|
+
const handleSubagentSpawn = import_react73.useCallback(({
|
|
283563
283700
|
subagentId,
|
|
283564
283701
|
input
|
|
283565
283702
|
}) => {
|
|
@@ -283579,7 +283716,7 @@ function Pentest({
|
|
|
283579
283716
|
}
|
|
283580
283717
|
}));
|
|
283581
283718
|
}, []);
|
|
283582
|
-
const handleSubagentComplete =
|
|
283719
|
+
const handleSubagentComplete = import_react73.useCallback(({ subagentId, status }) => {
|
|
283583
283720
|
if (!subagentId.startsWith("pentest-agent-"))
|
|
283584
283721
|
return;
|
|
283585
283722
|
setPentestAgents((prev) => {
|
|
@@ -283592,7 +283729,7 @@ function Pentest({
|
|
|
283592
283729
|
};
|
|
283593
283730
|
});
|
|
283594
283731
|
}, []);
|
|
283595
|
-
const appendPanelText =
|
|
283732
|
+
const appendPanelText = import_react73.useCallback((source, text2) => {
|
|
283596
283733
|
if (panelSourceRef.current !== source) {
|
|
283597
283734
|
panelTextRef.current = "";
|
|
283598
283735
|
panelSourceRef.current = source;
|
|
@@ -283617,7 +283754,7 @@ function Pentest({
|
|
|
283617
283754
|
];
|
|
283618
283755
|
});
|
|
283619
283756
|
}, []);
|
|
283620
|
-
const appendPentestText =
|
|
283757
|
+
const appendPentestText = import_react73.useCallback((subagentId, text2) => {
|
|
283621
283758
|
ensurePentestAgent(subagentId);
|
|
283622
283759
|
if (!pentestTextRefs.current[subagentId]) {
|
|
283623
283760
|
pentestTextRefs.current[subagentId] = "";
|
|
@@ -283650,8 +283787,8 @@ function Pentest({
|
|
|
283650
283787
|
};
|
|
283651
283788
|
});
|
|
283652
283789
|
}, [ensurePentestAgent]);
|
|
283653
|
-
const toolArgsDeltaRef =
|
|
283654
|
-
const addPanelStreamingToolCall =
|
|
283790
|
+
const toolArgsDeltaRef = import_react73.useRef(new Map);
|
|
283791
|
+
const addPanelStreamingToolCall = import_react73.useCallback((toolCallId, toolName) => {
|
|
283655
283792
|
panelTextRef.current = "";
|
|
283656
283793
|
panelSourceRef.current = null;
|
|
283657
283794
|
toolArgsDeltaRef.current.set(toolCallId, "");
|
|
@@ -283670,7 +283807,7 @@ function Pentest({
|
|
|
283670
283807
|
return [...prev, msg];
|
|
283671
283808
|
});
|
|
283672
283809
|
}, []);
|
|
283673
|
-
const appendPanelToolCallDelta =
|
|
283810
|
+
const appendPanelToolCallDelta = import_react73.useCallback((toolCallId, argsTextDelta) => {
|
|
283674
283811
|
const prev = toolArgsDeltaRef.current.get(toolCallId) ?? "";
|
|
283675
283812
|
const accumulated = prev + argsTextDelta;
|
|
283676
283813
|
toolArgsDeltaRef.current.set(toolCallId, accumulated);
|
|
@@ -283693,7 +283830,7 @@ function Pentest({
|
|
|
283693
283830
|
return updated;
|
|
283694
283831
|
});
|
|
283695
283832
|
}, []);
|
|
283696
|
-
const addPanelToolCall =
|
|
283833
|
+
const addPanelToolCall = import_react73.useCallback((toolCallId, toolName, args) => {
|
|
283697
283834
|
panelTextRef.current = "";
|
|
283698
283835
|
panelSourceRef.current = null;
|
|
283699
283836
|
toolArgsDeltaRef.current.delete(toolCallId);
|
|
@@ -283725,7 +283862,7 @@ function Pentest({
|
|
|
283725
283862
|
];
|
|
283726
283863
|
});
|
|
283727
283864
|
}, []);
|
|
283728
|
-
const addPentestStreamingToolCall =
|
|
283865
|
+
const addPentestStreamingToolCall = import_react73.useCallback((subagentId, toolCallId, toolName) => {
|
|
283729
283866
|
pentestTextRefs.current[subagentId] = "";
|
|
283730
283867
|
ensurePentestAgent(subagentId);
|
|
283731
283868
|
toolArgsDeltaRef.current.set(toolCallId, "");
|
|
@@ -283750,7 +283887,7 @@ function Pentest({
|
|
|
283750
283887
|
};
|
|
283751
283888
|
});
|
|
283752
283889
|
}, [ensurePentestAgent]);
|
|
283753
|
-
const appendPentestToolCallDelta =
|
|
283890
|
+
const appendPentestToolCallDelta = import_react73.useCallback((subagentId, toolCallId, argsTextDelta) => {
|
|
283754
283891
|
const prev = toolArgsDeltaRef.current.get(toolCallId) ?? "";
|
|
283755
283892
|
const accumulated = prev + argsTextDelta;
|
|
283756
283893
|
toolArgsDeltaRef.current.set(toolCallId, accumulated);
|
|
@@ -283776,7 +283913,7 @@ function Pentest({
|
|
|
283776
283913
|
return { ...agents, [subagentId]: { ...agent, messages: updatedMsgs } };
|
|
283777
283914
|
});
|
|
283778
283915
|
}, []);
|
|
283779
|
-
const addPentestToolCall =
|
|
283916
|
+
const addPentestToolCall = import_react73.useCallback((subagentId, toolCallId, toolName, args) => {
|
|
283780
283917
|
pentestTextRefs.current[subagentId] = "";
|
|
283781
283918
|
ensurePentestAgent(subagentId);
|
|
283782
283919
|
toolArgsDeltaRef.current.delete(toolCallId);
|
|
@@ -283837,12 +283974,12 @@ function Pentest({
|
|
|
283837
283974
|
}
|
|
283838
283975
|
];
|
|
283839
283976
|
};
|
|
283840
|
-
const updatePanelToolResult =
|
|
283977
|
+
const updatePanelToolResult = import_react73.useCallback((toolCallId, toolName, result) => {
|
|
283841
283978
|
panelTextRef.current = "";
|
|
283842
283979
|
panelSourceRef.current = null;
|
|
283843
283980
|
setPanelMessages((prev) => toolResultUpdater(prev, toolCallId, toolName, result));
|
|
283844
283981
|
}, []);
|
|
283845
|
-
const updatePentestToolResult =
|
|
283982
|
+
const updatePentestToolResult = import_react73.useCallback((subagentId, toolCallId, toolName, result) => {
|
|
283846
283983
|
pentestTextRefs.current[subagentId] = "";
|
|
283847
283984
|
setPentestAgents((prev) => {
|
|
283848
283985
|
const agent = prev[subagentId];
|
|
@@ -283857,11 +283994,12 @@ function Pentest({
|
|
|
283857
283994
|
};
|
|
283858
283995
|
});
|
|
283859
283996
|
}, []);
|
|
283860
|
-
const startPentest =
|
|
283861
|
-
setPhase("discovery");
|
|
283997
|
+
const startPentest = import_react73.useCallback(async (s2) => {
|
|
283998
|
+
setPhase((prev) => prev === "pentesting" || prev === "reporting" ? prev : "discovery");
|
|
283862
283999
|
setStartTime(new Date);
|
|
283863
284000
|
setIsExecuting(true);
|
|
283864
|
-
|
|
284001
|
+
const discoveryDone = existsSync26(join27(s2.rootPath, "attack-surface-results.json"));
|
|
284002
|
+
setThinking(!discoveryDone);
|
|
283865
284003
|
const controller = new AbortController;
|
|
283866
284004
|
setAbortController(controller);
|
|
283867
284005
|
try {
|
|
@@ -283984,7 +284122,7 @@ function Pentest({
|
|
|
283984
284122
|
handleSubagentSpawn,
|
|
283985
284123
|
handleSubagentComplete
|
|
283986
284124
|
]);
|
|
283987
|
-
|
|
284125
|
+
import_react73.useEffect(() => {
|
|
283988
284126
|
if (phase === "completed") {
|
|
283989
284127
|
setFocusedIndex(pentestAgentList.length);
|
|
283990
284128
|
}
|
|
@@ -284047,7 +284185,7 @@ function Pentest({
|
|
|
284047
284185
|
}
|
|
284048
284186
|
}
|
|
284049
284187
|
});
|
|
284050
|
-
const openReport =
|
|
284188
|
+
const openReport = import_react73.useCallback(() => {
|
|
284051
284189
|
if (!session)
|
|
284052
284190
|
return;
|
|
284053
284191
|
const err = openSessionReport(session.rootPath);
|
|
@@ -284232,7 +284370,7 @@ function OrchestratorPanel({
|
|
|
284232
284370
|
}) {
|
|
284233
284371
|
const { colors: colors2 } = useTheme();
|
|
284234
284372
|
const isRunning = phase !== "loading" && phase !== "completed" && phase !== "error";
|
|
284235
|
-
const assetSummary =
|
|
284373
|
+
const assetSummary = import_react73.useMemo(() => {
|
|
284236
284374
|
const byType = {};
|
|
284237
284375
|
for (const a of assets) {
|
|
284238
284376
|
const key = a.assetType;
|
|
@@ -284475,13 +284613,13 @@ function AgentCardGrid({
|
|
|
284475
284613
|
onSelectAgent
|
|
284476
284614
|
}) {
|
|
284477
284615
|
const { colors: colors2 } = useTheme();
|
|
284478
|
-
const scrollRef =
|
|
284479
|
-
|
|
284616
|
+
const scrollRef = import_react73.useRef(null);
|
|
284617
|
+
import_react73.useEffect(() => {
|
|
284480
284618
|
const agent = agents[focusedIndex];
|
|
284481
284619
|
if (agent)
|
|
284482
284620
|
scrollToChild(scrollRef.current, agent.id);
|
|
284483
284621
|
}, [focusedIndex, agents]);
|
|
284484
|
-
const rows =
|
|
284622
|
+
const rows = import_react73.useMemo(() => {
|
|
284485
284623
|
const result = [];
|
|
284486
284624
|
for (let i2 = 0;i2 < agents.length; i2 += gridColumns) {
|
|
284487
284625
|
result.push(agents.slice(i2, i2 + gridColumns));
|
|
@@ -284538,14 +284676,14 @@ function AgentCard({
|
|
|
284538
284676
|
completed: colors2.primary,
|
|
284539
284677
|
failed: colors2.error
|
|
284540
284678
|
}[agent.status];
|
|
284541
|
-
const lastActivity =
|
|
284679
|
+
const lastActivity = import_react73.useMemo(() => {
|
|
284542
284680
|
const last = agent.messages[agent.messages.length - 1];
|
|
284543
284681
|
if (!last)
|
|
284544
284682
|
return "Starting...";
|
|
284545
284683
|
const text2 = typeof last.content === "string" ? last.content.replace(/\n/g, " ").trim() : "Working...";
|
|
284546
284684
|
return text2.length > 50 ? text2.substring(0, 47) + "..." : text2;
|
|
284547
284685
|
}, [agent.messages]);
|
|
284548
|
-
const toolCalls =
|
|
284686
|
+
const toolCalls = import_react73.useMemo(() => agent.messages.filter((m4) => m4.role === "tool").length, [agent.messages]);
|
|
284549
284687
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
284550
284688
|
id: agent.id,
|
|
284551
284689
|
flexGrow: 1,
|
|
@@ -284733,8 +284871,8 @@ function MetricsBar({
|
|
|
284733
284871
|
isExecuting
|
|
284734
284872
|
}) {
|
|
284735
284873
|
const { colors: colors2 } = useTheme();
|
|
284736
|
-
const [now2, setNow] =
|
|
284737
|
-
|
|
284874
|
+
const [now2, setNow] = import_react73.useState(Date.now());
|
|
284875
|
+
import_react73.useEffect(() => {
|
|
284738
284876
|
if (!isExecuting)
|
|
284739
284877
|
return;
|
|
284740
284878
|
const interval = setInterval(() => setNow(Date.now()), 1000);
|
|
@@ -284877,7 +285015,7 @@ function MetricsBar({
|
|
|
284877
285015
|
}
|
|
284878
285016
|
|
|
284879
285017
|
// src/tui/components/operator-dashboard/index.tsx
|
|
284880
|
-
var
|
|
285018
|
+
var import_react78 = __toESM(require_react(), 1);
|
|
284881
285019
|
init_session();
|
|
284882
285020
|
|
|
284883
285021
|
// src/core/api/offesecAgent.ts
|
|
@@ -284980,7 +285118,7 @@ function InlineApprovalPrompt2({ approval }) {
|
|
|
284980
285118
|
}
|
|
284981
285119
|
|
|
284982
285120
|
// src/tui/components/chat/loading-indicator.tsx
|
|
284983
|
-
var
|
|
285121
|
+
var import_react75 = __toESM(require_react(), 1);
|
|
284984
285122
|
var SPINNER_FRAMES2 = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
284985
285123
|
var SPINNER_INTERVAL2 = 80;
|
|
284986
285124
|
var DOTS_FRAMES = ["", ".", "..", "..."];
|
|
@@ -284991,15 +285129,15 @@ function LoadingIndicator({
|
|
|
284991
285129
|
toolName
|
|
284992
285130
|
}) {
|
|
284993
285131
|
const { colors: colors2 } = useTheme();
|
|
284994
|
-
const [spinnerFrame, setSpinnerFrame] =
|
|
284995
|
-
const [dotsFrame, setDotsFrame] =
|
|
284996
|
-
|
|
285132
|
+
const [spinnerFrame, setSpinnerFrame] = import_react75.useState(0);
|
|
285133
|
+
const [dotsFrame, setDotsFrame] = import_react75.useState(0);
|
|
285134
|
+
import_react75.useEffect(() => {
|
|
284997
285135
|
const interval = setInterval(() => {
|
|
284998
285136
|
setSpinnerFrame((f3) => (f3 + 1) % SPINNER_FRAMES2.length);
|
|
284999
285137
|
}, SPINNER_INTERVAL2);
|
|
285000
285138
|
return () => clearInterval(interval);
|
|
285001
285139
|
}, []);
|
|
285002
|
-
|
|
285140
|
+
import_react75.useEffect(() => {
|
|
285003
285141
|
const interval = setInterval(() => {
|
|
285004
285142
|
setDotsFrame((f3) => (f3 + 1) % DOTS_FRAMES.length);
|
|
285005
285143
|
}, DOTS_INTERVAL);
|
|
@@ -285253,7 +285391,7 @@ function MessageList({
|
|
|
285253
285391
|
}
|
|
285254
285392
|
|
|
285255
285393
|
// src/tui/components/chat/input-area.tsx
|
|
285256
|
-
var
|
|
285394
|
+
var import_react76 = __toESM(require_react(), 1);
|
|
285257
285395
|
function NormalInputAreaInner({
|
|
285258
285396
|
value,
|
|
285259
285397
|
onChange,
|
|
@@ -285275,10 +285413,10 @@ function NormalInputAreaInner({
|
|
|
285275
285413
|
}) {
|
|
285276
285414
|
const { colors: colors2, theme, mode: colorMode } = useTheme();
|
|
285277
285415
|
const { inputValue, setInputValue } = useInput();
|
|
285278
|
-
const promptRef =
|
|
285279
|
-
const isExternalUpdate =
|
|
285280
|
-
const prevValueRef =
|
|
285281
|
-
|
|
285416
|
+
const promptRef = import_react76.useRef(null);
|
|
285417
|
+
const isExternalUpdate = import_react76.useRef(false);
|
|
285418
|
+
const prevValueRef = import_react76.useRef(value);
|
|
285419
|
+
import_react76.useEffect(() => {
|
|
285282
285420
|
const prevValue = prevValueRef.current;
|
|
285283
285421
|
prevValueRef.current = value;
|
|
285284
285422
|
if (value !== prevValue && value !== inputValue) {
|
|
@@ -285287,7 +285425,7 @@ function NormalInputAreaInner({
|
|
|
285287
285425
|
promptRef.current?.setValue(value);
|
|
285288
285426
|
}
|
|
285289
285427
|
}, [value, inputValue, setInputValue]);
|
|
285290
|
-
|
|
285428
|
+
import_react76.useEffect(() => {
|
|
285291
285429
|
if (isExternalUpdate.current) {
|
|
285292
285430
|
isExternalUpdate.current = false;
|
|
285293
285431
|
return;
|
|
@@ -285462,7 +285600,7 @@ function ApprovalInputArea2({
|
|
|
285462
285600
|
lastDeclineNote
|
|
285463
285601
|
}) {
|
|
285464
285602
|
const { colors: colors2 } = useTheme();
|
|
285465
|
-
const [focusedElement, setFocusedElement] =
|
|
285603
|
+
const [focusedElement, setFocusedElement] = import_react76.useState(0);
|
|
285466
285604
|
useKeyboard((key) => {
|
|
285467
285605
|
if (key.name === "up") {
|
|
285468
285606
|
setFocusedElement((prev) => Math.max(0, prev - 1));
|
|
@@ -285789,29 +285927,29 @@ function OperatorDashboard({
|
|
|
285789
285927
|
clear: clearDialog,
|
|
285790
285928
|
setSize: setDialogSize
|
|
285791
285929
|
} = useDialog();
|
|
285792
|
-
const autocompleteOptions =
|
|
285930
|
+
const autocompleteOptions = import_react78.useMemo(() => {
|
|
285793
285931
|
const skillSlugs = new Set(skills.map((s2) => `/${slugify(s2.name)}`));
|
|
285794
285932
|
return filterOperatorAutocomplete(allAutocompleteOptions, skillSlugs);
|
|
285795
285933
|
}, [allAutocompleteOptions, skills]);
|
|
285796
|
-
const [session, setSession] =
|
|
285797
|
-
const [loading, setLoading] =
|
|
285798
|
-
const [error40, setError] =
|
|
285799
|
-
const pendingNameRef =
|
|
285800
|
-
const [status, setStatus] =
|
|
285801
|
-
const abortControllerRef =
|
|
285802
|
-
const generationRef =
|
|
285803
|
-
const cancelHandleRef =
|
|
285934
|
+
const [session, setSession] = import_react78.useState(null);
|
|
285935
|
+
const [loading, setLoading] = import_react78.useState(true);
|
|
285936
|
+
const [error40, setError] = import_react78.useState(null);
|
|
285937
|
+
const pendingNameRef = import_react78.useRef(null);
|
|
285938
|
+
const [status, setStatus] = import_react78.useState("idle");
|
|
285939
|
+
const abortControllerRef = import_react78.useRef(null);
|
|
285940
|
+
const generationRef = import_react78.useRef(0);
|
|
285941
|
+
const cancelHandleRef = import_react78.useRef({
|
|
285804
285942
|
cancel: () => false
|
|
285805
285943
|
});
|
|
285806
|
-
const commandCancelledRef =
|
|
285807
|
-
const [messages, setMessages] =
|
|
285808
|
-
const textRef =
|
|
285809
|
-
const conversationRef =
|
|
285810
|
-
const [inputValue, setInputValue] =
|
|
285811
|
-
const [queuedMessages, setQueuedMessages] =
|
|
285812
|
-
const [selectedQueueIndex, setSelectedQueueIndex] =
|
|
285813
|
-
const queuedMessagesRef =
|
|
285814
|
-
|
|
285944
|
+
const commandCancelledRef = import_react78.useRef(false);
|
|
285945
|
+
const [messages, setMessages] = import_react78.useState([]);
|
|
285946
|
+
const textRef = import_react78.useRef("");
|
|
285947
|
+
const conversationRef = import_react78.useRef([]);
|
|
285948
|
+
const [inputValue, setInputValue] = import_react78.useState("");
|
|
285949
|
+
const [queuedMessages, setQueuedMessages] = import_react78.useState([]);
|
|
285950
|
+
const [selectedQueueIndex, setSelectedQueueIndex] = import_react78.useState(-1);
|
|
285951
|
+
const queuedMessagesRef = import_react78.useRef([]);
|
|
285952
|
+
import_react78.useEffect(() => {
|
|
285815
285953
|
queuedMessagesRef.current = queuedMessages;
|
|
285816
285954
|
if (queuedMessages.length === 0) {
|
|
285817
285955
|
setSelectedQueueIndex(-1);
|
|
@@ -285819,17 +285957,17 @@ function OperatorDashboard({
|
|
|
285819
285957
|
setSelectedQueueIndex(queuedMessages.length - 1);
|
|
285820
285958
|
}
|
|
285821
285959
|
}, [queuedMessages, selectedQueueIndex]);
|
|
285822
|
-
const [operatorState, setOperatorState] =
|
|
285823
|
-
const approvalGateRef =
|
|
285824
|
-
const [pendingApprovals, setPendingApprovals] =
|
|
285825
|
-
const [lastApprovedAction, setLastApprovedAction] =
|
|
285826
|
-
const [verboseMode, setVerboseMode] =
|
|
285827
|
-
const [expandedLogs, setExpandedLogs] =
|
|
285828
|
-
const tokenUsageRef =
|
|
285829
|
-
|
|
285960
|
+
const [operatorState, setOperatorState] = import_react78.useState(() => createInitialOperatorState("manual", true));
|
|
285961
|
+
const approvalGateRef = import_react78.useRef(new ApprovalGate({ requireApproval: true }));
|
|
285962
|
+
const [pendingApprovals, setPendingApprovals] = import_react78.useState([]);
|
|
285963
|
+
const [lastApprovedAction, setLastApprovedAction] = import_react78.useState(null);
|
|
285964
|
+
const [verboseMode, setVerboseMode] = import_react78.useState(false);
|
|
285965
|
+
const [expandedLogs, setExpandedLogs] = import_react78.useState(false);
|
|
285966
|
+
const tokenUsageRef = import_react78.useRef(tokenUsage);
|
|
285967
|
+
import_react78.useEffect(() => {
|
|
285830
285968
|
tokenUsageRef.current = tokenUsage;
|
|
285831
285969
|
}, [tokenUsage]);
|
|
285832
|
-
|
|
285970
|
+
import_react78.useEffect(() => {
|
|
285833
285971
|
const gate = approvalGateRef.current;
|
|
285834
285972
|
const onApprovalNeeded = () => {
|
|
285835
285973
|
setPendingApprovals(gate.getPendingApprovals());
|
|
@@ -285851,7 +285989,7 @@ function OperatorDashboard({
|
|
|
285851
285989
|
gate.off("approval-resolved", onApprovalResolved);
|
|
285852
285990
|
};
|
|
285853
285991
|
}, []);
|
|
285854
|
-
|
|
285992
|
+
import_react78.useEffect(() => {
|
|
285855
285993
|
async function loadSession() {
|
|
285856
285994
|
try {
|
|
285857
285995
|
if (sessionId) {
|
|
@@ -285908,10 +286046,10 @@ function OperatorDashboard({
|
|
|
285908
286046
|
}
|
|
285909
286047
|
loadSession();
|
|
285910
286048
|
}, [sessionId]);
|
|
285911
|
-
|
|
286049
|
+
import_react78.useEffect(() => {
|
|
285912
286050
|
return () => setSessionCwd(null);
|
|
285913
286051
|
}, [setSessionCwd]);
|
|
285914
|
-
|
|
286052
|
+
import_react78.useEffect(() => {
|
|
285915
286053
|
if (!session)
|
|
285916
286054
|
return;
|
|
285917
286055
|
resetTokenUsage();
|
|
@@ -285929,7 +286067,7 @@ function OperatorDashboard({
|
|
|
285929
286067
|
});
|
|
285930
286068
|
} catch {}
|
|
285931
286069
|
}, [session, addTokenUsage, resetTokenUsage]);
|
|
285932
|
-
const appendText =
|
|
286070
|
+
const appendText = import_react78.useCallback((text2) => {
|
|
285933
286071
|
textRef.current += text2;
|
|
285934
286072
|
const accumulated = textRef.current;
|
|
285935
286073
|
setMessages((prev) => {
|
|
@@ -285945,8 +286083,8 @@ function OperatorDashboard({
|
|
|
285945
286083
|
];
|
|
285946
286084
|
});
|
|
285947
286085
|
}, []);
|
|
285948
|
-
const toolArgsDeltaRef =
|
|
285949
|
-
const addStreamingToolCall =
|
|
286086
|
+
const toolArgsDeltaRef = import_react78.useRef(new Map);
|
|
286087
|
+
const addStreamingToolCall = import_react78.useCallback((toolCallId, toolName) => {
|
|
285950
286088
|
textRef.current = "";
|
|
285951
286089
|
toolArgsDeltaRef.current.set(toolCallId, {
|
|
285952
286090
|
toolName,
|
|
@@ -285965,7 +286103,7 @@ function OperatorDashboard({
|
|
|
285965
286103
|
}
|
|
285966
286104
|
]);
|
|
285967
286105
|
}, []);
|
|
285968
|
-
const appendToolCallDelta =
|
|
286106
|
+
const appendToolCallDelta = import_react78.useCallback((toolCallId, argsTextDelta) => {
|
|
285969
286107
|
const entry = toolArgsDeltaRef.current.get(toolCallId);
|
|
285970
286108
|
const accumulated = (entry?.accumulated ?? "") + argsTextDelta;
|
|
285971
286109
|
toolArgsDeltaRef.current.set(toolCallId, {
|
|
@@ -285987,7 +286125,7 @@ function OperatorDashboard({
|
|
|
285987
286125
|
return updated;
|
|
285988
286126
|
});
|
|
285989
286127
|
}, []);
|
|
285990
|
-
const addToolCall =
|
|
286128
|
+
const addToolCall = import_react78.useCallback((toolCallId, toolName, args) => {
|
|
285991
286129
|
textRef.current = "";
|
|
285992
286130
|
toolArgsDeltaRef.current.delete(toolCallId);
|
|
285993
286131
|
setMessages((prev) => {
|
|
@@ -286016,7 +286154,7 @@ function OperatorDashboard({
|
|
|
286016
286154
|
];
|
|
286017
286155
|
});
|
|
286018
286156
|
}, []);
|
|
286019
|
-
const updateToolResult =
|
|
286157
|
+
const updateToolResult = import_react78.useCallback((toolCallId, _toolName, result) => {
|
|
286020
286158
|
textRef.current = "";
|
|
286021
286159
|
setMessages((prev) => {
|
|
286022
286160
|
const idx = prev.findIndex((m4) => isToolMessage(m4) && m4.toolCallId === toolCallId);
|
|
@@ -286027,10 +286165,10 @@ function OperatorDashboard({
|
|
|
286027
286165
|
return updated;
|
|
286028
286166
|
});
|
|
286029
286167
|
}, []);
|
|
286030
|
-
const cmdOutputBufRef =
|
|
286031
|
-
const cmdFlushTimerRef =
|
|
286168
|
+
const cmdOutputBufRef = import_react78.useRef("");
|
|
286169
|
+
const cmdFlushTimerRef = import_react78.useRef(null);
|
|
286032
286170
|
const MAX_LOG_LINES = 200;
|
|
286033
|
-
const flushCommandOutput =
|
|
286171
|
+
const flushCommandOutput = import_react78.useCallback(() => {
|
|
286034
286172
|
const buf = cmdOutputBufRef.current;
|
|
286035
286173
|
if (!buf)
|
|
286036
286174
|
return;
|
|
@@ -286060,7 +286198,7 @@ function OperatorDashboard({
|
|
|
286060
286198
|
return updated;
|
|
286061
286199
|
});
|
|
286062
286200
|
}, []);
|
|
286063
|
-
const onCommandOutput =
|
|
286201
|
+
const onCommandOutput = import_react78.useCallback((data) => {
|
|
286064
286202
|
cmdOutputBufRef.current += data;
|
|
286065
286203
|
if (!cmdFlushTimerRef.current) {
|
|
286066
286204
|
cmdFlushTimerRef.current = setInterval(() => {
|
|
@@ -286068,7 +286206,7 @@ function OperatorDashboard({
|
|
|
286068
286206
|
}, 150);
|
|
286069
286207
|
}
|
|
286070
286208
|
}, [flushCommandOutput]);
|
|
286071
|
-
|
|
286209
|
+
import_react78.useEffect(() => {
|
|
286072
286210
|
return () => {
|
|
286073
286211
|
if (cmdFlushTimerRef.current) {
|
|
286074
286212
|
clearInterval(cmdFlushTimerRef.current);
|
|
@@ -286076,7 +286214,7 @@ function OperatorDashboard({
|
|
|
286076
286214
|
}
|
|
286077
286215
|
};
|
|
286078
286216
|
}, []);
|
|
286079
|
-
const appendLogToActiveTool =
|
|
286217
|
+
const appendLogToActiveTool = import_react78.useCallback((line) => {
|
|
286080
286218
|
setMessages((prev) => {
|
|
286081
286219
|
const idx = prev.findLastIndex((m4) => isToolMessage(m4) && (m4.status === "pending" || m4.status === "streaming"));
|
|
286082
286220
|
if (idx === -1)
|
|
@@ -286091,7 +286229,7 @@ function OperatorDashboard({
|
|
|
286091
286229
|
return updated;
|
|
286092
286230
|
});
|
|
286093
286231
|
}, []);
|
|
286094
|
-
const initSubagent =
|
|
286232
|
+
const initSubagent = import_react78.useCallback((subagentId, name26) => {
|
|
286095
286233
|
setMessages((prev) => {
|
|
286096
286234
|
const idx = prev.findLastIndex((m4) => isToolMessage(m4) && (m4.status === "pending" || m4.status === "streaming"));
|
|
286097
286235
|
if (idx === -1)
|
|
@@ -286106,7 +286244,7 @@ function OperatorDashboard({
|
|
|
286106
286244
|
return updated;
|
|
286107
286245
|
});
|
|
286108
286246
|
}, []);
|
|
286109
|
-
const completeSubagent =
|
|
286247
|
+
const completeSubagent = import_react78.useCallback((subagentId, status2) => {
|
|
286110
286248
|
setMessages((prev) => {
|
|
286111
286249
|
const idx = prev.findLastIndex((m4) => isToolMessage(m4) && (m4.status === "pending" || m4.status === "streaming"));
|
|
286112
286250
|
if (idx === -1)
|
|
@@ -286124,7 +286262,7 @@ function OperatorDashboard({
|
|
|
286124
286262
|
return updated;
|
|
286125
286263
|
});
|
|
286126
286264
|
}, []);
|
|
286127
|
-
const appendLogToSubagent =
|
|
286265
|
+
const appendLogToSubagent = import_react78.useCallback((subagentId, line) => {
|
|
286128
286266
|
setMessages((prev) => {
|
|
286129
286267
|
const idx = prev.findLastIndex((m4) => isToolMessage(m4) && (m4.status === "pending" || m4.status === "streaming"));
|
|
286130
286268
|
if (idx === -1)
|
|
@@ -286146,13 +286284,13 @@ function OperatorDashboard({
|
|
|
286146
286284
|
return updated;
|
|
286147
286285
|
});
|
|
286148
286286
|
}, []);
|
|
286149
|
-
const handleApprove =
|
|
286287
|
+
const handleApprove = import_react78.useCallback(() => {
|
|
286150
286288
|
const pending = approvalGateRef.current.getPendingApprovals();
|
|
286151
286289
|
if (pending.length > 0) {
|
|
286152
286290
|
approvalGateRef.current.approve(pending[0].id);
|
|
286153
286291
|
}
|
|
286154
286292
|
}, []);
|
|
286155
|
-
const handleAutoApprove =
|
|
286293
|
+
const handleAutoApprove = import_react78.useCallback(() => {
|
|
286156
286294
|
approvalGateRef.current.updateConfig({ requireApproval: false });
|
|
286157
286295
|
setOperatorState((prev) => ({ ...prev, requireApproval: false }));
|
|
286158
286296
|
const pending = approvalGateRef.current.getPendingApprovals();
|
|
@@ -286160,7 +286298,7 @@ function OperatorDashboard({
|
|
|
286160
286298
|
approvalGateRef.current.approve(p.id);
|
|
286161
286299
|
}
|
|
286162
286300
|
}, []);
|
|
286163
|
-
const runAgent =
|
|
286301
|
+
const runAgent = import_react78.useCallback(async (prompt) => {
|
|
286164
286302
|
if (abortControllerRef.current) {
|
|
286165
286303
|
abortControllerRef.current.abort();
|
|
286166
286304
|
abortControllerRef.current = null;
|
|
@@ -286374,7 +286512,7 @@ function OperatorDashboard({
|
|
|
286374
286512
|
setThinking,
|
|
286375
286513
|
setIsExecuting
|
|
286376
286514
|
]);
|
|
286377
|
-
const handleSubmit =
|
|
286515
|
+
const handleSubmit = import_react78.useCallback((value) => {
|
|
286378
286516
|
const pending = approvalGateRef.current.getPendingApprovals();
|
|
286379
286517
|
const result = resolveSubmit(value, status, pending.length > 0);
|
|
286380
286518
|
if (result.denyPending) {
|
|
@@ -286392,16 +286530,16 @@ function OperatorDashboard({
|
|
|
286392
286530
|
setInputValue("");
|
|
286393
286531
|
runAgent(result.prompt);
|
|
286394
286532
|
}, [status, runAgent]);
|
|
286395
|
-
const initialMessageSentRef =
|
|
286396
|
-
const runAgentRef =
|
|
286533
|
+
const initialMessageSentRef = import_react78.useRef(false);
|
|
286534
|
+
const runAgentRef = import_react78.useRef(runAgent);
|
|
286397
286535
|
runAgentRef.current = runAgent;
|
|
286398
|
-
|
|
286536
|
+
import_react78.useEffect(() => {
|
|
286399
286537
|
if (!loading && initialMessage && !initialMessageSentRef.current) {
|
|
286400
286538
|
initialMessageSentRef.current = true;
|
|
286401
286539
|
runAgentRef.current(initialMessage);
|
|
286402
286540
|
}
|
|
286403
286541
|
}, [loading, initialMessage]);
|
|
286404
|
-
|
|
286542
|
+
import_react78.useEffect(() => {
|
|
286405
286543
|
if (status !== "idle")
|
|
286406
286544
|
return;
|
|
286407
286545
|
const queue = queuedMessagesRef.current;
|
|
@@ -286412,7 +286550,7 @@ function OperatorDashboard({
|
|
|
286412
286550
|
setSelectedQueueIndex(-1);
|
|
286413
286551
|
runAgentRef.current(next);
|
|
286414
286552
|
}, [status]);
|
|
286415
|
-
const showModelPicker =
|
|
286553
|
+
const showModelPicker = import_react78.useCallback(() => {
|
|
286416
286554
|
setDialogSize("large");
|
|
286417
286555
|
showDialog(/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
286418
286556
|
flexDirection: "column",
|
|
@@ -286474,7 +286612,7 @@ function OperatorDashboard({
|
|
|
286474
286612
|
clearDialog,
|
|
286475
286613
|
setDialogSize
|
|
286476
286614
|
]);
|
|
286477
|
-
const handleCommandExecute =
|
|
286615
|
+
const handleCommandExecute = import_react78.useCallback(async (command) => {
|
|
286478
286616
|
const action = routeCommand(command, resolveSkillContent);
|
|
286479
286617
|
switch (action.type) {
|
|
286480
286618
|
case "show-models":
|
|
@@ -286492,7 +286630,7 @@ function OperatorDashboard({
|
|
|
286492
286630
|
return;
|
|
286493
286631
|
}
|
|
286494
286632
|
}, [resolveSkillContent, handleSubmit, executeCommand2, showModelPicker]);
|
|
286495
|
-
const handleAbort =
|
|
286633
|
+
const handleAbort = import_react78.useCallback(() => {
|
|
286496
286634
|
if (!abortControllerRef.current)
|
|
286497
286635
|
return;
|
|
286498
286636
|
const action = resolveAbortAction(commandCancelledRef.current, () => cancelHandleRef.current.cancel());
|
|
@@ -286542,7 +286680,7 @@ function OperatorDashboard({
|
|
|
286542
286680
|
];
|
|
286543
286681
|
});
|
|
286544
286682
|
}, [session, setThinking, setIsExecuting]);
|
|
286545
|
-
const toggleApproval =
|
|
286683
|
+
const toggleApproval = import_react78.useCallback(() => {
|
|
286546
286684
|
setOperatorState((prev) => {
|
|
286547
286685
|
const newVal = !prev.requireApproval;
|
|
286548
286686
|
approvalGateRef.current.updateConfig({ requireApproval: newVal });
|
|
@@ -286776,10 +286914,10 @@ function OperatorDashboard({
|
|
|
286776
286914
|
}
|
|
286777
286915
|
|
|
286778
286916
|
// src/tui/components/commands/theme-picker.tsx
|
|
286779
|
-
var
|
|
286917
|
+
var import_react80 = __toESM(require_react(), 1);
|
|
286780
286918
|
init_config2();
|
|
286781
286919
|
function ThemePicker({ onClose }) {
|
|
286782
|
-
const dimensions =
|
|
286920
|
+
const dimensions = useDimensions();
|
|
286783
286921
|
const {
|
|
286784
286922
|
colors: colors2,
|
|
286785
286923
|
theme,
|
|
@@ -286789,15 +286927,15 @@ function ThemePicker({ onClose }) {
|
|
|
286789
286927
|
toggleMode,
|
|
286790
286928
|
setMode
|
|
286791
286929
|
} = useTheme();
|
|
286792
|
-
const [selectedIndex, setSelectedIndex] =
|
|
286793
|
-
const originalThemeRef =
|
|
286794
|
-
const originalModeRef =
|
|
286795
|
-
const handleClose =
|
|
286930
|
+
const [selectedIndex, setSelectedIndex] = import_react80.useState(() => Math.max(0, availableThemes.indexOf(theme.name)));
|
|
286931
|
+
const originalThemeRef = import_react80.useRef(theme.name);
|
|
286932
|
+
const originalModeRef = import_react80.useRef(mode);
|
|
286933
|
+
const handleClose = import_react80.useCallback(() => {
|
|
286796
286934
|
setTheme(originalThemeRef.current);
|
|
286797
286935
|
setMode(originalModeRef.current);
|
|
286798
286936
|
onClose();
|
|
286799
286937
|
}, [setTheme, setMode, onClose]);
|
|
286800
|
-
const handleConfirm =
|
|
286938
|
+
const handleConfirm = import_react80.useCallback(async () => {
|
|
286801
286939
|
const currentThemeName = availableThemes[selectedIndex];
|
|
286802
286940
|
if (currentThemeName) {
|
|
286803
286941
|
await config2.update({ theme: currentThemeName });
|
|
@@ -286926,16 +287064,16 @@ function ThemePicker({ onClose }) {
|
|
|
286926
287064
|
}
|
|
286927
287065
|
|
|
286928
287066
|
// src/tui/components/commands/create-skill-wizard.tsx
|
|
286929
|
-
var
|
|
287067
|
+
var import_react82 = __toESM(require_react(), 1);
|
|
286930
287068
|
function CreateSkillWizard() {
|
|
286931
287069
|
const { colors: colors2 } = useTheme();
|
|
286932
287070
|
const route = useRoute();
|
|
286933
|
-
const [step, setStep] =
|
|
286934
|
-
const [name26, setName] =
|
|
286935
|
-
const [description, setDescription] =
|
|
286936
|
-
const [content, setContent] =
|
|
286937
|
-
const [error40, setError] =
|
|
286938
|
-
const [confirmFocused, setConfirmFocused] =
|
|
287071
|
+
const [step, setStep] = import_react82.useState("name");
|
|
287072
|
+
const [name26, setName] = import_react82.useState("");
|
|
287073
|
+
const [description, setDescription] = import_react82.useState("");
|
|
287074
|
+
const [content, setContent] = import_react82.useState("");
|
|
287075
|
+
const [error40, setError] = import_react82.useState(null);
|
|
287076
|
+
const [confirmFocused, setConfirmFocused] = import_react82.useState(0);
|
|
286939
287077
|
const slug = slugify(name26);
|
|
286940
287078
|
async function handleSave() {
|
|
286941
287079
|
if (!name26.trim() || !content.trim())
|
|
@@ -289811,7 +289949,7 @@ async function detectTerminalMode(timeoutMs = 1000) {
|
|
|
289811
289949
|
}
|
|
289812
289950
|
|
|
289813
289951
|
// src/tui/console-theme.ts
|
|
289814
|
-
var
|
|
289952
|
+
var import_react84 = __toESM(require_react(), 1);
|
|
289815
289953
|
var withAlpha = (rgba, a) => RGBA.fromValues(rgba.r, rgba.g, rgba.b, a);
|
|
289816
289954
|
var overlayThemeRef = {
|
|
289817
289955
|
current: null
|
|
@@ -289834,7 +289972,7 @@ function buildConsoleOptions(themeColors) {
|
|
|
289834
289972
|
function ConsoleThemeSync() {
|
|
289835
289973
|
const { colors: colors2 } = useTheme();
|
|
289836
289974
|
const renderer = useRenderer();
|
|
289837
|
-
|
|
289975
|
+
import_react84.useEffect(() => {
|
|
289838
289976
|
overlayThemeRef.current = colors2;
|
|
289839
289977
|
const c = renderer.console;
|
|
289840
289978
|
c.backgroundColor = withAlpha(colors2.backgroundPanel, 0.85);
|
|
@@ -289922,17 +290060,17 @@ function setupAutoCopy(renderer, copyToClipboard) {
|
|
|
289922
290060
|
|
|
289923
290061
|
// src/tui/index.tsx
|
|
289924
290062
|
function App({ appConfig }) {
|
|
289925
|
-
const [focusIndex, setFocusIndex] =
|
|
289926
|
-
const [cwd, setCwd] =
|
|
289927
|
-
const [ctrlCPressTime, setCtrlCPressTime] =
|
|
289928
|
-
const [showExitWarning, setShowExitWarning] =
|
|
289929
|
-
const [inputKey, setInputKey] =
|
|
289930
|
-
const [showSessionsDialog, setShowSessionsDialog] =
|
|
289931
|
-
const [showShortcutsDialog, setShowShortcutsDialog] =
|
|
289932
|
-
const [showThemeDialog, setShowThemeDialog] =
|
|
289933
|
-
const [showAuthDialog, setShowAuthDialog] =
|
|
289934
|
-
const [showPentestDialog, setShowPentestDialog] =
|
|
289935
|
-
const [pendingPentestFlags, setPendingPentestFlags] =
|
|
290063
|
+
const [focusIndex, setFocusIndex] = import_react87.useState(0);
|
|
290064
|
+
const [cwd, setCwd] = import_react87.useState(process.cwd());
|
|
290065
|
+
const [ctrlCPressTime, setCtrlCPressTime] = import_react87.useState(null);
|
|
290066
|
+
const [showExitWarning, setShowExitWarning] = import_react87.useState(false);
|
|
290067
|
+
const [inputKey, setInputKey] = import_react87.useState(0);
|
|
290068
|
+
const [showSessionsDialog, setShowSessionsDialog] = import_react87.useState(false);
|
|
290069
|
+
const [showShortcutsDialog, setShowShortcutsDialog] = import_react87.useState(false);
|
|
290070
|
+
const [showThemeDialog, setShowThemeDialog] = import_react87.useState(false);
|
|
290071
|
+
const [showAuthDialog, setShowAuthDialog] = import_react87.useState(false);
|
|
290072
|
+
const [showPentestDialog, setShowPentestDialog] = import_react87.useState(false);
|
|
290073
|
+
const [pendingPentestFlags, setPendingPentestFlags] = import_react87.useState(undefined);
|
|
289936
290074
|
const navigableItems = ["command-input"];
|
|
289937
290075
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ConfigProvider, {
|
|
289938
290076
|
config: appConfig,
|
|
@@ -290019,14 +290157,14 @@ function AppContent({
|
|
|
290019
290157
|
const { toast } = useToast();
|
|
290020
290158
|
const { refocusPrompt } = useFocus();
|
|
290021
290159
|
const { setExternalDialogOpen } = useDialog();
|
|
290022
|
-
|
|
290160
|
+
import_react87.useEffect(() => {
|
|
290023
290161
|
checkForUpdate().then(({ updateAvailable, currentVersion, latestVersion }) => {
|
|
290024
290162
|
if (!updateAvailable)
|
|
290025
290163
|
return;
|
|
290026
290164
|
toast(`Update available: v${currentVersion} → v${latestVersion}. Run: pensar upgrade`, "warn", 8000);
|
|
290027
290165
|
});
|
|
290028
290166
|
}, []);
|
|
290029
|
-
|
|
290167
|
+
import_react87.useEffect(() => {
|
|
290030
290168
|
if (route.data.type !== "base")
|
|
290031
290169
|
return;
|
|
290032
290170
|
if (!config3.data.responsibleUseAccepted && route.data.path !== "disclosure") {
|
|
@@ -290035,12 +290173,12 @@ function AppContent({
|
|
|
290035
290173
|
route.navigate({ type: "base", path: "providers" });
|
|
290036
290174
|
}
|
|
290037
290175
|
}, [config3.data.responsibleUseAccepted, route.data]);
|
|
290038
|
-
|
|
290176
|
+
import_react87.useEffect(() => {
|
|
290039
290177
|
if (showThemeDialog || showAuthDialog || showPentestDialog) {
|
|
290040
290178
|
setExternalDialogOpen(true);
|
|
290041
290179
|
}
|
|
290042
290180
|
}, [showThemeDialog, showAuthDialog, showPentestDialog]);
|
|
290043
|
-
|
|
290181
|
+
import_react87.useEffect(() => {
|
|
290044
290182
|
if (showExitWarning) {
|
|
290045
290183
|
const timer = setTimeout(() => {
|
|
290046
290184
|
setShowExitWarning(false);
|
|
@@ -290294,16 +290432,18 @@ async function main2() {
|
|
|
290294
290432
|
initialMode: mode,
|
|
290295
290433
|
children: [
|
|
290296
290434
|
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ConsoleThemeSync, {}, undefined, false, undefined, this),
|
|
290297
|
-
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(
|
|
290298
|
-
children:
|
|
290299
|
-
|
|
290300
|
-
|
|
290301
|
-
|
|
290302
|
-
|
|
290303
|
-
|
|
290304
|
-
|
|
290305
|
-
|
|
290306
|
-
|
|
290435
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(TerminalDimensionsProvider, {
|
|
290436
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ToastProvider, {
|
|
290437
|
+
children: [
|
|
290438
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ErrorBoundary2, {
|
|
290439
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(App, {
|
|
290440
|
+
appConfig
|
|
290441
|
+
}, undefined, false, undefined, this)
|
|
290442
|
+
}, undefined, false, undefined, this),
|
|
290443
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ToastContainer, {}, undefined, false, undefined, this)
|
|
290444
|
+
]
|
|
290445
|
+
}, undefined, true, undefined, this)
|
|
290446
|
+
}, undefined, false, undefined, this)
|
|
290307
290447
|
]
|
|
290308
290448
|
}, undefined, true, undefined, this));
|
|
290309
290449
|
}
|