@pensar/apex 0.0.88-canary.2b93505f → 0.0.88
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 +402 -174
- 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.88
|
|
31974
|
+
version: "0.0.88",
|
|
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",
|
|
@@ -88478,6 +88478,7 @@ Summary: ${summary}
|
|
|
88478
88478
|
Original task: Please respond based on this summary.` : `${opts.prompt}
|
|
88479
88479
|
|
|
88480
88480
|
The previous agent has summarized the conversation to pass to you to continue the task. Here is the summary: ${summary}`;
|
|
88481
|
+
opts.onSummarized?.(summary);
|
|
88481
88482
|
const resumed = streamResponse({
|
|
88482
88483
|
...opts,
|
|
88483
88484
|
prompt: enhancedPrompt,
|
|
@@ -89152,6 +89153,20 @@ function hasOperatorState(session) {
|
|
|
89152
89153
|
const statePath = path5.join(session.rootPath, "messages.json");
|
|
89153
89154
|
return existsSync3(statePath);
|
|
89154
89155
|
}
|
|
89156
|
+
function getResumeMessages(messages, limit = MAX_RESUME_MESSAGES) {
|
|
89157
|
+
if (messages.length <= limit)
|
|
89158
|
+
return messages;
|
|
89159
|
+
let cutIndex = messages.length - limit;
|
|
89160
|
+
while (cutIndex < messages.length) {
|
|
89161
|
+
if (messages[cutIndex].role === "user")
|
|
89162
|
+
break;
|
|
89163
|
+
cutIndex++;
|
|
89164
|
+
}
|
|
89165
|
+
if (cutIndex >= messages.length) {
|
|
89166
|
+
cutIndex = messages.length - limit;
|
|
89167
|
+
}
|
|
89168
|
+
return messages.slice(cutIndex);
|
|
89169
|
+
}
|
|
89155
89170
|
async function updateOperatorSettings(sessionId, settings) {
|
|
89156
89171
|
return await update3(sessionId, (session) => {
|
|
89157
89172
|
if (!session.config) {
|
|
@@ -89224,7 +89239,7 @@ var DEFAULT_OUTCOME_GUIDANCE, EXFIL_OUTCOME_GUIDANCE, DEFAULT_OFFENSIVE_HEADERS,
|
|
|
89224
89239
|
input.messageId
|
|
89225
89240
|
]);
|
|
89226
89241
|
return input.messageId;
|
|
89227
|
-
}, sessions;
|
|
89242
|
+
}, MAX_RESUME_MESSAGES = 200, sessions;
|
|
89228
89243
|
var init_session = __esm(() => {
|
|
89229
89244
|
init_zod();
|
|
89230
89245
|
init_id();
|
|
@@ -89356,6 +89371,7 @@ var init_session = __esm(() => {
|
|
|
89356
89371
|
removeMessage,
|
|
89357
89372
|
loadOperatorState,
|
|
89358
89373
|
hasOperatorState,
|
|
89374
|
+
getResumeMessages,
|
|
89359
89375
|
updateOperatorSettings,
|
|
89360
89376
|
updateToolsetState,
|
|
89361
89377
|
toggleTool: toggleTool2
|
|
@@ -106964,6 +106980,34 @@ var init_executeCommand = __esm(() => {
|
|
|
106964
106980
|
});
|
|
106965
106981
|
|
|
106966
106982
|
// src/core/agents/offSecAgent/tools/httpRequest.ts
|
|
106983
|
+
import { join as join10 } from "path";
|
|
106984
|
+
import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync6, existsSync as existsSync14 } from "fs";
|
|
106985
|
+
function maybeSaveBody(body, ctx4) {
|
|
106986
|
+
if (body.length <= MAX_INLINE_BODY)
|
|
106987
|
+
return { text: body };
|
|
106988
|
+
const outputDir = join10(ctx4.session.logsPath, "http-responses");
|
|
106989
|
+
if (!existsSync14(outputDir)) {
|
|
106990
|
+
mkdirSync6(outputDir, { recursive: true });
|
|
106991
|
+
}
|
|
106992
|
+
const ts = new Date().toISOString().replace(/[:.]/g, "-");
|
|
106993
|
+
const filename = `response-${ts}.txt`;
|
|
106994
|
+
const filePath = join10(outputDir, filename);
|
|
106995
|
+
try {
|
|
106996
|
+
writeFileSync6(filePath, body);
|
|
106997
|
+
} catch {
|
|
106998
|
+
return {
|
|
106999
|
+
text: `${body.substring(0, MAX_INLINE_BODY)}...
|
|
107000
|
+
|
|
107001
|
+
(truncated — failed to save full response to file)`
|
|
107002
|
+
};
|
|
107003
|
+
}
|
|
107004
|
+
return {
|
|
107005
|
+
text: `${body.substring(0, MAX_INLINE_BODY)}...
|
|
107006
|
+
|
|
107007
|
+
(truncated — full response saved to ${filePath}). Use read_file or grep to analyze.`,
|
|
107008
|
+
file: filePath
|
|
107009
|
+
};
|
|
107010
|
+
}
|
|
106967
107011
|
function parseHeaders(raw) {
|
|
106968
107012
|
if (!raw)
|
|
106969
107013
|
return {};
|
|
@@ -107052,14 +107096,13 @@ COMMON TESTING PATTERNS:
|
|
|
107052
107096
|
} catch {
|
|
107053
107097
|
responseBody = "(unable to read response body)";
|
|
107054
107098
|
}
|
|
107099
|
+
const { text: truncatedBody } = maybeSaveBody(responseBody, ctx4);
|
|
107055
107100
|
return {
|
|
107056
107101
|
success: true,
|
|
107057
107102
|
status: response.status,
|
|
107058
107103
|
statusText: response.statusText,
|
|
107059
107104
|
headers: responseHeaders,
|
|
107060
|
-
body:
|
|
107061
|
-
|
|
107062
|
-
(truncated) use execute_command with grep / tail to paginate the response` : responseBody,
|
|
107105
|
+
body: truncatedBody,
|
|
107063
107106
|
url: response.url,
|
|
107064
107107
|
redirected: response.redirected
|
|
107065
107108
|
};
|
|
@@ -107134,14 +107177,13 @@ async function executeSandboxHttpRequest(ctx4, opts) {
|
|
|
107134
107177
|
const statusText = statusMatch ? statusMatch[2] : "Unknown";
|
|
107135
107178
|
const responseBody = lines.slice(bodyStartIndex).join(`
|
|
107136
107179
|
`);
|
|
107180
|
+
const { text: truncatedBody } = maybeSaveBody(responseBody, ctx4);
|
|
107137
107181
|
return {
|
|
107138
107182
|
success: status >= 200 && status < 400,
|
|
107139
107183
|
status,
|
|
107140
107184
|
statusText,
|
|
107141
107185
|
headers: responseHeaders,
|
|
107142
|
-
body:
|
|
107143
|
-
|
|
107144
|
-
(truncated) use execute_command with grep / tail to paginate the response` : responseBody,
|
|
107186
|
+
body: truncatedBody,
|
|
107145
107187
|
url: url2,
|
|
107146
107188
|
redirected: false
|
|
107147
107189
|
};
|
|
@@ -107159,7 +107201,7 @@ async function executeSandboxHttpRequest(ctx4, opts) {
|
|
|
107159
107201
|
};
|
|
107160
107202
|
}
|
|
107161
107203
|
}
|
|
107162
|
-
var httpRequestInputSchema;
|
|
107204
|
+
var MAX_INLINE_BODY = 5000, httpRequestInputSchema;
|
|
107163
107205
|
var init_httpRequest = __esm(() => {
|
|
107164
107206
|
init_dist5();
|
|
107165
107207
|
init_zod();
|
|
@@ -108030,8 +108072,8 @@ var init_cvssScorer = __esm(() => {
|
|
|
108030
108072
|
});
|
|
108031
108073
|
|
|
108032
108074
|
// src/core/agents/offSecAgent/tools/documentFinding.ts
|
|
108033
|
-
import { join as
|
|
108034
|
-
import { writeFileSync as
|
|
108075
|
+
import { join as join11 } from "path";
|
|
108076
|
+
import { writeFileSync as writeFileSync7, appendFileSync as appendFileSync2 } from "fs";
|
|
108035
108077
|
function documentVulnerability(ctx4) {
|
|
108036
108078
|
const { session } = ctx4;
|
|
108037
108079
|
return tool({
|
|
@@ -108060,8 +108102,8 @@ FINDING STRUCTURE:
|
|
|
108060
108102
|
if (input.evidence.length > EVIDENCE_FILE_THRESHOLD) {
|
|
108061
108103
|
const safeSlug = input.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").substring(0, 40);
|
|
108062
108104
|
const evidenceFilename = `${timestamp.split("T")[0]}-${safeSlug}-evidence.txt`;
|
|
108063
|
-
evidenceFilePath =
|
|
108064
|
-
|
|
108105
|
+
evidenceFilePath = join11(session.findingsPath, evidenceFilename);
|
|
108106
|
+
writeFileSync7(evidenceFilePath, input.evidence);
|
|
108065
108107
|
evidenceForPrompt = input.evidence.substring(0, EVIDENCE_FILE_THRESHOLD) + `
|
|
108066
108108
|
... [truncated — full output saved to ${evidenceFilename}]`;
|
|
108067
108109
|
}
|
|
@@ -108120,11 +108162,11 @@ FINDING STRUCTURE:
|
|
|
108120
108162
|
const safeTitle = finding.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").substring(0, 50);
|
|
108121
108163
|
const findingId = `${timestamp.split("T")[0]}-${safeTitle}`;
|
|
108122
108164
|
const jsonFilename = `${findingId}.json`;
|
|
108123
|
-
const jsonPath =
|
|
108165
|
+
const jsonPath = join11(session.findingsPath, jsonFilename);
|
|
108124
108166
|
const mdFilename = `${findingId}.md`;
|
|
108125
|
-
const mdPath =
|
|
108167
|
+
const mdPath = join11(session.findingsPath, mdFilename);
|
|
108126
108168
|
try {
|
|
108127
|
-
|
|
108169
|
+
writeFileSync7(jsonPath, JSON.stringify(findingWithMeta, null, 2));
|
|
108128
108170
|
const cvssSection = cvssWarning ? `## CVSS 4.0 Assessment
|
|
108129
108171
|
|
|
108130
108172
|
**Warning:** ${cvssWarning}
|
|
@@ -108186,8 +108228,8 @@ ${finding.references}` : ""}
|
|
|
108186
108228
|
|
|
108187
108229
|
*This finding was automatically documented by the Pensar penetration testing agent.*
|
|
108188
108230
|
`;
|
|
108189
|
-
|
|
108190
|
-
const summaryPath =
|
|
108231
|
+
writeFileSync7(mdPath, markdown);
|
|
108232
|
+
const summaryPath = join11(session.rootPath, "findings-summary.md");
|
|
108191
108233
|
const summaryEntry = `- [${finding.severity}] (CVSS ${cvssResult.score}) ${finding.title} - \`findings/${mdFilename}\`
|
|
108192
108234
|
`;
|
|
108193
108235
|
try {
|
|
@@ -108201,7 +108243,7 @@ ${finding.references}` : ""}
|
|
|
108201
108243
|
## All Findings
|
|
108202
108244
|
|
|
108203
108245
|
`;
|
|
108204
|
-
|
|
108246
|
+
writeFileSync7(summaryPath, header + summaryEntry);
|
|
108205
108247
|
}
|
|
108206
108248
|
} catch (writeError) {
|
|
108207
108249
|
if (ctx4.findingsRegistry) {
|
|
@@ -108267,14 +108309,14 @@ var init_documentFinding = __esm(() => {
|
|
|
108267
108309
|
});
|
|
108268
108310
|
|
|
108269
108311
|
// src/core/agents/offSecAgent/tools/createPoc.ts
|
|
108270
|
-
import { join as
|
|
108312
|
+
import { join as join12 } from "path";
|
|
108271
108313
|
import { spawn as spawn2 } from "child_process";
|
|
108272
108314
|
import {
|
|
108273
|
-
existsSync as
|
|
108274
|
-
writeFileSync as
|
|
108315
|
+
existsSync as existsSync15,
|
|
108316
|
+
writeFileSync as writeFileSync8,
|
|
108275
108317
|
chmodSync,
|
|
108276
108318
|
unlinkSync,
|
|
108277
|
-
mkdirSync as
|
|
108319
|
+
mkdirSync as mkdirSync7
|
|
108278
108320
|
} from "fs";
|
|
108279
108321
|
function sanitizeFilename(str) {
|
|
108280
108322
|
return str.toLowerCase().replace(/[^a-z0-9_-]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "").substring(0, 50);
|
|
@@ -108323,12 +108365,12 @@ Max ${MAX_POC_ATTEMPTS} attempts per approach before pivoting.`,
|
|
|
108323
108365
|
async function executeLocalPoc(ctx4, poc, currentAttempts) {
|
|
108324
108366
|
try {
|
|
108325
108367
|
const pocsPath = ctx4.session.pocsPath;
|
|
108326
|
-
if (!
|
|
108327
|
-
|
|
108368
|
+
if (!existsSync15(pocsPath)) {
|
|
108369
|
+
mkdirSync7(pocsPath, { recursive: true });
|
|
108328
108370
|
}
|
|
108329
108371
|
const { filename, pocContent } = preparePoc(poc, currentAttempts);
|
|
108330
|
-
const pocPath =
|
|
108331
|
-
|
|
108372
|
+
const pocPath = join12(pocsPath, filename);
|
|
108373
|
+
writeFileSync8(pocPath, pocContent);
|
|
108332
108374
|
chmodSync(pocPath, 493);
|
|
108333
108375
|
const runner = poc.pocType === "bash" ? "bash" : poc.pocType === "python" ? "python3" : "node";
|
|
108334
108376
|
const { stdout, stderr, exitCode } = await runScript(runner, pocPath, 60000, ctx4.abortSignal);
|
|
@@ -108359,18 +108401,18 @@ async function executeSandboxPoc(ctx4, poc, currentAttempts) {
|
|
|
108359
108401
|
try {
|
|
108360
108402
|
const { filename, pocContent } = preparePoc(poc, currentAttempts);
|
|
108361
108403
|
const localPocsPath = ctx4.session.pocsPath;
|
|
108362
|
-
if (!
|
|
108363
|
-
|
|
108404
|
+
if (!existsSync15(localPocsPath)) {
|
|
108405
|
+
mkdirSync7(localPocsPath, { recursive: true });
|
|
108364
108406
|
}
|
|
108365
|
-
const localPocPath =
|
|
108366
|
-
if (
|
|
108407
|
+
const localPocPath = join12(localPocsPath, filename);
|
|
108408
|
+
if (existsSync15(localPocPath)) {
|
|
108367
108409
|
return {
|
|
108368
108410
|
success: false,
|
|
108369
108411
|
error: `POC already exists at: pocs/${filename}`,
|
|
108370
108412
|
attemptsRemaining: MAX_POC_ATTEMPTS - currentAttempts
|
|
108371
108413
|
};
|
|
108372
108414
|
}
|
|
108373
|
-
|
|
108415
|
+
writeFileSync8(localPocPath, pocContent);
|
|
108374
108416
|
const sandboxPocPath = `/tmp/pocs/${filename}`;
|
|
108375
108417
|
await ctx4.sandbox.execute("mkdir -p /tmp/pocs");
|
|
108376
108418
|
const base64Content = Buffer.from(pocContent).toString("base64");
|
|
@@ -108568,7 +108610,7 @@ var init_readFile = __esm(() => {
|
|
|
108568
108610
|
|
|
108569
108611
|
// src/core/agents/offSecAgent/tools/listFiles.ts
|
|
108570
108612
|
import { readdir as readdir2, stat } from "fs/promises";
|
|
108571
|
-
import { join as
|
|
108613
|
+
import { join as join13, relative, resolve as resolve7, isAbsolute as isAbsolute3 } from "path";
|
|
108572
108614
|
async function listRecursive(dir, maxEntries) {
|
|
108573
108615
|
const results = [];
|
|
108574
108616
|
let total = 0;
|
|
@@ -108581,7 +108623,7 @@ async function listRecursive(dir, maxEntries) {
|
|
|
108581
108623
|
}
|
|
108582
108624
|
for (const entry of entries2) {
|
|
108583
108625
|
total++;
|
|
108584
|
-
const fullPath =
|
|
108626
|
+
const fullPath = join13(current, entry.name);
|
|
108585
108627
|
if (entry.isDirectory()) {
|
|
108586
108628
|
if (results.length < maxEntries)
|
|
108587
108629
|
results.push(`${fullPath}/`);
|
|
@@ -108644,7 +108686,7 @@ Each directory entry is suffixed with "/" for easy identification.`,
|
|
|
108644
108686
|
}
|
|
108645
108687
|
const entries2 = await readdir2(dir, { withFileTypes: true });
|
|
108646
108688
|
const fullPaths = entries2.map((e) => {
|
|
108647
|
-
const name26 =
|
|
108689
|
+
const name26 = join13(dir, e.name);
|
|
108648
108690
|
return e.isDirectory() ? `${name26}/` : name26;
|
|
108649
108691
|
});
|
|
108650
108692
|
const capped = fullPaths.slice(0, MAX_NON_RECURSIVE);
|
|
@@ -108790,7 +108832,7 @@ var init_grep = __esm(() => {
|
|
|
108790
108832
|
// src/core/agents/offSecAgent/tools/createFile.ts
|
|
108791
108833
|
import { writeFile, mkdir } from "fs/promises";
|
|
108792
108834
|
import { dirname as dirname4, resolve as resolve8, isAbsolute as isAbsolute4 } from "path";
|
|
108793
|
-
import { existsSync as
|
|
108835
|
+
import { existsSync as existsSync16 } from "fs";
|
|
108794
108836
|
function createFile(ctx4) {
|
|
108795
108837
|
return tool({
|
|
108796
108838
|
description: `Create a new file with the given content.
|
|
@@ -108815,7 +108857,7 @@ Parent directories are created automatically if they don't exist.`,
|
|
|
108815
108857
|
}
|
|
108816
108858
|
async function executeLocalCreate(filePath, content, overwrite) {
|
|
108817
108859
|
try {
|
|
108818
|
-
if (!overwrite &&
|
|
108860
|
+
if (!overwrite && existsSync16(filePath)) {
|
|
108819
108861
|
return {
|
|
108820
108862
|
success: false,
|
|
108821
108863
|
error: `File already exists: ${filePath}. Set overwrite=true to replace it.`,
|
|
@@ -109025,11 +109067,173 @@ var init_updateFile = __esm(() => {
|
|
|
109025
109067
|
});
|
|
109026
109068
|
});
|
|
109027
109069
|
|
|
109070
|
+
// src/core/agents/specialized/attackSurface/blackboxRiskScoring.ts
|
|
109071
|
+
function computeBlackboxRiskScore(riskLevel, assetType, details, notes) {
|
|
109072
|
+
const exposure = computeExposure(riskLevel, details);
|
|
109073
|
+
const dataSensitivity = computeDataSensitivity(riskLevel, assetType, details);
|
|
109074
|
+
const functionCriticality = computeFunctionCriticality(riskLevel, assetType, details, notes);
|
|
109075
|
+
const securityIndicators = computeSecurityIndicators(riskLevel, details, notes);
|
|
109076
|
+
const rawSum = exposure + dataSensitivity + functionCriticality + securityIndicators;
|
|
109077
|
+
const score = Math.min(10, Math.max(0, rawSum));
|
|
109078
|
+
const baseScore = RISK_LEVEL_BASE_SCORE[riskLevel] ?? 0;
|
|
109079
|
+
const explanation = buildExplanation(riskLevel, assetType, baseScore, score, {
|
|
109080
|
+
exposure,
|
|
109081
|
+
dataSensitivity,
|
|
109082
|
+
functionCriticality,
|
|
109083
|
+
securityIndicators
|
|
109084
|
+
});
|
|
109085
|
+
return {
|
|
109086
|
+
score,
|
|
109087
|
+
explanation,
|
|
109088
|
+
breakdown: {
|
|
109089
|
+
exposure,
|
|
109090
|
+
dataSensitivity,
|
|
109091
|
+
functionCriticality,
|
|
109092
|
+
securityIndicators
|
|
109093
|
+
}
|
|
109094
|
+
};
|
|
109095
|
+
}
|
|
109096
|
+
function computeExposure(riskLevel, details) {
|
|
109097
|
+
let base = EXPOSURE_BY_RISK[riskLevel] ?? 1;
|
|
109098
|
+
if (details?.authentication) {
|
|
109099
|
+
const authLower = details.authentication.toLowerCase();
|
|
109100
|
+
if (authLower.includes("none") || authLower.includes("no auth") || authLower.includes("public")) {
|
|
109101
|
+
base = Math.max(base, 3);
|
|
109102
|
+
} else if (authLower.includes("admin") || authLower.includes("privileged")) {
|
|
109103
|
+
base = Math.min(base, 1);
|
|
109104
|
+
}
|
|
109105
|
+
}
|
|
109106
|
+
return Math.min(3, Math.max(0, base));
|
|
109107
|
+
}
|
|
109108
|
+
function computeDataSensitivity(riskLevel, assetType, details) {
|
|
109109
|
+
if (riskLevel === "CRITICAL")
|
|
109110
|
+
return 3;
|
|
109111
|
+
let score = riskLevel === "HIGH" ? 2 : riskLevel === "MEDIUM" ? 1 : 0;
|
|
109112
|
+
if (assetType === "admin_panel")
|
|
109113
|
+
score = Math.max(score, 2);
|
|
109114
|
+
const techStr = (details?.technology ?? []).join(" ").toLowerCase();
|
|
109115
|
+
if (techStr.includes("database") || techStr.includes("postgres") || techStr.includes("mysql") || techStr.includes("mongo") || techStr.includes("redis")) {
|
|
109116
|
+
score = Math.max(score, 2);
|
|
109117
|
+
}
|
|
109118
|
+
return Math.min(3, score);
|
|
109119
|
+
}
|
|
109120
|
+
function computeFunctionCriticality(riskLevel, assetType, details, notes) {
|
|
109121
|
+
if (assetType === "admin_panel")
|
|
109122
|
+
return 2;
|
|
109123
|
+
if (riskLevel === "CRITICAL")
|
|
109124
|
+
return 2;
|
|
109125
|
+
const searchText = [
|
|
109126
|
+
...details?.services ?? [],
|
|
109127
|
+
...details?.technology ?? [],
|
|
109128
|
+
details?.authentication ?? "",
|
|
109129
|
+
notes ?? ""
|
|
109130
|
+
].join(" ").toLowerCase();
|
|
109131
|
+
const criticalPatterns = [
|
|
109132
|
+
"auth",
|
|
109133
|
+
"login",
|
|
109134
|
+
"payment",
|
|
109135
|
+
"checkout",
|
|
109136
|
+
"password",
|
|
109137
|
+
"oauth",
|
|
109138
|
+
"sso",
|
|
109139
|
+
"saml",
|
|
109140
|
+
"admin",
|
|
109141
|
+
"transfer",
|
|
109142
|
+
"billing"
|
|
109143
|
+
];
|
|
109144
|
+
if (criticalPatterns.some((p) => searchText.includes(p)))
|
|
109145
|
+
return 2;
|
|
109146
|
+
if (riskLevel === "HIGH")
|
|
109147
|
+
return 1;
|
|
109148
|
+
if (assetType === "api" || assetType === "web_application")
|
|
109149
|
+
return 1;
|
|
109150
|
+
return 0;
|
|
109151
|
+
}
|
|
109152
|
+
function computeSecurityIndicators(riskLevel, details, notes) {
|
|
109153
|
+
if (riskLevel === "CRITICAL")
|
|
109154
|
+
return 2;
|
|
109155
|
+
const searchText = [
|
|
109156
|
+
...details?.services ?? [],
|
|
109157
|
+
...details?.technology ?? [],
|
|
109158
|
+
notes ?? "",
|
|
109159
|
+
String(details?.status ?? "")
|
|
109160
|
+
].join(" ").toLowerCase();
|
|
109161
|
+
const criticalIndicators = [
|
|
109162
|
+
"injection",
|
|
109163
|
+
"sqli",
|
|
109164
|
+
"xss",
|
|
109165
|
+
"rce",
|
|
109166
|
+
"traversal",
|
|
109167
|
+
"deserialization",
|
|
109168
|
+
"hardcoded",
|
|
109169
|
+
"default credentials",
|
|
109170
|
+
"vulnerable",
|
|
109171
|
+
"cve-",
|
|
109172
|
+
"exploit"
|
|
109173
|
+
];
|
|
109174
|
+
if (criticalIndicators.some((p) => searchText.includes(p)))
|
|
109175
|
+
return 2;
|
|
109176
|
+
const moderateIndicators = [
|
|
109177
|
+
"outdated",
|
|
109178
|
+
"deprecated",
|
|
109179
|
+
"insecure",
|
|
109180
|
+
"http:",
|
|
109181
|
+
"self-signed",
|
|
109182
|
+
"debug",
|
|
109183
|
+
"verbose error",
|
|
109184
|
+
"stack trace",
|
|
109185
|
+
"cors",
|
|
109186
|
+
"misconfigur"
|
|
109187
|
+
];
|
|
109188
|
+
if (moderateIndicators.some((p) => searchText.includes(p)))
|
|
109189
|
+
return 1;
|
|
109190
|
+
if (riskLevel === "HIGH")
|
|
109191
|
+
return 1;
|
|
109192
|
+
return 0;
|
|
109193
|
+
}
|
|
109194
|
+
function buildExplanation(riskLevel, assetType, _baseScore, totalScore, breakdown) {
|
|
109195
|
+
const parts = [
|
|
109196
|
+
`${riskLevel} risk ${assetType.replace(/_/g, " ")} (score ${totalScore}/10).`
|
|
109197
|
+
];
|
|
109198
|
+
if (breakdown.exposure >= 3)
|
|
109199
|
+
parts.push("Publicly exposed.");
|
|
109200
|
+
else if (breakdown.exposure >= 2)
|
|
109201
|
+
parts.push("Externally accessible.");
|
|
109202
|
+
if (breakdown.dataSensitivity >= 3)
|
|
109203
|
+
parts.push("Likely handles sensitive data.");
|
|
109204
|
+
else if (breakdown.dataSensitivity >= 2)
|
|
109205
|
+
parts.push("May handle business-critical data.");
|
|
109206
|
+
if (breakdown.functionCriticality >= 2)
|
|
109207
|
+
parts.push("Critical function.");
|
|
109208
|
+
else if (breakdown.functionCriticality >= 1)
|
|
109209
|
+
parts.push("Core function.");
|
|
109210
|
+
if (breakdown.securityIndicators >= 2)
|
|
109211
|
+
parts.push("Security concerns observed.");
|
|
109212
|
+
else if (breakdown.securityIndicators >= 1)
|
|
109213
|
+
parts.push("Moderate security concerns.");
|
|
109214
|
+
return parts.join(" ");
|
|
109215
|
+
}
|
|
109216
|
+
var RISK_LEVEL_BASE_SCORE, EXPOSURE_BY_RISK;
|
|
109217
|
+
var init_blackboxRiskScoring = __esm(() => {
|
|
109218
|
+
RISK_LEVEL_BASE_SCORE = {
|
|
109219
|
+
CRITICAL: 10,
|
|
109220
|
+
HIGH: 8,
|
|
109221
|
+
MEDIUM: 5,
|
|
109222
|
+
LOW: 2
|
|
109223
|
+
};
|
|
109224
|
+
EXPOSURE_BY_RISK = {
|
|
109225
|
+
CRITICAL: 3,
|
|
109226
|
+
HIGH: 3,
|
|
109227
|
+
MEDIUM: 2,
|
|
109228
|
+
LOW: 1
|
|
109229
|
+
};
|
|
109230
|
+
});
|
|
109231
|
+
|
|
109028
109232
|
// src/core/agents/offSecAgent/tools/documentAsset.ts
|
|
109029
|
-
import { join as
|
|
109030
|
-
import { writeFileSync as
|
|
109233
|
+
import { join as join14 } from "path";
|
|
109234
|
+
import { writeFileSync as writeFileSync9, mkdirSync as mkdirSync8, existsSync as existsSync17 } from "fs";
|
|
109031
109235
|
function documentAsset(ctx4) {
|
|
109032
|
-
const assetsPath =
|
|
109236
|
+
const assetsPath = join14(ctx4.session.rootPath, "assets");
|
|
109033
109237
|
return tool({
|
|
109034
109238
|
description: `Document a discovered asset during attack surface analysis.
|
|
109035
109239
|
|
|
@@ -109107,21 +109311,23 @@ Each asset creates a JSON file in the assets directory for tracking and analysis
|
|
|
109107
109311
|
};
|
|
109108
109312
|
}
|
|
109109
109313
|
}
|
|
109110
|
-
if (!
|
|
109111
|
-
|
|
109314
|
+
if (!existsSync17(assetsPath)) {
|
|
109315
|
+
mkdirSync8(assetsPath, { recursive: true });
|
|
109112
109316
|
}
|
|
109113
109317
|
const sanitizedName = asset.assetName.toLowerCase().replace(/[^a-z0-9-_.]/g, "_");
|
|
109114
109318
|
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
109115
109319
|
const filename = `asset_${sanitizedName}_${timestamp}.json`;
|
|
109116
|
-
const filepath =
|
|
109320
|
+
const filepath = join14(assetsPath, filename);
|
|
109321
|
+
const riskScore = computeBlackboxRiskScore(asset.riskLevel, asset.assetType, asset.details, asset.notes);
|
|
109117
109322
|
const assetRecord = {
|
|
109118
109323
|
...asset,
|
|
109119
109324
|
discoveredAt: new Date().toISOString(),
|
|
109120
109325
|
sessionId: ctx4.session.id,
|
|
109121
|
-
target: ctx4.session.targets[0]
|
|
109326
|
+
target: ctx4.session.targets[0],
|
|
109327
|
+
riskScore
|
|
109122
109328
|
};
|
|
109123
109329
|
try {
|
|
109124
|
-
|
|
109330
|
+
writeFileSync9(filepath, JSON.stringify(assetRecord, null, 2));
|
|
109125
109331
|
} catch (writeError) {
|
|
109126
109332
|
if (ctx4.attackSurfaceRegistry) {
|
|
109127
109333
|
await ctx4.attackSurfaceRegistry.unregister(asset);
|
|
@@ -109142,11 +109348,12 @@ Each asset creates a JSON file in the assets directory for tracking and analysis
|
|
|
109142
109348
|
var init_documentAsset = __esm(() => {
|
|
109143
109349
|
init_dist5();
|
|
109144
109350
|
init_zod();
|
|
109351
|
+
init_blackboxRiskScoring();
|
|
109145
109352
|
});
|
|
109146
109353
|
|
|
109147
109354
|
// src/core/agents/offSecAgent/tools/authenticateSession.ts
|
|
109148
|
-
import { join as
|
|
109149
|
-
import { writeFileSync as
|
|
109355
|
+
import { join as join15 } from "path";
|
|
109356
|
+
import { writeFileSync as writeFileSync10 } from "fs";
|
|
109150
109357
|
function authenticateSession(ctx4) {
|
|
109151
109358
|
return tool({
|
|
109152
109359
|
description: `Authenticate with credentials and obtain a session cookie for subsequent authenticated requests.
|
|
@@ -109234,7 +109441,7 @@ or provide username/password directly.`,
|
|
|
109234
109441
|
const sessionCookies = Array.isArray(setCookieHeader) ? setCookieHeader : [setCookieHeader];
|
|
109235
109442
|
const cookieString = sessionCookies.join("; ");
|
|
109236
109443
|
const authenticated = result.status >= 200 && result.status < 400 && cookieString.length > 0;
|
|
109237
|
-
const sessionInfoPath =
|
|
109444
|
+
const sessionInfoPath = join15(ctx4.session.rootPath, "session-info.json");
|
|
109238
109445
|
const sessionInfo = {
|
|
109239
109446
|
authenticated,
|
|
109240
109447
|
username,
|
|
@@ -109242,7 +109449,7 @@ or provide username/password directly.`,
|
|
|
109242
109449
|
loginUrl,
|
|
109243
109450
|
timestamp: new Date().toISOString()
|
|
109244
109451
|
};
|
|
109245
|
-
|
|
109452
|
+
writeFileSync10(sessionInfoPath, JSON.stringify(sessionInfo, null, 2));
|
|
109246
109453
|
return {
|
|
109247
109454
|
success: authenticated,
|
|
109248
109455
|
authenticated,
|
|
@@ -109407,10 +109614,10 @@ If you encounter rate-limiting errors (e.g. "Rate limit exceeded", HTTP 429, "to
|
|
|
109407
109614
|
`;
|
|
109408
109615
|
|
|
109409
109616
|
// src/core/agents/specialized/authenticationAgent/agent.ts
|
|
109410
|
-
import { existsSync as
|
|
109411
|
-
import { join as
|
|
109617
|
+
import { existsSync as existsSync18, readFileSync as readFileSync7 } from "fs";
|
|
109618
|
+
import { join as join16 } from "path";
|
|
109412
109619
|
function loadAuthResult(authDataPath) {
|
|
109413
|
-
if (!
|
|
109620
|
+
if (!existsSync18(authDataPath)) {
|
|
109414
109621
|
return {
|
|
109415
109622
|
success: false,
|
|
109416
109623
|
summary: "Authentication completed but no auth-data.json was written.",
|
|
@@ -109547,7 +109754,7 @@ var init_agent = __esm(() => {
|
|
|
109547
109754
|
],
|
|
109548
109755
|
stopWhen: hasToolCall("complete_authentication"),
|
|
109549
109756
|
resolveResult: () => {
|
|
109550
|
-
const authDataPath =
|
|
109757
|
+
const authDataPath = join16(session.rootPath, "auth", "auth-data.json");
|
|
109551
109758
|
return loadAuthResult(authDataPath);
|
|
109552
109759
|
}
|
|
109553
109760
|
});
|
|
@@ -109567,8 +109774,8 @@ var init_authentication = __esm(() => {
|
|
|
109567
109774
|
});
|
|
109568
109775
|
|
|
109569
109776
|
// src/core/agents/offSecAgent/tools/delegateAuth.ts
|
|
109570
|
-
import { join as
|
|
109571
|
-
import { writeFileSync as
|
|
109777
|
+
import { join as join17 } from "path";
|
|
109778
|
+
import { writeFileSync as writeFileSync11 } from "fs";
|
|
109572
109779
|
function mergeAuthCredentials(sessionCreds, explicit) {
|
|
109573
109780
|
const hasExplicit = explicit.username || explicit.password || explicit.apiKey || explicit.tokens;
|
|
109574
109781
|
const hasSession = sessionCreds && (sessionCreds.username || sessionCreds.password || sessionCreds.apiKey || sessionCreds.tokens);
|
|
@@ -109766,7 +109973,7 @@ When to use delegate_to_auth_subagent vs authenticate_session:
|
|
|
109766
109973
|
status: result.success ? "completed" : "failed"
|
|
109767
109974
|
});
|
|
109768
109975
|
if (result.success) {
|
|
109769
|
-
const sessionInfoPath =
|
|
109976
|
+
const sessionInfoPath = join17(ctx4.session.rootPath, "session-info.json");
|
|
109770
109977
|
const sessionInfo = {
|
|
109771
109978
|
authenticated: true,
|
|
109772
109979
|
username: username || "via_subagent",
|
|
@@ -109776,7 +109983,7 @@ When to use delegate_to_auth_subagent vs authenticate_session:
|
|
|
109776
109983
|
timestamp: new Date().toISOString(),
|
|
109777
109984
|
delegatedToSubagent: true
|
|
109778
109985
|
};
|
|
109779
|
-
|
|
109986
|
+
writeFileSync11(sessionInfoPath, JSON.stringify(sessionInfo, null, 2));
|
|
109780
109987
|
}
|
|
109781
109988
|
const hasHeaders = result.exportedHeaders && Object.keys(result.exportedHeaders).length > 0;
|
|
109782
109989
|
const hasCookies = result.exportedCookies && result.exportedCookies.length > 0;
|
|
@@ -110186,8 +110393,8 @@ var init_validateDiscovery = __esm(() => {
|
|
|
110186
110393
|
});
|
|
110187
110394
|
|
|
110188
110395
|
// src/core/agents/offSecAgent/tools/createAttackSurfaceReport.ts
|
|
110189
|
-
import { join as
|
|
110190
|
-
import { writeFileSync as
|
|
110396
|
+
import { join as join18 } from "path";
|
|
110397
|
+
import { writeFileSync as writeFileSync12 } from "fs";
|
|
110191
110398
|
function createAttackSurfaceReport(ctx4) {
|
|
110192
110399
|
return tool({
|
|
110193
110400
|
description: `Provide attack surface analysis results to the orchestrator agent.
|
|
@@ -110213,8 +110420,8 @@ Call this at the END of your analysis with:
|
|
|
110213
110420
|
toolCallDescription: exports_external.string().describe("A concise, human-readable description of what this tool call is doing")
|
|
110214
110421
|
}),
|
|
110215
110422
|
execute: async (results) => {
|
|
110216
|
-
const resultsPath =
|
|
110217
|
-
|
|
110423
|
+
const resultsPath = join18(ctx4.session.rootPath, "attack-surface-results.json");
|
|
110424
|
+
writeFileSync12(resultsPath, JSON.stringify(results, null, 2));
|
|
110218
110425
|
return {
|
|
110219
110426
|
success: true,
|
|
110220
110427
|
resultsPath,
|
|
@@ -110230,8 +110437,8 @@ var init_createAttackSurfaceReport = __esm(() => {
|
|
|
110230
110437
|
});
|
|
110231
110438
|
|
|
110232
110439
|
// src/core/agents/offSecAgent/tools/completeAuthentication.ts
|
|
110233
|
-
import { join as
|
|
110234
|
-
import { existsSync as
|
|
110440
|
+
import { join as join19 } from "path";
|
|
110441
|
+
import { existsSync as existsSync19, mkdirSync as mkdirSync9, writeFileSync as writeFileSync13 } from "fs";
|
|
110235
110442
|
function completeAuthentication(ctx4) {
|
|
110236
110443
|
return tool({
|
|
110237
110444
|
description: `Signal that the authentication process is complete.
|
|
@@ -110273,11 +110480,11 @@ This tool marks the end of the authentication flow.`,
|
|
|
110273
110480
|
let authDataPath;
|
|
110274
110481
|
if (result.success && (result.exportedCookies || result.exportedHeaders)) {
|
|
110275
110482
|
try {
|
|
110276
|
-
const authDir =
|
|
110277
|
-
if (!
|
|
110278
|
-
|
|
110483
|
+
const authDir = join19(ctx4.session.rootPath, AUTH_DIR);
|
|
110484
|
+
if (!existsSync19(authDir)) {
|
|
110485
|
+
mkdirSync9(authDir, { recursive: true });
|
|
110279
110486
|
}
|
|
110280
|
-
authDataPath =
|
|
110487
|
+
authDataPath = join19(authDir, AUTH_DATA_FILENAME);
|
|
110281
110488
|
const authData = {
|
|
110282
110489
|
authenticated: true,
|
|
110283
110490
|
strategy: result.strategy || "unknown",
|
|
@@ -110287,7 +110494,7 @@ This tool marks the end of the authentication flow.`,
|
|
|
110287
110494
|
target: ctx4.target || "",
|
|
110288
110495
|
timestamp: new Date().toISOString()
|
|
110289
110496
|
};
|
|
110290
|
-
|
|
110497
|
+
writeFileSync13(authDataPath, JSON.stringify(authData, null, 2));
|
|
110291
110498
|
console.log(`Auth data persisted to ${authDataPath}`);
|
|
110292
110499
|
} catch (err) {
|
|
110293
110500
|
console.error(`Failed to persist auth data: ${err}`);
|
|
@@ -111035,8 +111242,8 @@ var init_runAttackSurface = __esm(() => {
|
|
|
111035
111242
|
});
|
|
111036
111243
|
|
|
111037
111244
|
// src/core/findings/registry.ts
|
|
111038
|
-
import { existsSync as
|
|
111039
|
-
import { join as
|
|
111245
|
+
import { existsSync as existsSync20, readdirSync as readdirSync3, readFileSync as readFileSync8 } from "fs";
|
|
111246
|
+
import { join as join20 } from "path";
|
|
111040
111247
|
function extractVulnClass(title) {
|
|
111041
111248
|
const t2 = title.trim();
|
|
111042
111249
|
for (const [pattern, cls] of VULN_CLASS_PATTERNS) {
|
|
@@ -111108,12 +111315,12 @@ class FindingsRegistry {
|
|
|
111108
111315
|
}
|
|
111109
111316
|
static fromDirectory(findingsPath, opts) {
|
|
111110
111317
|
const registry2 = new FindingsRegistry(opts);
|
|
111111
|
-
if (!
|
|
111318
|
+
if (!existsSync20(findingsPath))
|
|
111112
111319
|
return registry2;
|
|
111113
111320
|
const files = readdirSync3(findingsPath).filter((f) => f.endsWith(".json"));
|
|
111114
111321
|
for (const file2 of files) {
|
|
111115
111322
|
try {
|
|
111116
|
-
const raw = readFileSync8(
|
|
111323
|
+
const raw = readFileSync8(join20(findingsPath, file2), "utf-8");
|
|
111117
111324
|
const finding = JSON.parse(raw);
|
|
111118
111325
|
if (finding && typeof finding.title === "string" && typeof finding.endpoint === "string") {
|
|
111119
111326
|
registry2.indexFinding(finding);
|
|
@@ -111599,8 +111806,8 @@ var init_spawnCodingAgent = __esm(() => {
|
|
|
111599
111806
|
});
|
|
111600
111807
|
|
|
111601
111808
|
// src/core/agents/offSecAgent/tools/provideComparisonResults.ts
|
|
111602
|
-
import { join as
|
|
111603
|
-
import { writeFileSync as
|
|
111809
|
+
import { join as join21 } from "path";
|
|
111810
|
+
import { writeFileSync as writeFileSync14 } from "fs";
|
|
111604
111811
|
function provideComparisonResults(ctx4) {
|
|
111605
111812
|
return tool({
|
|
111606
111813
|
description: `Provide the final comparison results with matched, missed, and extra findings.
|
|
@@ -111646,8 +111853,8 @@ Results will be saved to: comparison-results.json in the session directory.`,
|
|
|
111646
111853
|
recall,
|
|
111647
111854
|
precision
|
|
111648
111855
|
};
|
|
111649
|
-
const resultsPath =
|
|
111650
|
-
|
|
111856
|
+
const resultsPath = join21(ctx4.session.rootPath, "comparison-results.json");
|
|
111857
|
+
writeFileSync14(resultsPath, JSON.stringify(result, null, 2));
|
|
111651
111858
|
return {
|
|
111652
111859
|
success: true,
|
|
111653
111860
|
resultsPath,
|
|
@@ -140946,8 +141153,8 @@ var require_core5 = __commonJS((exports) => {
|
|
|
140946
141153
|
function many1(p) {
|
|
140947
141154
|
return ab(p, many(p), (head, tail) => [head, ...tail]);
|
|
140948
141155
|
}
|
|
140949
|
-
function ab(pa, pb,
|
|
140950
|
-
return (data, i) => mapOuter(pa(data, i), (ma) => mapInner(pb(data, ma.position), (vb, j2) =>
|
|
141156
|
+
function ab(pa, pb, join22) {
|
|
141157
|
+
return (data, i) => mapOuter(pa(data, i), (ma) => mapInner(pb(data, ma.position), (vb, j2) => join22(ma.value, vb, data, i, j2)));
|
|
140951
141158
|
}
|
|
140952
141159
|
function left(pa, pb) {
|
|
140953
141160
|
return ab(pa, pb, (va) => va);
|
|
@@ -140955,8 +141162,8 @@ var require_core5 = __commonJS((exports) => {
|
|
|
140955
141162
|
function right(pa, pb) {
|
|
140956
141163
|
return ab(pa, pb, (va, vb) => vb);
|
|
140957
141164
|
}
|
|
140958
|
-
function abc(pa, pb, pc,
|
|
140959
|
-
return (data, i) => mapOuter(pa(data, i), (ma) => mapOuter(pb(data, ma.position), (mb) => mapInner(pc(data, mb.position), (vc, j2) =>
|
|
141165
|
+
function abc(pa, pb, pc, join22) {
|
|
141166
|
+
return (data, i) => mapOuter(pa(data, i), (ma) => mapOuter(pb(data, ma.position), (mb) => mapInner(pc(data, mb.position), (vc, j2) => join22(ma.value, mb.value, vc, data, i, j2))));
|
|
140960
141167
|
}
|
|
140961
141168
|
function middle(pa, pb, pc) {
|
|
140962
141169
|
return abc(pa, pb, pc, (ra, rb) => rb);
|
|
@@ -176793,7 +177000,7 @@ var require_thread_stream = __commonJS((exports, module2) => {
|
|
|
176793
177000
|
var { version: version2 } = require_package5();
|
|
176794
177001
|
var { EventEmitter: EventEmitter11 } = __require("events");
|
|
176795
177002
|
var { Worker: Worker2 } = __require("worker_threads");
|
|
176796
|
-
var { join:
|
|
177003
|
+
var { join: join22 } = __require("path");
|
|
176797
177004
|
var { pathToFileURL } = __require("url");
|
|
176798
177005
|
var { wait } = require_wait();
|
|
176799
177006
|
var {
|
|
@@ -176829,7 +177036,7 @@ var require_thread_stream = __commonJS((exports, module2) => {
|
|
|
176829
177036
|
function createWorker(stream, opts) {
|
|
176830
177037
|
const { filename, workerData } = opts;
|
|
176831
177038
|
const bundlerOverrides = "__bundlerPathsOverrides" in globalThis ? globalThis.__bundlerPathsOverrides : {};
|
|
176832
|
-
const toExecute = bundlerOverrides["thread-stream-worker"] ||
|
|
177039
|
+
const toExecute = bundlerOverrides["thread-stream-worker"] || join22(__dirname, "lib", "worker.js");
|
|
176833
177040
|
const worker = new Worker2(toExecute, {
|
|
176834
177041
|
...opts.workerOpts,
|
|
176835
177042
|
trackUnmanagedFds: false,
|
|
@@ -177218,7 +177425,7 @@ var require_transport = __commonJS((exports, module2) => {
|
|
|
177218
177425
|
var { createRequire: createRequire3 } = __require("module");
|
|
177219
177426
|
var { existsSync: existsSync4 } = __require("node:fs");
|
|
177220
177427
|
var getCallers = require_caller();
|
|
177221
|
-
var { join:
|
|
177428
|
+
var { join: join22, isAbsolute: isAbsolute6, sep } = __require("node:path");
|
|
177222
177429
|
var { fileURLToPath: fileURLToPath2 } = __require("node:url");
|
|
177223
177430
|
var sleep2 = require_atomic_sleep();
|
|
177224
177431
|
var onExit = require_on_exit_leak_free();
|
|
@@ -177371,7 +177578,7 @@ var require_transport = __commonJS((exports, module2) => {
|
|
|
177371
177578
|
throw new Error("only one of target or targets can be specified");
|
|
177372
177579
|
}
|
|
177373
177580
|
if (targets) {
|
|
177374
|
-
target = bundlerOverrides["pino-worker"] ||
|
|
177581
|
+
target = bundlerOverrides["pino-worker"] || join22(__dirname, "worker.js");
|
|
177375
177582
|
options.targets = targets.filter((dest) => dest.target).map((dest) => {
|
|
177376
177583
|
return {
|
|
177377
177584
|
...dest,
|
|
@@ -177388,7 +177595,7 @@ var require_transport = __commonJS((exports, module2) => {
|
|
|
177388
177595
|
});
|
|
177389
177596
|
});
|
|
177390
177597
|
} else if (pipeline3) {
|
|
177391
|
-
target = bundlerOverrides["pino-worker"] ||
|
|
177598
|
+
target = bundlerOverrides["pino-worker"] || join22(__dirname, "worker.js");
|
|
177392
177599
|
options.pipelines = [pipeline3.map((dest) => {
|
|
177393
177600
|
return {
|
|
177394
177601
|
...dest,
|
|
@@ -177411,7 +177618,7 @@ var require_transport = __commonJS((exports, module2) => {
|
|
|
177411
177618
|
return origin;
|
|
177412
177619
|
}
|
|
177413
177620
|
if (origin === "pino/file") {
|
|
177414
|
-
return
|
|
177621
|
+
return join22(__dirname, "..", "file.js");
|
|
177415
177622
|
}
|
|
177416
177623
|
let fixTarget2;
|
|
177417
177624
|
for (const filePath of callers) {
|
|
@@ -178340,7 +178547,7 @@ var require_safe_stable_stringify = __commonJS((exports, module2) => {
|
|
|
178340
178547
|
return circularValue;
|
|
178341
178548
|
}
|
|
178342
178549
|
let res = "";
|
|
178343
|
-
let
|
|
178550
|
+
let join22 = ",";
|
|
178344
178551
|
const originalIndentation = indentation;
|
|
178345
178552
|
if (Array.isArray(value)) {
|
|
178346
178553
|
if (value.length === 0) {
|
|
@@ -178354,7 +178561,7 @@ var require_safe_stable_stringify = __commonJS((exports, module2) => {
|
|
|
178354
178561
|
indentation += spacer;
|
|
178355
178562
|
res += `
|
|
178356
178563
|
${indentation}`;
|
|
178357
|
-
|
|
178564
|
+
join22 = `,
|
|
178358
178565
|
${indentation}`;
|
|
178359
178566
|
}
|
|
178360
178567
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
@@ -178362,13 +178569,13 @@ ${indentation}`;
|
|
|
178362
178569
|
for (;i2 < maximumValuesToStringify - 1; i2++) {
|
|
178363
178570
|
const tmp2 = stringifyFnReplacer(String(i2), value, stack, replacer, spacer, indentation);
|
|
178364
178571
|
res += tmp2 !== undefined ? tmp2 : "null";
|
|
178365
|
-
res +=
|
|
178572
|
+
res += join22;
|
|
178366
178573
|
}
|
|
178367
178574
|
const tmp = stringifyFnReplacer(String(i2), value, stack, replacer, spacer, indentation);
|
|
178368
178575
|
res += tmp !== undefined ? tmp : "null";
|
|
178369
178576
|
if (value.length - 1 > maximumBreadth) {
|
|
178370
178577
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
178371
|
-
res += `${
|
|
178578
|
+
res += `${join22}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
178372
178579
|
}
|
|
178373
178580
|
if (spacer !== "") {
|
|
178374
178581
|
res += `
|
|
@@ -178389,7 +178596,7 @@ ${originalIndentation}`;
|
|
|
178389
178596
|
let separator = "";
|
|
178390
178597
|
if (spacer !== "") {
|
|
178391
178598
|
indentation += spacer;
|
|
178392
|
-
|
|
178599
|
+
join22 = `,
|
|
178393
178600
|
${indentation}`;
|
|
178394
178601
|
whitespace = " ";
|
|
178395
178602
|
}
|
|
@@ -178403,13 +178610,13 @@ ${indentation}`;
|
|
|
178403
178610
|
const tmp = stringifyFnReplacer(key2, value, stack, replacer, spacer, indentation);
|
|
178404
178611
|
if (tmp !== undefined) {
|
|
178405
178612
|
res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
|
|
178406
|
-
separator =
|
|
178613
|
+
separator = join22;
|
|
178407
178614
|
}
|
|
178408
178615
|
}
|
|
178409
178616
|
if (keyLength > maximumBreadth) {
|
|
178410
178617
|
const removedKeys = keyLength - maximumBreadth;
|
|
178411
178618
|
res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`;
|
|
178412
|
-
separator =
|
|
178619
|
+
separator = join22;
|
|
178413
178620
|
}
|
|
178414
178621
|
if (spacer !== "" && separator.length > 1) {
|
|
178415
178622
|
res = `
|
|
@@ -178449,7 +178656,7 @@ ${originalIndentation}`;
|
|
|
178449
178656
|
}
|
|
178450
178657
|
const originalIndentation = indentation;
|
|
178451
178658
|
let res = "";
|
|
178452
|
-
let
|
|
178659
|
+
let join22 = ",";
|
|
178453
178660
|
if (Array.isArray(value)) {
|
|
178454
178661
|
if (value.length === 0) {
|
|
178455
178662
|
return "[]";
|
|
@@ -178462,7 +178669,7 @@ ${originalIndentation}`;
|
|
|
178462
178669
|
indentation += spacer;
|
|
178463
178670
|
res += `
|
|
178464
178671
|
${indentation}`;
|
|
178465
|
-
|
|
178672
|
+
join22 = `,
|
|
178466
178673
|
${indentation}`;
|
|
178467
178674
|
}
|
|
178468
178675
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
@@ -178470,13 +178677,13 @@ ${indentation}`;
|
|
|
178470
178677
|
for (;i2 < maximumValuesToStringify - 1; i2++) {
|
|
178471
178678
|
const tmp2 = stringifyArrayReplacer(String(i2), value[i2], stack, replacer, spacer, indentation);
|
|
178472
178679
|
res += tmp2 !== undefined ? tmp2 : "null";
|
|
178473
|
-
res +=
|
|
178680
|
+
res += join22;
|
|
178474
178681
|
}
|
|
178475
178682
|
const tmp = stringifyArrayReplacer(String(i2), value[i2], stack, replacer, spacer, indentation);
|
|
178476
178683
|
res += tmp !== undefined ? tmp : "null";
|
|
178477
178684
|
if (value.length - 1 > maximumBreadth) {
|
|
178478
178685
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
178479
|
-
res += `${
|
|
178686
|
+
res += `${join22}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
178480
178687
|
}
|
|
178481
178688
|
if (spacer !== "") {
|
|
178482
178689
|
res += `
|
|
@@ -178489,7 +178696,7 @@ ${originalIndentation}`;
|
|
|
178489
178696
|
let whitespace = "";
|
|
178490
178697
|
if (spacer !== "") {
|
|
178491
178698
|
indentation += spacer;
|
|
178492
|
-
|
|
178699
|
+
join22 = `,
|
|
178493
178700
|
${indentation}`;
|
|
178494
178701
|
whitespace = " ";
|
|
178495
178702
|
}
|
|
@@ -178498,7 +178705,7 @@ ${indentation}`;
|
|
|
178498
178705
|
const tmp = stringifyArrayReplacer(key2, value[key2], stack, replacer, spacer, indentation);
|
|
178499
178706
|
if (tmp !== undefined) {
|
|
178500
178707
|
res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
|
|
178501
|
-
separator =
|
|
178708
|
+
separator = join22;
|
|
178502
178709
|
}
|
|
178503
178710
|
}
|
|
178504
178711
|
if (spacer !== "" && separator.length > 1) {
|
|
@@ -178555,20 +178762,20 @@ ${originalIndentation}`;
|
|
|
178555
178762
|
indentation += spacer;
|
|
178556
178763
|
let res2 = `
|
|
178557
178764
|
${indentation}`;
|
|
178558
|
-
const
|
|
178765
|
+
const join23 = `,
|
|
178559
178766
|
${indentation}`;
|
|
178560
178767
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
178561
178768
|
let i2 = 0;
|
|
178562
178769
|
for (;i2 < maximumValuesToStringify - 1; i2++) {
|
|
178563
178770
|
const tmp2 = stringifyIndent(String(i2), value[i2], stack, spacer, indentation);
|
|
178564
178771
|
res2 += tmp2 !== undefined ? tmp2 : "null";
|
|
178565
|
-
res2 +=
|
|
178772
|
+
res2 += join23;
|
|
178566
178773
|
}
|
|
178567
178774
|
const tmp = stringifyIndent(String(i2), value[i2], stack, spacer, indentation);
|
|
178568
178775
|
res2 += tmp !== undefined ? tmp : "null";
|
|
178569
178776
|
if (value.length - 1 > maximumBreadth) {
|
|
178570
178777
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
178571
|
-
res2 += `${
|
|
178778
|
+
res2 += `${join23}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
178572
178779
|
}
|
|
178573
178780
|
res2 += `
|
|
178574
178781
|
${originalIndentation}`;
|
|
@@ -178584,16 +178791,16 @@ ${originalIndentation}`;
|
|
|
178584
178791
|
return '"[Object]"';
|
|
178585
178792
|
}
|
|
178586
178793
|
indentation += spacer;
|
|
178587
|
-
const
|
|
178794
|
+
const join22 = `,
|
|
178588
178795
|
${indentation}`;
|
|
178589
178796
|
let res = "";
|
|
178590
178797
|
let separator = "";
|
|
178591
178798
|
let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
|
|
178592
178799
|
if (isTypedArrayWithEntries(value)) {
|
|
178593
|
-
res += stringifyTypedArray(value,
|
|
178800
|
+
res += stringifyTypedArray(value, join22, maximumBreadth);
|
|
178594
178801
|
keys = keys.slice(value.length);
|
|
178595
178802
|
maximumPropertiesToStringify -= value.length;
|
|
178596
|
-
separator =
|
|
178803
|
+
separator = join22;
|
|
178597
178804
|
}
|
|
178598
178805
|
if (deterministic) {
|
|
178599
178806
|
keys = sort(keys, comparator);
|
|
@@ -178604,13 +178811,13 @@ ${indentation}`;
|
|
|
178604
178811
|
const tmp = stringifyIndent(key2, value[key2], stack, spacer, indentation);
|
|
178605
178812
|
if (tmp !== undefined) {
|
|
178606
178813
|
res += `${separator}${strEscape(key2)}: ${tmp}`;
|
|
178607
|
-
separator =
|
|
178814
|
+
separator = join22;
|
|
178608
178815
|
}
|
|
178609
178816
|
}
|
|
178610
178817
|
if (keyLength > maximumBreadth) {
|
|
178611
178818
|
const removedKeys = keyLength - maximumBreadth;
|
|
178612
178819
|
res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`;
|
|
178613
|
-
separator =
|
|
178820
|
+
separator = join22;
|
|
178614
178821
|
}
|
|
178615
178822
|
if (separator !== "") {
|
|
178616
178823
|
res = `
|
|
@@ -193871,8 +194078,8 @@ var init_operator = __esm(() => {
|
|
|
193871
194078
|
});
|
|
193872
194079
|
|
|
193873
194080
|
// src/core/agents/offSecAgent/offensiveSecurityAgent.ts
|
|
193874
|
-
import { join as
|
|
193875
|
-
import { writeFileSync as
|
|
194081
|
+
import { join as join22 } from "path";
|
|
194082
|
+
import { writeFileSync as writeFileSync15, mkdirSync as mkdirSync10, existsSync as existsSync21 } from "fs";
|
|
193876
194083
|
function wrapToolsWithApprovalGate(tools, gate) {
|
|
193877
194084
|
const wrapped = {};
|
|
193878
194085
|
for (const [name26, coreTool] of Object.entries(tools)) {
|
|
@@ -193998,16 +194205,18 @@ var init_offensiveSecurityAgent = __esm(() => {
|
|
|
193998
194205
|
const emailToolSet = new Set(EMAIL_TOOL_NAMES);
|
|
193999
194206
|
const activeTools = hasEmail ? input.activeTools : input.activeTools.filter((t3) => !emailToolSet.has(t3));
|
|
194000
194207
|
const messagesDir = input.messagesDir ?? input.session.rootPath;
|
|
194001
|
-
if (!
|
|
194002
|
-
|
|
194208
|
+
if (!existsSync21(messagesDir)) {
|
|
194209
|
+
mkdirSync10(messagesDir, { recursive: true });
|
|
194003
194210
|
}
|
|
194004
|
-
const messagesPath =
|
|
194005
|
-
const
|
|
194006
|
-
|
|
194007
|
-
|
|
194008
|
-
|
|
194009
|
-
|
|
194010
|
-
|
|
194211
|
+
const messagesPath = join22(messagesDir, "messages.json");
|
|
194212
|
+
const initialMessagesRef = {
|
|
194213
|
+
current: input.messages ? [...input.messages] : [
|
|
194214
|
+
{
|
|
194215
|
+
role: "user",
|
|
194216
|
+
content: [{ type: "text", text: input.prompt }]
|
|
194217
|
+
}
|
|
194218
|
+
]
|
|
194219
|
+
};
|
|
194011
194220
|
this.streamResult = streamResponse({
|
|
194012
194221
|
prompt: input.prompt,
|
|
194013
194222
|
system: (input.system ?? BASE_SYSTEM_PROMPT) + buildSessionWorkspaceSection(input.session),
|
|
@@ -194019,11 +194228,17 @@ var init_offensiveSecurityAgent = __esm(() => {
|
|
|
194019
194228
|
toolChoice: "auto",
|
|
194020
194229
|
onStepFinish: (event) => {
|
|
194021
194230
|
try {
|
|
194022
|
-
const allMessages = [
|
|
194023
|
-
|
|
194231
|
+
const allMessages = [
|
|
194232
|
+
...initialMessagesRef.current,
|
|
194233
|
+
...event.response.messages
|
|
194234
|
+
];
|
|
194235
|
+
writeFileSync15(messagesPath, JSON.stringify(allMessages, null, 2));
|
|
194024
194236
|
} catch {}
|
|
194025
194237
|
input.onStepFinish?.(event);
|
|
194026
194238
|
},
|
|
194239
|
+
onSummarized: () => {
|
|
194240
|
+
initialMessagesRef.current = [];
|
|
194241
|
+
},
|
|
194027
194242
|
onFinish: input.onFinish,
|
|
194028
194243
|
abortSignal: input.abortSignal,
|
|
194029
194244
|
authConfig: input.authConfig,
|
|
@@ -194106,8 +194321,8 @@ var exports_blackboxAgent = {};
|
|
|
194106
194321
|
__export(exports_blackboxAgent, {
|
|
194107
194322
|
BlackboxAttackSurfaceAgent: () => BlackboxAttackSurfaceAgent
|
|
194108
194323
|
});
|
|
194109
|
-
import { join as
|
|
194110
|
-
import { existsSync as
|
|
194324
|
+
import { join as join23 } from "path";
|
|
194325
|
+
import { existsSync as existsSync22 } from "fs";
|
|
194111
194326
|
function buildPrompt3(target, session) {
|
|
194112
194327
|
const scopeConstraints = session.config?.scopeConstraints;
|
|
194113
194328
|
const authenticationInstructions = session.config?.authenticationInstructions;
|
|
@@ -194158,7 +194373,7 @@ Note any login pages you find as assets and flag them for pentest agents.`;
|
|
|
194158
194373
|
return `TARGET: ${target}
|
|
194159
194374
|
|
|
194160
194375
|
Session: ${session.id}
|
|
194161
|
-
Assets directory: ${
|
|
194376
|
+
Assets directory: ${join23(session.rootPath, "assets")}
|
|
194162
194377
|
|
|
194163
194378
|
${authBlock}
|
|
194164
194379
|
|
|
@@ -194186,8 +194401,8 @@ var init_blackboxAgent = __esm(() => {
|
|
|
194186
194401
|
attackSurfaceRegistry
|
|
194187
194402
|
} = opts;
|
|
194188
194403
|
const target = opts.target ?? opts.cwd;
|
|
194189
|
-
const resultsPath =
|
|
194190
|
-
const assetsPath =
|
|
194404
|
+
const resultsPath = join23(session.rootPath, "attack-surface-results.json");
|
|
194405
|
+
const assetsPath = join23(session.rootPath, "assets");
|
|
194191
194406
|
super({
|
|
194192
194407
|
system: detectOSAndEnhancePrompt(SYSTEM),
|
|
194193
194408
|
prompt: buildPrompt3(target, session),
|
|
@@ -194223,7 +194438,7 @@ var init_blackboxAgent = __esm(() => {
|
|
|
194223
194438
|
resolveResult: () => {
|
|
194224
194439
|
let results = null;
|
|
194225
194440
|
let targets = [];
|
|
194226
|
-
if (
|
|
194441
|
+
if (existsSync22(resultsPath)) {
|
|
194227
194442
|
try {
|
|
194228
194443
|
results = loadAttackSurfaceResults2(resultsPath);
|
|
194229
194444
|
targets = results.targets || [];
|
|
@@ -194237,8 +194452,8 @@ var init_blackboxAgent = __esm(() => {
|
|
|
194237
194452
|
});
|
|
194238
194453
|
|
|
194239
194454
|
// src/core/agents/specialized/pentest/agent.ts
|
|
194240
|
-
import { existsSync as
|
|
194241
|
-
import { join as
|
|
194455
|
+
import { existsSync as existsSync23, readdirSync as readdirSync4, readFileSync as readFileSync9 } from "fs";
|
|
194456
|
+
import { join as join24 } from "path";
|
|
194242
194457
|
function buildSystemPrompt(session) {
|
|
194243
194458
|
return session.config?.exfilMode ? PENTEST_SYSTEM_PROMPT_EXFIL : PENTEST_SYSTEM_PROMPT_BASE;
|
|
194244
194459
|
}
|
|
@@ -194249,8 +194464,8 @@ function buildPrompt4(target, objectives, session, findingsRegistry) {
|
|
|
194249
194464
|
const objectiveList = objectives.map((o, i2) => `${i2 + 1}. ${o}`).join(`
|
|
194250
194465
|
`);
|
|
194251
194466
|
let authSection = "";
|
|
194252
|
-
const authDataPath =
|
|
194253
|
-
if (
|
|
194467
|
+
const authDataPath = join24(sessionRootPath, "auth", "auth-data.json");
|
|
194468
|
+
if (existsSync23(authDataPath)) {
|
|
194254
194469
|
try {
|
|
194255
194470
|
const raw = readFileSync9(authDataPath, "utf-8");
|
|
194256
194471
|
const authData = JSON.parse(raw);
|
|
@@ -194327,12 +194542,12 @@ ${outcomeSection}
|
|
|
194327
194542
|
${instructions}`;
|
|
194328
194543
|
}
|
|
194329
194544
|
function loadFindings(findingsPath) {
|
|
194330
|
-
if (!
|
|
194545
|
+
if (!existsSync23(findingsPath)) {
|
|
194331
194546
|
return [];
|
|
194332
194547
|
}
|
|
194333
194548
|
return readdirSync4(findingsPath).filter((f3) => f3.endsWith(".json")).map((f3) => {
|
|
194334
194549
|
try {
|
|
194335
|
-
const content = readFileSync9(
|
|
194550
|
+
const content = readFileSync9(join24(findingsPath, f3), "utf-8");
|
|
194336
194551
|
return JSON.parse(content);
|
|
194337
194552
|
} catch {
|
|
194338
194553
|
return null;
|
|
@@ -194487,8 +194702,8 @@ var init_agent4 = __esm(() => {
|
|
|
194487
194702
|
});
|
|
194488
194703
|
|
|
194489
194704
|
// src/core/session/execution-metrics.ts
|
|
194490
|
-
import { existsSync as
|
|
194491
|
-
import { join as
|
|
194705
|
+
import { existsSync as existsSync24, readFileSync as readFileSync10, writeFileSync as writeFileSync16 } from "fs";
|
|
194706
|
+
import { join as join25 } from "path";
|
|
194492
194707
|
function toNonNegativeInteger(value) {
|
|
194493
194708
|
const n = Number(value);
|
|
194494
194709
|
return Number.isFinite(n) && n > 0 ? Math.floor(n) : 0;
|
|
@@ -194505,14 +194720,14 @@ function normalizeTokenUsage(value) {
|
|
|
194505
194720
|
};
|
|
194506
194721
|
}
|
|
194507
194722
|
function metricsPath(sessionRootPath) {
|
|
194508
|
-
return
|
|
194723
|
+
return join25(sessionRootPath, EXECUTION_METRICS_FILENAME);
|
|
194509
194724
|
}
|
|
194510
194725
|
function sessionJsonPath(sessionRootPath) {
|
|
194511
|
-
return
|
|
194726
|
+
return join25(sessionRootPath, "session.json");
|
|
194512
194727
|
}
|
|
194513
194728
|
function readExecutionMetrics(sessionRootPath) {
|
|
194514
194729
|
const path6 = metricsPath(sessionRootPath);
|
|
194515
|
-
if (!
|
|
194730
|
+
if (!existsSync24(path6))
|
|
194516
194731
|
return null;
|
|
194517
194732
|
try {
|
|
194518
194733
|
const parsed = JSON.parse(readFileSync10(path6, "utf-8"));
|
|
@@ -194527,13 +194742,13 @@ function readExecutionMetrics(sessionRootPath) {
|
|
|
194527
194742
|
}
|
|
194528
194743
|
function writeSessionJsonTokenTotals(sessionRootPath, tokenUsage) {
|
|
194529
194744
|
const path6 = sessionJsonPath(sessionRootPath);
|
|
194530
|
-
if (!
|
|
194745
|
+
if (!existsSync24(path6))
|
|
194531
194746
|
return;
|
|
194532
194747
|
try {
|
|
194533
194748
|
const parsed = JSON.parse(readFileSync10(path6, "utf-8"));
|
|
194534
194749
|
parsed.tokensIn = tokenUsage.inputTokens;
|
|
194535
194750
|
parsed.tokensOut = tokenUsage.outputTokens;
|
|
194536
|
-
|
|
194751
|
+
writeFileSync16(path6, JSON.stringify(parsed, null, 2));
|
|
194537
194752
|
} catch {}
|
|
194538
194753
|
}
|
|
194539
194754
|
function writeExecutionMetrics(input) {
|
|
@@ -194548,7 +194763,7 @@ function writeExecutionMetrics(input) {
|
|
|
194548
194763
|
runtime: input.runtime ?? existing?.runtime,
|
|
194549
194764
|
updatedAt: new Date().toISOString()
|
|
194550
194765
|
};
|
|
194551
|
-
|
|
194766
|
+
writeFileSync16(metricsPath(input.sessionRootPath), JSON.stringify(next, null, 2), "utf-8");
|
|
194552
194767
|
writeSessionJsonTokenTotals(input.sessionRootPath, next.tokenUsage);
|
|
194553
194768
|
return next;
|
|
194554
194769
|
}
|
|
@@ -194611,8 +194826,8 @@ async function scoreEndpoints(input) {
|
|
|
194611
194826
|
} = input;
|
|
194612
194827
|
const results = new Map;
|
|
194613
194828
|
const scored = await runWithBoundedConcurrency(endpoints, concurrency, async (ep) => {
|
|
194614
|
-
const key = `${ep.file}:${ep.path}`;
|
|
194615
|
-
const subagentId = `risk-score-${ep.appName}-${ep.path}`;
|
|
194829
|
+
const key = `${ep.method}:${ep.file}:${ep.path}`;
|
|
194830
|
+
const subagentId = `risk-score-${ep.appName}-${ep.method}-${ep.path}`;
|
|
194616
194831
|
callbacks?.subagentCallbacks?.onSubagentSpawn?.({
|
|
194617
194832
|
subagentId,
|
|
194618
194833
|
input: { app: ep.appName, path: ep.path },
|
|
@@ -194922,7 +195137,7 @@ async function runWhiteboxAttackSurfaceWorkflow(input) {
|
|
|
194922
195137
|
}
|
|
194923
195138
|
}
|
|
194924
195139
|
function attachRiskScore(ep) {
|
|
194925
|
-
const key = `${ep.file}:${ep.path}`;
|
|
195140
|
+
const key = `${ep.method}:${ep.file}:${ep.path}`;
|
|
194926
195141
|
const score = riskScores.get(key);
|
|
194927
195142
|
return score ? { ...ep, riskScore: score } : ep;
|
|
194928
195143
|
}
|
|
@@ -195143,8 +195358,8 @@ __export(exports_pentest, {
|
|
|
195143
195358
|
runPentestSwarm: () => runPentestSwarm,
|
|
195144
195359
|
DEFAULT_CONCURRENCY: () => DEFAULT_CONCURRENCY4
|
|
195145
195360
|
});
|
|
195146
|
-
import { existsSync as
|
|
195147
|
-
import { join as
|
|
195361
|
+
import { existsSync as existsSync25, readdirSync as readdirSync5, readFileSync as readFileSync11, writeFileSync as writeFileSync17 } from "fs";
|
|
195362
|
+
import { join as join26 } from "path";
|
|
195148
195363
|
function addUsageTotals(totals, usage) {
|
|
195149
195364
|
if (!usage)
|
|
195150
195365
|
return;
|
|
@@ -195288,10 +195503,10 @@ async function runPentestWorkflow(input) {
|
|
|
195288
195503
|
sessionId: session.id,
|
|
195289
195504
|
mode
|
|
195290
195505
|
});
|
|
195291
|
-
const mdPath2 =
|
|
195292
|
-
const jsonPath2 =
|
|
195293
|
-
|
|
195294
|
-
|
|
195506
|
+
const mdPath2 = join26(session.rootPath, REPORT_FILENAME_MD);
|
|
195507
|
+
const jsonPath2 = join26(session.rootPath, REPORT_FILENAME_JSON);
|
|
195508
|
+
writeFileSync17(mdPath2, renderMarkdown(report2));
|
|
195509
|
+
writeFileSync17(jsonPath2, renderJson(report2));
|
|
195295
195510
|
return {
|
|
195296
195511
|
findings: [],
|
|
195297
195512
|
findingsPath: session.findingsPath,
|
|
@@ -195321,10 +195536,10 @@ async function runPentestWorkflow(input) {
|
|
|
195321
195536
|
sessionId: session.id,
|
|
195322
195537
|
mode
|
|
195323
195538
|
});
|
|
195324
|
-
const mdPath =
|
|
195325
|
-
const jsonPath =
|
|
195326
|
-
|
|
195327
|
-
|
|
195539
|
+
const mdPath = join26(session.rootPath, REPORT_FILENAME_MD);
|
|
195540
|
+
const jsonPath = join26(session.rootPath, REPORT_FILENAME_JSON);
|
|
195541
|
+
writeFileSync17(mdPath, renderMarkdown(report));
|
|
195542
|
+
writeFileSync17(jsonPath, renderJson(report));
|
|
195328
195543
|
return {
|
|
195329
195544
|
findings,
|
|
195330
195545
|
findingsPath: session.findingsPath,
|
|
@@ -195405,12 +195620,12 @@ async function runBlackboxPhase(opts) {
|
|
|
195405
195620
|
}
|
|
195406
195621
|
}
|
|
195407
195622
|
function loadFindings2(findingsPath) {
|
|
195408
|
-
if (!
|
|
195623
|
+
if (!existsSync25(findingsPath)) {
|
|
195409
195624
|
return [];
|
|
195410
195625
|
}
|
|
195411
195626
|
return readdirSync5(findingsPath).filter((f3) => f3.endsWith(".json")).map((f3) => {
|
|
195412
195627
|
try {
|
|
195413
|
-
const content = readFileSync11(
|
|
195628
|
+
const content = readFileSync11(join26(findingsPath, f3), "utf-8");
|
|
195414
195629
|
return JSON.parse(content);
|
|
195415
195630
|
} catch {
|
|
195416
195631
|
return null;
|
|
@@ -279864,8 +280079,8 @@ function KeybindingProvider({
|
|
|
279864
280079
|
// src/tui/components/pentest/pentest.tsx
|
|
279865
280080
|
var import_react74 = __toESM(require_react(), 1);
|
|
279866
280081
|
init_report();
|
|
279867
|
-
import { existsSync as
|
|
279868
|
-
import { join as
|
|
280082
|
+
import { existsSync as existsSync26, readdirSync as readdirSync6, readFileSync as readFileSync12 } from "fs";
|
|
280083
|
+
import { join as join27 } from "path";
|
|
279869
280084
|
init_session();
|
|
279870
280085
|
|
|
279871
280086
|
// src/core/session/loader.ts
|
|
@@ -283127,16 +283342,16 @@ function Pentest({
|
|
|
283127
283342
|
import_react74.useEffect(() => {
|
|
283128
283343
|
if (!session)
|
|
283129
283344
|
return;
|
|
283130
|
-
const assetsPath =
|
|
283345
|
+
const assetsPath = join27(session.rootPath, "assets");
|
|
283131
283346
|
function readAssets() {
|
|
283132
|
-
if (!
|
|
283347
|
+
if (!existsSync26(assetsPath))
|
|
283133
283348
|
return;
|
|
283134
283349
|
try {
|
|
283135
283350
|
const files = readdirSync6(assetsPath).filter((f3) => f3.endsWith(".json"));
|
|
283136
283351
|
const loaded = [];
|
|
283137
283352
|
for (const file2 of files) {
|
|
283138
283353
|
try {
|
|
283139
|
-
const content = readFileSync12(
|
|
283354
|
+
const content = readFileSync12(join27(assetsPath, file2), "utf-8");
|
|
283140
283355
|
loaded.push(JSON.parse(content));
|
|
283141
283356
|
} catch {}
|
|
283142
283357
|
}
|
|
@@ -285350,8 +285565,8 @@ function navigateDown(selectedIndex, queueLength) {
|
|
|
285350
285565
|
}
|
|
285351
285566
|
|
|
285352
285567
|
// src/tui/components/operator-dashboard/index.tsx
|
|
285353
|
-
import { existsSync as
|
|
285354
|
-
import { join as
|
|
285568
|
+
import { existsSync as existsSync27, readFileSync as readFileSync13 } from "fs";
|
|
285569
|
+
import { join as join28 } from "path";
|
|
285355
285570
|
function OperatorDashboard({
|
|
285356
285571
|
sessionId,
|
|
285357
285572
|
initialMessage,
|
|
@@ -285468,7 +285683,7 @@ function OperatorDashboard({
|
|
|
285468
285683
|
});
|
|
285469
285684
|
if (Array.isArray(savedState.messages) && savedState.messages.length > 0) {
|
|
285470
285685
|
const modelMsgs = savedState.messages;
|
|
285471
|
-
conversationRef.current = modelMsgs;
|
|
285686
|
+
conversationRef.current = sessions.getResumeMessages(modelMsgs);
|
|
285472
285687
|
const uiMsgs = convertModelMessagesToUI(modelMsgs);
|
|
285473
285688
|
setMessages(uiMsgs.map((m4) => ({
|
|
285474
285689
|
role: m4.role,
|
|
@@ -285904,15 +286119,28 @@ function OperatorDashboard({
|
|
|
285904
286119
|
setSession(created);
|
|
285905
286120
|
setSessionCwd(created.rootPath);
|
|
285906
286121
|
}
|
|
285907
|
-
|
|
285908
|
-
|
|
285909
|
-
|
|
285910
|
-
|
|
285911
|
-
|
|
285912
|
-
|
|
285913
|
-
|
|
286122
|
+
if (gen === generationRef.current) {
|
|
286123
|
+
try {
|
|
286124
|
+
const rootPath = agentResult.session.rootPath;
|
|
286125
|
+
const mp = join28(rootPath, "messages.json");
|
|
286126
|
+
if (existsSync27(mp)) {
|
|
286127
|
+
const raw = JSON.parse(readFileSync13(mp, "utf-8"));
|
|
286128
|
+
if (Array.isArray(raw) && raw.length > 0) {
|
|
286129
|
+
conversationRef.current = sessions.getResumeMessages(raw);
|
|
286130
|
+
}
|
|
286131
|
+
}
|
|
286132
|
+
} catch {
|
|
286133
|
+
try {
|
|
286134
|
+
const response = await agentResult.streamResult.response;
|
|
286135
|
+
if (response.messages) {
|
|
286136
|
+
conversationRef.current = [
|
|
286137
|
+
...nextMessages,
|
|
286138
|
+
...response.messages
|
|
286139
|
+
];
|
|
286140
|
+
}
|
|
286141
|
+
} catch {}
|
|
285914
286142
|
}
|
|
285915
|
-
}
|
|
286143
|
+
}
|
|
285916
286144
|
} catch (e2) {
|
|
285917
286145
|
if (gen !== generationRef.current)
|
|
285918
286146
|
return;
|
|
@@ -286103,11 +286331,11 @@ function OperatorDashboard({
|
|
|
286103
286331
|
approvalGateRef.current.denyAll();
|
|
286104
286332
|
if (session) {
|
|
286105
286333
|
try {
|
|
286106
|
-
const messagesPath =
|
|
286107
|
-
if (
|
|
286334
|
+
const messagesPath = join28(session.rootPath, "messages.json");
|
|
286335
|
+
if (existsSync27(messagesPath)) {
|
|
286108
286336
|
const raw = JSON.parse(readFileSync13(messagesPath, "utf-8"));
|
|
286109
286337
|
if (Array.isArray(raw) && raw.length > 0) {
|
|
286110
|
-
conversationRef.current = raw;
|
|
286338
|
+
conversationRef.current = sessions.getResumeMessages(raw);
|
|
286111
286339
|
}
|
|
286112
286340
|
}
|
|
286113
286341
|
} catch {}
|