@pensar/apex 0.0.65 → 0.0.66
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/README.md +1 -1
- package/build/index.js +654 -274
- package/package.json +1 -1
package/build/index.js
CHANGED
|
@@ -49473,19 +49473,19 @@ var require_token_io = __commonJS((exports, module2) => {
|
|
|
49473
49473
|
getUserDataDir: () => getUserDataDir
|
|
49474
49474
|
});
|
|
49475
49475
|
module2.exports = __toCommonJS2(token_io_exports);
|
|
49476
|
-
var
|
|
49477
|
-
var
|
|
49478
|
-
var
|
|
49476
|
+
var import_path11 = __toESM2(__require("path"));
|
|
49477
|
+
var import_fs10 = __toESM2(__require("fs"));
|
|
49478
|
+
var import_os7 = __toESM2(__require("os"));
|
|
49479
49479
|
var import_token_error = require_token_error();
|
|
49480
49480
|
function findRootDir() {
|
|
49481
49481
|
try {
|
|
49482
49482
|
let dir = process.cwd();
|
|
49483
|
-
while (dir !==
|
|
49484
|
-
const pkgPath =
|
|
49485
|
-
if (
|
|
49483
|
+
while (dir !== import_path11.default.dirname(dir)) {
|
|
49484
|
+
const pkgPath = import_path11.default.join(dir, ".vercel");
|
|
49485
|
+
if (import_fs10.default.existsSync(pkgPath)) {
|
|
49486
49486
|
return dir;
|
|
49487
49487
|
}
|
|
49488
|
-
dir =
|
|
49488
|
+
dir = import_path11.default.dirname(dir);
|
|
49489
49489
|
}
|
|
49490
49490
|
} catch (e) {
|
|
49491
49491
|
throw new import_token_error.VercelOidcTokenError("Token refresh only supported in node server environments");
|
|
@@ -49496,11 +49496,11 @@ var require_token_io = __commonJS((exports, module2) => {
|
|
|
49496
49496
|
if (process.env.XDG_DATA_HOME) {
|
|
49497
49497
|
return process.env.XDG_DATA_HOME;
|
|
49498
49498
|
}
|
|
49499
|
-
switch (
|
|
49499
|
+
switch (import_os7.default.platform()) {
|
|
49500
49500
|
case "darwin":
|
|
49501
|
-
return
|
|
49501
|
+
return import_path11.default.join(import_os7.default.homedir(), "Library/Application Support");
|
|
49502
49502
|
case "linux":
|
|
49503
|
-
return
|
|
49503
|
+
return import_path11.default.join(import_os7.default.homedir(), ".local/share");
|
|
49504
49504
|
case "win32":
|
|
49505
49505
|
if (process.env.LOCALAPPDATA) {
|
|
49506
49506
|
return process.env.LOCALAPPDATA;
|
|
@@ -49609,10 +49609,10 @@ var require_oauth = __commonJS((exports, module2) => {
|
|
|
49609
49609
|
refreshTokenRequest: () => refreshTokenRequest
|
|
49610
49610
|
});
|
|
49611
49611
|
module2.exports = __toCommonJS2(oauth_exports);
|
|
49612
|
-
var
|
|
49612
|
+
var import_os7 = __require("os");
|
|
49613
49613
|
var VERCEL_ISSUER = "https://vercel.com";
|
|
49614
49614
|
var VERCEL_CLI_CLIENT_ID = "cl_HYyOPBNtFMfHhaUn9L4QPfTZz6TP47bp";
|
|
49615
|
-
var userAgent = `@vercel/oidc node-${process.version} ${(0,
|
|
49615
|
+
var userAgent = `@vercel/oidc node-${process.version} ${(0, import_os7.platform)()} (${(0, import_os7.arch)()}) ${(0, import_os7.hostname)()}`;
|
|
49616
49616
|
var _tokenEndpoint = null;
|
|
49617
49617
|
async function getTokenEndpoint() {
|
|
49618
49618
|
if (_tokenEndpoint) {
|
|
@@ -61019,11 +61019,11 @@ Submit the final structured report. Call this ONCE at the very end with complete
|
|
|
61019
61019
|
If resuming from a previous run, review the assets already in the session assets folder and continue where you left off.`;
|
|
61020
61020
|
|
|
61021
61021
|
// src/core/agents/specialized/utils.ts
|
|
61022
|
-
import { readFileSync as
|
|
61022
|
+
import { readFileSync as readFileSync3, existsSync as existsSync9 } from "fs";
|
|
61023
61023
|
import { execSync } from "child_process";
|
|
61024
61024
|
function readOsRelease() {
|
|
61025
61025
|
try {
|
|
61026
|
-
const content =
|
|
61026
|
+
const content = readFileSync3("/etc/os-release", "utf8");
|
|
61027
61027
|
const lines = content.split(/\r?\n/);
|
|
61028
61028
|
const map2 = {};
|
|
61029
61029
|
for (const line of lines) {
|
|
@@ -61044,11 +61044,11 @@ function readOsRelease() {
|
|
|
61044
61044
|
}
|
|
61045
61045
|
function detectDocker() {
|
|
61046
61046
|
try {
|
|
61047
|
-
if (
|
|
61047
|
+
if (existsSync9("/.dockerenv"))
|
|
61048
61048
|
return true;
|
|
61049
61049
|
} catch {}
|
|
61050
61050
|
try {
|
|
61051
|
-
const cgroup =
|
|
61051
|
+
const cgroup = readFileSync3("/proc/1/cgroup", "utf8");
|
|
61052
61052
|
if (/docker|containerd|kubepods/i.test(cgroup))
|
|
61053
61053
|
return true;
|
|
61054
61054
|
} catch {}
|
|
@@ -61128,9 +61128,9 @@ ${prompt}`;
|
|
|
61128
61128
|
var init_utils = () => {};
|
|
61129
61129
|
|
|
61130
61130
|
// src/core/agents/specialized/attackSurface/types.ts
|
|
61131
|
-
import { readFileSync as
|
|
61131
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
61132
61132
|
function loadAttackSurfaceResults(resultsPath) {
|
|
61133
|
-
const data =
|
|
61133
|
+
const data = readFileSync4(resultsPath, "utf-8");
|
|
61134
61134
|
return JSON.parse(data);
|
|
61135
61135
|
}
|
|
61136
61136
|
var init_types2 = () => {};
|
|
@@ -104156,7 +104156,7 @@ var init_stdio2 = __esm(() => {
|
|
|
104156
104156
|
});
|
|
104157
104157
|
|
|
104158
104158
|
// src/core/agents/offSecAgent/tools/playwrightMcp.ts
|
|
104159
|
-
import { writeFileSync as
|
|
104159
|
+
import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync2, existsSync as existsSync10 } from "fs";
|
|
104160
104160
|
import { join as join3, dirname as dirname2 } from "path";
|
|
104161
104161
|
async function initializeMcpClient() {
|
|
104162
104162
|
if (mcpClient) {
|
|
@@ -104239,8 +104239,8 @@ function createBrowserTools(targetUrl, evidenceDir, mode = "pentest", logger, ab
|
|
|
104239
104239
|
abortSignal?.addEventListener("abort", () => {
|
|
104240
104240
|
disconnectMcpClient().catch(() => {});
|
|
104241
104241
|
});
|
|
104242
|
-
if (!
|
|
104243
|
-
|
|
104242
|
+
if (!existsSync10(evidenceDir)) {
|
|
104243
|
+
mkdirSync2(evidenceDir, { recursive: true });
|
|
104244
104244
|
}
|
|
104245
104245
|
const descriptions = mode === "pentest" ? PENTEST_DESCRIPTIONS : mode === "auth" ? AUTH_DESCRIPTIONS : OPERATOR_DESCRIPTIONS;
|
|
104246
104246
|
const browser_navigate = tool2({
|
|
@@ -104280,10 +104280,10 @@ Target base URL: ${targetUrl}`,
|
|
|
104280
104280
|
const screenshotFilename = `${filename}_${timestamp}.png`;
|
|
104281
104281
|
const screenshotPath = join3(evidenceDir, screenshotFilename);
|
|
104282
104282
|
const dir = dirname2(screenshotPath);
|
|
104283
|
-
if (!
|
|
104284
|
-
|
|
104283
|
+
if (!existsSync10(dir)) {
|
|
104284
|
+
mkdirSync2(dir, { recursive: true });
|
|
104285
104285
|
}
|
|
104286
|
-
|
|
104286
|
+
writeFileSync3(screenshotPath, Buffer.from(result.data, "base64"));
|
|
104287
104287
|
return {
|
|
104288
104288
|
success: true,
|
|
104289
104289
|
path: screenshotPath,
|
|
@@ -104725,6 +104725,32 @@ IMPORTANT: Always analyze results and adjust your approach based on findings.`,
|
|
|
104725
104725
|
command
|
|
104726
104726
|
};
|
|
104727
104727
|
}
|
|
104728
|
+
if (ctx4.sandbox) {
|
|
104729
|
+
try {
|
|
104730
|
+
const ssmTimeout = Math.max(Math.ceil(timeout / 1000), 30);
|
|
104731
|
+
const result = await ctx4.sandbox.execute(command, {
|
|
104732
|
+
timeout: ssmTimeout
|
|
104733
|
+
});
|
|
104734
|
+
return {
|
|
104735
|
+
success: result.success,
|
|
104736
|
+
error: !result.success ? result.stderr || "Command failed" : "",
|
|
104737
|
+
stdout: result.stdout.length > 50000 ? `${result.stdout.substring(0, 50000)}...
|
|
104738
|
+
|
|
104739
|
+
(truncated) call the command again with grep / tail to paginate` : result.stdout || "(no output)",
|
|
104740
|
+
stderr: result.stderr || "",
|
|
104741
|
+
command
|
|
104742
|
+
};
|
|
104743
|
+
} catch (error41) {
|
|
104744
|
+
const msg = error41 instanceof Error ? error41.message : String(error41);
|
|
104745
|
+
return {
|
|
104746
|
+
success: false,
|
|
104747
|
+
error: msg,
|
|
104748
|
+
stdout: "",
|
|
104749
|
+
stderr: msg,
|
|
104750
|
+
command
|
|
104751
|
+
};
|
|
104752
|
+
}
|
|
104753
|
+
}
|
|
104728
104754
|
return new Promise((resolve4) => {
|
|
104729
104755
|
const shellCmd = process.platform === "win32" ? "cmd" : "bash";
|
|
104730
104756
|
const shellArgs = process.platform === "win32" ? ["/c", command] : ["-lc", command];
|
|
@@ -104823,6 +104849,16 @@ COMMON TESTING PATTERNS:
|
|
|
104823
104849
|
followRedirects,
|
|
104824
104850
|
timeout
|
|
104825
104851
|
}) => {
|
|
104852
|
+
if (ctx4.sandbox) {
|
|
104853
|
+
return executeSandboxHttpRequest(ctx4, {
|
|
104854
|
+
url: url2,
|
|
104855
|
+
method,
|
|
104856
|
+
headers,
|
|
104857
|
+
body,
|
|
104858
|
+
followRedirects,
|
|
104859
|
+
timeout
|
|
104860
|
+
});
|
|
104861
|
+
}
|
|
104826
104862
|
let timeoutId;
|
|
104827
104863
|
try {
|
|
104828
104864
|
if (ctx4.abortSignal?.aborted) {
|
|
@@ -104890,6 +104926,82 @@ COMMON TESTING PATTERNS:
|
|
|
104890
104926
|
}
|
|
104891
104927
|
});
|
|
104892
104928
|
}
|
|
104929
|
+
async function executeSandboxHttpRequest(ctx4, opts) {
|
|
104930
|
+
const { url: url2, method, headers, body, followRedirects, timeout } = opts;
|
|
104931
|
+
try {
|
|
104932
|
+
let curlCommand = `curl -i -X ${method}`;
|
|
104933
|
+
if (headers) {
|
|
104934
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
104935
|
+
curlCommand += ` -H "${key}: ${value}"`;
|
|
104936
|
+
}
|
|
104937
|
+
}
|
|
104938
|
+
if (body && ["POST", "PUT", "PATCH"].includes(method)) {
|
|
104939
|
+
const escapedBody = body.replace(/"/g, "\\\"").replace(/\$/g, "\\$");
|
|
104940
|
+
curlCommand += ` -d "${escapedBody}"`;
|
|
104941
|
+
}
|
|
104942
|
+
if (followRedirects) {
|
|
104943
|
+
curlCommand += " -L";
|
|
104944
|
+
}
|
|
104945
|
+
const timeoutSeconds = Math.ceil(timeout / 1000);
|
|
104946
|
+
curlCommand += ` --max-time ${timeoutSeconds}`;
|
|
104947
|
+
curlCommand += ` "${url2}" 2>&1`;
|
|
104948
|
+
const ssmTimeout = Math.max(timeoutSeconds, 30);
|
|
104949
|
+
const result = await ctx4.sandbox.execute(curlCommand, {
|
|
104950
|
+
timeout: ssmTimeout
|
|
104951
|
+
});
|
|
104952
|
+
const output = result.stdout || "";
|
|
104953
|
+
const lines = output.split(`
|
|
104954
|
+
`);
|
|
104955
|
+
let statusLine = "";
|
|
104956
|
+
const responseHeaders = {};
|
|
104957
|
+
let bodyStartIndex = 0;
|
|
104958
|
+
for (let i = 0;i < lines.length; i++) {
|
|
104959
|
+
const line = lines[i];
|
|
104960
|
+
if (line.startsWith("HTTP/")) {
|
|
104961
|
+
statusLine = line;
|
|
104962
|
+
for (let j2 = i + 1;j2 < lines.length; j2++) {
|
|
104963
|
+
if (lines[j2].trim() === "") {
|
|
104964
|
+
bodyStartIndex = j2 + 1;
|
|
104965
|
+
break;
|
|
104966
|
+
}
|
|
104967
|
+
const headerMatch = lines[j2].match(/^([^:]+):\s*(.+)$/);
|
|
104968
|
+
if (headerMatch) {
|
|
104969
|
+
responseHeaders[headerMatch[1].toLowerCase()] = headerMatch[2];
|
|
104970
|
+
}
|
|
104971
|
+
}
|
|
104972
|
+
break;
|
|
104973
|
+
}
|
|
104974
|
+
}
|
|
104975
|
+
const statusMatch = statusLine.match(/HTTP\/[\d.]+\s+(\d+)\s+(.+)/);
|
|
104976
|
+
const status = statusMatch ? parseInt(statusMatch[1]) : 0;
|
|
104977
|
+
const statusText = statusMatch ? statusMatch[2] : "Unknown";
|
|
104978
|
+
const responseBody = lines.slice(bodyStartIndex).join(`
|
|
104979
|
+
`);
|
|
104980
|
+
return {
|
|
104981
|
+
success: status >= 200 && status < 400,
|
|
104982
|
+
status,
|
|
104983
|
+
statusText,
|
|
104984
|
+
headers: responseHeaders,
|
|
104985
|
+
body: responseBody.length > 5000 ? `${responseBody.substring(0, 5000)}...
|
|
104986
|
+
|
|
104987
|
+
(truncated) use execute_command with grep / tail to paginate the response` : responseBody,
|
|
104988
|
+
url: url2,
|
|
104989
|
+
redirected: false
|
|
104990
|
+
};
|
|
104991
|
+
} catch (error41) {
|
|
104992
|
+
const msg = error41 instanceof Error ? error41.message : String(error41);
|
|
104993
|
+
return {
|
|
104994
|
+
success: false,
|
|
104995
|
+
error: msg,
|
|
104996
|
+
status: 0,
|
|
104997
|
+
statusText: "Error",
|
|
104998
|
+
headers: {},
|
|
104999
|
+
body: "",
|
|
105000
|
+
url: url2,
|
|
105001
|
+
redirected: false
|
|
105002
|
+
};
|
|
105003
|
+
}
|
|
105004
|
+
}
|
|
104893
105005
|
var httpRequestInputSchema;
|
|
104894
105006
|
var init_httpRequest = __esm(() => {
|
|
104895
105007
|
init_dist7();
|
|
@@ -104916,7 +105028,7 @@ var init_httpRequest = __esm(() => {
|
|
|
104916
105028
|
|
|
104917
105029
|
// src/core/agents/offSecAgent/tools/documentFinding.ts
|
|
104918
105030
|
import { join as join5 } from "path";
|
|
104919
|
-
import { writeFileSync as
|
|
105031
|
+
import { writeFileSync as writeFileSync4, appendFileSync as appendFileSync2 } from "fs";
|
|
104920
105032
|
function documentFinding(ctx4) {
|
|
104921
105033
|
const { session } = ctx4;
|
|
104922
105034
|
return tool2({
|
|
@@ -104952,7 +105064,7 @@ FINDING STRUCTURE:
|
|
|
104952
105064
|
const jsonPath = join5(session.findingsPath, jsonFilename);
|
|
104953
105065
|
const mdFilename = `${findingId}.md`;
|
|
104954
105066
|
const mdPath = join5(session.findingsPath, mdFilename);
|
|
104955
|
-
|
|
105067
|
+
writeFileSync4(jsonPath, JSON.stringify(findingWithMeta, null, 2));
|
|
104956
105068
|
const markdown = `# ${finding.title}
|
|
104957
105069
|
|
|
104958
105070
|
**Severity:** ${finding.severity}
|
|
@@ -104991,12 +105103,12 @@ ${finding.references}` : ""}
|
|
|
104991
105103
|
|
|
104992
105104
|
*This finding was automatically documented by the Pensar penetration testing agent.*
|
|
104993
105105
|
`;
|
|
104994
|
-
|
|
105106
|
+
writeFileSync4(mdPath, markdown);
|
|
104995
105107
|
const summaryPath = join5(session.rootPath, "findings-summary.md");
|
|
104996
105108
|
const summaryEntry = `- [${finding.severity}] ${finding.title} - \`findings/${mdFilename}\`
|
|
104997
105109
|
`;
|
|
104998
105110
|
try {
|
|
104999
|
-
|
|
105111
|
+
appendFileSync2(summaryPath, summaryEntry);
|
|
105000
105112
|
} catch {
|
|
105001
105113
|
const header = `# Findings Summary
|
|
105002
105114
|
|
|
@@ -105006,7 +105118,7 @@ ${finding.references}` : ""}
|
|
|
105006
105118
|
## All Findings
|
|
105007
105119
|
|
|
105008
105120
|
`;
|
|
105009
|
-
|
|
105121
|
+
writeFileSync4(summaryPath, header + summaryEntry);
|
|
105010
105122
|
}
|
|
105011
105123
|
return {
|
|
105012
105124
|
success: true,
|
|
@@ -105047,11 +105159,11 @@ var init_documentFinding = __esm(() => {
|
|
|
105047
105159
|
import { join as join6 } from "path";
|
|
105048
105160
|
import { spawn as spawn3 } from "child_process";
|
|
105049
105161
|
import {
|
|
105050
|
-
existsSync as
|
|
105051
|
-
writeFileSync as
|
|
105162
|
+
existsSync as existsSync11,
|
|
105163
|
+
writeFileSync as writeFileSync5,
|
|
105052
105164
|
chmodSync,
|
|
105053
105165
|
unlinkSync,
|
|
105054
|
-
mkdirSync as
|
|
105166
|
+
mkdirSync as mkdirSync3
|
|
105055
105167
|
} from "fs";
|
|
105056
105168
|
function sanitizeFilename(str) {
|
|
105057
105169
|
return str.toLowerCase().replace(/[^a-z0-9_-]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "").substring(0, 50);
|
|
@@ -105090,67 +105202,126 @@ Max ${MAX_POC_ATTEMPTS} attempts per approach before pivoting.`,
|
|
|
105090
105202
|
attemptsRemaining: 0
|
|
105091
105203
|
};
|
|
105092
105204
|
}
|
|
105205
|
+
if (ctx4.sandbox) {
|
|
105206
|
+
return executeSandboxPoc(ctx4, poc, currentAttempts);
|
|
105207
|
+
}
|
|
105208
|
+
return executeLocalPoc(ctx4, poc, currentAttempts);
|
|
105209
|
+
}
|
|
105210
|
+
});
|
|
105211
|
+
}
|
|
105212
|
+
async function executeLocalPoc(ctx4, poc, currentAttempts) {
|
|
105213
|
+
try {
|
|
105214
|
+
const pocsPath = ctx4.session.pocsPath;
|
|
105215
|
+
if (!existsSync11(pocsPath)) {
|
|
105216
|
+
mkdirSync3(pocsPath, { recursive: true });
|
|
105217
|
+
}
|
|
105218
|
+
const { filename, pocContent } = preparePoc(poc, currentAttempts);
|
|
105219
|
+
const pocPath = join6(pocsPath, filename);
|
|
105220
|
+
writeFileSync5(pocPath, pocContent);
|
|
105221
|
+
chmodSync(pocPath, 493);
|
|
105222
|
+
const runner = poc.pocType === "bash" ? "bash" : poc.pocType === "python" ? "python3" : "node";
|
|
105223
|
+
const { stdout, stderr, exitCode } = await runScript(runner, pocPath, 60000, ctx4.abortSignal);
|
|
105224
|
+
if (exitCode !== 0) {
|
|
105225
|
+
try {
|
|
105226
|
+
unlinkSync(pocPath);
|
|
105227
|
+
} catch {}
|
|
105228
|
+
}
|
|
105229
|
+
return {
|
|
105230
|
+
success: exitCode === 0,
|
|
105231
|
+
pocPath: exitCode === 0 ? `pocs/${filename}` : undefined,
|
|
105232
|
+
stdout,
|
|
105233
|
+
stderr,
|
|
105234
|
+
exitCode,
|
|
105235
|
+
attemptsRemaining: MAX_POC_ATTEMPTS - currentAttempts,
|
|
105236
|
+
error: exitCode !== 0 ? `POC exited with code ${exitCode}. ${MAX_POC_ATTEMPTS - currentAttempts} attempts remaining.` : undefined
|
|
105237
|
+
};
|
|
105238
|
+
} catch (error41) {
|
|
105239
|
+
const errorMsg = error41 instanceof Error ? error41.message : String(error41);
|
|
105240
|
+
return {
|
|
105241
|
+
success: false,
|
|
105242
|
+
error: errorMsg,
|
|
105243
|
+
attemptsRemaining: MAX_POC_ATTEMPTS - currentAttempts
|
|
105244
|
+
};
|
|
105245
|
+
}
|
|
105246
|
+
}
|
|
105247
|
+
async function executeSandboxPoc(ctx4, poc, currentAttempts) {
|
|
105248
|
+
try {
|
|
105249
|
+
const { filename, pocContent } = preparePoc(poc, currentAttempts);
|
|
105250
|
+
const localPocsPath = ctx4.session.pocsPath;
|
|
105251
|
+
if (!existsSync11(localPocsPath)) {
|
|
105252
|
+
mkdirSync3(localPocsPath, { recursive: true });
|
|
105253
|
+
}
|
|
105254
|
+
const localPocPath = join6(localPocsPath, filename);
|
|
105255
|
+
if (existsSync11(localPocPath)) {
|
|
105256
|
+
return {
|
|
105257
|
+
success: false,
|
|
105258
|
+
error: `POC already exists at: pocs/${filename}`,
|
|
105259
|
+
attemptsRemaining: MAX_POC_ATTEMPTS - currentAttempts
|
|
105260
|
+
};
|
|
105261
|
+
}
|
|
105262
|
+
writeFileSync5(localPocPath, pocContent);
|
|
105263
|
+
const sandboxPocPath = `/tmp/pocs/${filename}`;
|
|
105264
|
+
await ctx4.sandbox.execute("mkdir -p /tmp/pocs");
|
|
105265
|
+
const base64Content = Buffer.from(pocContent).toString("base64");
|
|
105266
|
+
await ctx4.sandbox.execute(`echo "${base64Content}" | base64 -d > ${sandboxPocPath}`);
|
|
105267
|
+
await ctx4.sandbox.execute(`chmod +x ${sandboxPocPath}`);
|
|
105268
|
+
const runner = poc.pocType === "bash" ? "bash" : poc.pocType === "python" ? "python3" : "node";
|
|
105269
|
+
const result = await ctx4.sandbox.execute(`cd /tmp && ${runner} ${sandboxPocPath}`, { timeout: 60 });
|
|
105270
|
+
const executionSuccess = result.success || result.exitCode === 0;
|
|
105271
|
+
if (!executionSuccess) {
|
|
105272
|
+
await ctx4.sandbox.execute(`rm -f ${sandboxPocPath}`);
|
|
105093
105273
|
try {
|
|
105094
|
-
|
|
105095
|
-
|
|
105096
|
-
|
|
105097
|
-
|
|
105098
|
-
|
|
105099
|
-
|
|
105100
|
-
|
|
105101
|
-
|
|
105102
|
-
|
|
105103
|
-
|
|
105104
|
-
|
|
105105
|
-
|
|
105274
|
+
unlinkSync(localPocPath);
|
|
105275
|
+
} catch {}
|
|
105276
|
+
}
|
|
105277
|
+
return {
|
|
105278
|
+
success: executionSuccess,
|
|
105279
|
+
pocPath: executionSuccess ? `pocs/${filename}` : undefined,
|
|
105280
|
+
stdout: result.stdout || "(no output)",
|
|
105281
|
+
stderr: executionSuccess ? result.stderr || "(no errors)" : (result.stderr || "POC execution failed") + `
|
|
105282
|
+
|
|
105283
|
+
POC file has been deleted.`,
|
|
105284
|
+
exitCode: result.exitCode,
|
|
105285
|
+
attemptsRemaining: MAX_POC_ATTEMPTS - currentAttempts,
|
|
105286
|
+
error: !executionSuccess ? `POC exited with code ${result.exitCode}. ${MAX_POC_ATTEMPTS - currentAttempts} attempts remaining.` : undefined
|
|
105287
|
+
};
|
|
105288
|
+
} catch (error41) {
|
|
105289
|
+
const errorMsg = error41 instanceof Error ? error41.message : String(error41);
|
|
105290
|
+
return {
|
|
105291
|
+
success: false,
|
|
105292
|
+
error: errorMsg,
|
|
105293
|
+
attemptsRemaining: MAX_POC_ATTEMPTS - currentAttempts
|
|
105294
|
+
};
|
|
105295
|
+
}
|
|
105296
|
+
}
|
|
105297
|
+
function preparePoc(poc, currentAttempts) {
|
|
105298
|
+
const extension = poc.pocType === "bash" ? ".sh" : poc.pocType === "python" ? ".py" : ".js";
|
|
105299
|
+
const sanitizedName = sanitizeFilename(poc.pocName);
|
|
105300
|
+
const filename = `poc_${sanitizedName}${extension}`;
|
|
105301
|
+
let pocContent = poc.pocContent.trim();
|
|
105302
|
+
if (!pocContent.startsWith("#!")) {
|
|
105303
|
+
const shebangs = {
|
|
105304
|
+
bash: `#!/bin/bash
|
|
105106
105305
|
set -e
|
|
105107
105306
|
|
|
105108
105307
|
`,
|
|
105109
|
-
|
|
105308
|
+
python: `#!/usr/bin/env python3
|
|
105110
105309
|
|
|
105111
105310
|
`,
|
|
105112
|
-
|
|
105311
|
+
javascript: `#!/usr/bin/env node
|
|
105113
105312
|
|
|
105114
105313
|
`
|
|
105115
|
-
|
|
105116
|
-
|
|
105117
|
-
|
|
105118
|
-
|
|
105119
|
-
|
|
105314
|
+
};
|
|
105315
|
+
pocContent = shebangs[poc.pocType] + pocContent;
|
|
105316
|
+
}
|
|
105317
|
+
const commentChar = poc.pocType === "javascript" ? "//" : "#";
|
|
105318
|
+
const header = `${commentChar} POC: ${poc.description}
|
|
105120
105319
|
${commentChar} Created: ${new Date().toISOString()}
|
|
105121
105320
|
${commentChar} Attempt: ${currentAttempts}/${MAX_POC_ATTEMPTS}
|
|
105122
105321
|
|
|
105123
105322
|
`;
|
|
105124
|
-
|
|
105125
|
-
|
|
105126
|
-
writeFileSync4(pocPath, pocContent);
|
|
105127
|
-
chmodSync(pocPath, 493);
|
|
105128
|
-
const runner = poc.pocType === "bash" ? "bash" : poc.pocType === "python" ? "python3" : "node";
|
|
105129
|
-
const { stdout, stderr, exitCode } = await runScript(runner, pocPath, 60000, ctx4.abortSignal);
|
|
105130
|
-
if (exitCode !== 0) {
|
|
105131
|
-
try {
|
|
105132
|
-
unlinkSync(pocPath);
|
|
105133
|
-
} catch {}
|
|
105134
|
-
}
|
|
105135
|
-
return {
|
|
105136
|
-
success: exitCode === 0,
|
|
105137
|
-
pocPath: exitCode === 0 ? `pocs/${filename}` : undefined,
|
|
105138
|
-
stdout,
|
|
105139
|
-
stderr,
|
|
105140
|
-
exitCode,
|
|
105141
|
-
attemptsRemaining: MAX_POC_ATTEMPTS - currentAttempts,
|
|
105142
|
-
error: exitCode !== 0 ? `POC exited with code ${exitCode}. ${MAX_POC_ATTEMPTS - currentAttempts} attempts remaining.` : undefined
|
|
105143
|
-
};
|
|
105144
|
-
} catch (error41) {
|
|
105145
|
-
const errorMsg = error41 instanceof Error ? error41.message : String(error41);
|
|
105146
|
-
return {
|
|
105147
|
-
success: false,
|
|
105148
|
-
error: errorMsg,
|
|
105149
|
-
attemptsRemaining: MAX_POC_ATTEMPTS - currentAttempts
|
|
105150
|
-
};
|
|
105151
|
-
}
|
|
105152
|
-
}
|
|
105153
|
-
});
|
|
105323
|
+
pocContent = pocContent.replace(/^#!.*\n/, (match) => match + header);
|
|
105324
|
+
return { filename, pocContent };
|
|
105154
105325
|
}
|
|
105155
105326
|
function runScript(runner, scriptPath, timeout, abortSignal) {
|
|
105156
105327
|
return new Promise((resolve4) => {
|
|
@@ -105447,7 +105618,7 @@ var init_grep = __esm(() => {
|
|
|
105447
105618
|
|
|
105448
105619
|
// src/core/agents/offSecAgent/tools/documentAsset.ts
|
|
105449
105620
|
import { join as join8 } from "path";
|
|
105450
|
-
import { writeFileSync as
|
|
105621
|
+
import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync4, existsSync as existsSync12 } from "fs";
|
|
105451
105622
|
function documentAsset(ctx4) {
|
|
105452
105623
|
const assetsPath = join8(ctx4.session.rootPath, "assets");
|
|
105453
105624
|
return tool2({
|
|
@@ -105514,8 +105685,8 @@ Each asset creates a JSON file in the assets directory for tracking and analysis
|
|
|
105514
105685
|
toolCallDescription: exports_external.string().describe("A concise, human-readable description of what this tool call is doing")
|
|
105515
105686
|
}),
|
|
105516
105687
|
execute: async (asset) => {
|
|
105517
|
-
if (!
|
|
105518
|
-
|
|
105688
|
+
if (!existsSync12(assetsPath)) {
|
|
105689
|
+
mkdirSync4(assetsPath, { recursive: true });
|
|
105519
105690
|
}
|
|
105520
105691
|
const sanitizedName = asset.assetName.toLowerCase().replace(/[^a-z0-9-_.]/g, "_");
|
|
105521
105692
|
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
@@ -105527,7 +105698,7 @@ Each asset creates a JSON file in the assets directory for tracking and analysis
|
|
|
105527
105698
|
sessionId: ctx4.session.id,
|
|
105528
105699
|
target: ctx4.session.targets[0]
|
|
105529
105700
|
};
|
|
105530
|
-
|
|
105701
|
+
writeFileSync6(filepath, JSON.stringify(assetRecord, null, 2));
|
|
105531
105702
|
return {
|
|
105532
105703
|
success: true,
|
|
105533
105704
|
assetName: asset.assetName,
|
|
@@ -105546,7 +105717,7 @@ var init_documentAsset = __esm(() => {
|
|
|
105546
105717
|
|
|
105547
105718
|
// src/core/agents/offSecAgent/tools/authenticateSession.ts
|
|
105548
105719
|
import { join as join9 } from "path";
|
|
105549
|
-
import { writeFileSync as
|
|
105720
|
+
import { writeFileSync as writeFileSync7 } from "fs";
|
|
105550
105721
|
function authenticateSession(ctx4) {
|
|
105551
105722
|
return tool2({
|
|
105552
105723
|
description: `Authenticate with credentials and obtain a session cookie for subsequent authenticated requests.
|
|
@@ -105611,7 +105782,7 @@ Use this to:
|
|
|
105611
105782
|
loginUrl,
|
|
105612
105783
|
timestamp: new Date().toISOString()
|
|
105613
105784
|
};
|
|
105614
|
-
|
|
105785
|
+
writeFileSync7(sessionInfoPath, JSON.stringify(sessionInfo, null, 2));
|
|
105615
105786
|
return {
|
|
105616
105787
|
success: authenticated,
|
|
105617
105788
|
authenticated,
|
|
@@ -105923,7 +106094,7 @@ var init_authentication = __esm(() => {
|
|
|
105923
106094
|
|
|
105924
106095
|
// src/core/agents/offSecAgent/tools/delegateAuth.ts
|
|
105925
106096
|
import { join as join10 } from "path";
|
|
105926
|
-
import { writeFileSync as
|
|
106097
|
+
import { writeFileSync as writeFileSync8 } from "fs";
|
|
105927
106098
|
function mergeAuthCredentials(sessionCreds, explicit) {
|
|
105928
106099
|
const hasExplicit = explicit.username || explicit.password || explicit.apiKey || explicit.tokens;
|
|
105929
106100
|
const hasSession = sessionCreds && (sessionCreds.username || sessionCreds.password || sessionCreds.apiKey || sessionCreds.tokens);
|
|
@@ -106084,7 +106255,7 @@ When to use delegate_to_auth_subagent vs authenticate_session:
|
|
|
106084
106255
|
timestamp: new Date().toISOString(),
|
|
106085
106256
|
delegatedToSubagent: true
|
|
106086
106257
|
};
|
|
106087
|
-
|
|
106258
|
+
writeFileSync8(sessionInfoPath, JSON.stringify(sessionInfo, null, 2));
|
|
106088
106259
|
}
|
|
106089
106260
|
const hasHeaders = result.exportedHeaders && Object.keys(result.exportedHeaders).length > 0;
|
|
106090
106261
|
const hasCookies = result.exportedCookies && result.exportedCookies.length > 0;
|
|
@@ -106489,7 +106660,7 @@ var init_validateDiscovery = __esm(() => {
|
|
|
106489
106660
|
|
|
106490
106661
|
// src/core/agents/offSecAgent/tools/createAttackSurfaceReport.ts
|
|
106491
106662
|
import { join as join11 } from "path";
|
|
106492
|
-
import { writeFileSync as
|
|
106663
|
+
import { writeFileSync as writeFileSync9 } from "fs";
|
|
106493
106664
|
function createAttackSurfaceReport(ctx4) {
|
|
106494
106665
|
return tool2({
|
|
106495
106666
|
description: `Provide attack surface analysis results to the orchestrator agent.
|
|
@@ -106516,7 +106687,7 @@ Call this at the END of your analysis with:
|
|
|
106516
106687
|
}),
|
|
106517
106688
|
execute: async (results) => {
|
|
106518
106689
|
const resultsPath = join11(ctx4.session.rootPath, "attack-surface-results.json");
|
|
106519
|
-
|
|
106690
|
+
writeFileSync9(resultsPath, JSON.stringify(results, null, 2));
|
|
106520
106691
|
return {
|
|
106521
106692
|
success: true,
|
|
106522
106693
|
resultsPath,
|
|
@@ -106533,7 +106704,7 @@ var init_createAttackSurfaceReport = __esm(() => {
|
|
|
106533
106704
|
|
|
106534
106705
|
// src/core/agents/offSecAgent/tools/completeAuthentication.ts
|
|
106535
106706
|
import { join as join12 } from "path";
|
|
106536
|
-
import { existsSync as
|
|
106707
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync5, writeFileSync as writeFileSync10 } from "fs";
|
|
106537
106708
|
function completeAuthentication(ctx4) {
|
|
106538
106709
|
return tool2({
|
|
106539
106710
|
description: `Signal that the authentication process is complete.
|
|
@@ -106576,8 +106747,8 @@ This tool marks the end of the authentication flow.`,
|
|
|
106576
106747
|
if (result.success && (result.exportedCookies || result.exportedHeaders)) {
|
|
106577
106748
|
try {
|
|
106578
106749
|
const authDir = join12(ctx4.session.rootPath, AUTH_DIR);
|
|
106579
|
-
if (!
|
|
106580
|
-
|
|
106750
|
+
if (!existsSync13(authDir)) {
|
|
106751
|
+
mkdirSync5(authDir, { recursive: true });
|
|
106581
106752
|
}
|
|
106582
106753
|
authDataPath = join12(authDir, AUTH_DATA_FILENAME);
|
|
106583
106754
|
const authData = {
|
|
@@ -106589,7 +106760,7 @@ This tool marks the end of the authentication flow.`,
|
|
|
106589
106760
|
target: ctx4.target || "",
|
|
106590
106761
|
timestamp: new Date().toISOString()
|
|
106591
106762
|
};
|
|
106592
|
-
|
|
106763
|
+
writeFileSync10(authDataPath, JSON.stringify(authData, null, 2));
|
|
106593
106764
|
console.log(`Auth data persisted to ${authDataPath}`);
|
|
106594
106765
|
} catch (err) {
|
|
106595
106766
|
console.error(`Failed to persist auth data: ${err}`);
|
|
@@ -107299,16 +107470,16 @@ __export(exports_agent2, {
|
|
|
107299
107470
|
runPentestAgent: () => runPentestAgent,
|
|
107300
107471
|
TargetedPentestAgent: () => TargetedPentestAgent
|
|
107301
107472
|
});
|
|
107302
|
-
import { existsSync as
|
|
107473
|
+
import { existsSync as existsSync14, readdirSync as readdirSync2, readFileSync as readFileSync5 } from "fs";
|
|
107303
107474
|
import { join as join13 } from "path";
|
|
107304
107475
|
function buildPrompt2(target, objectives, sessionRootPath) {
|
|
107305
107476
|
const objectiveList = objectives.map((o, i) => `${i + 1}. ${o}`).join(`
|
|
107306
107477
|
`);
|
|
107307
107478
|
let authSection = "";
|
|
107308
107479
|
const authDataPath = join13(sessionRootPath, "auth", "auth-data.json");
|
|
107309
|
-
if (
|
|
107480
|
+
if (existsSync14(authDataPath)) {
|
|
107310
107481
|
try {
|
|
107311
|
-
const raw =
|
|
107482
|
+
const raw = readFileSync5(authDataPath, "utf-8");
|
|
107312
107483
|
const authData = JSON.parse(raw);
|
|
107313
107484
|
if (authData.authenticated) {
|
|
107314
107485
|
const parts = [
|
|
@@ -107354,12 +107525,12 @@ ${objectiveList}
|
|
|
107354
107525
|
Do NOT discover or enumerate other endpoints or services. Focus exclusively on the target and objectives above.`;
|
|
107355
107526
|
}
|
|
107356
107527
|
function loadFindings(findingsPath) {
|
|
107357
|
-
if (!
|
|
107528
|
+
if (!existsSync14(findingsPath)) {
|
|
107358
107529
|
return [];
|
|
107359
107530
|
}
|
|
107360
107531
|
return readdirSync2(findingsPath).filter((f) => f.endsWith(".json")).map((f) => {
|
|
107361
107532
|
try {
|
|
107362
|
-
const content =
|
|
107533
|
+
const content = readFileSync5(join13(findingsPath, f), "utf-8");
|
|
107363
107534
|
return JSON.parse(content);
|
|
107364
107535
|
} catch {
|
|
107365
107536
|
return null;
|
|
@@ -107416,7 +107587,8 @@ var init_agent3 = __esm(() => {
|
|
|
107416
107587
|
session,
|
|
107417
107588
|
authConfig,
|
|
107418
107589
|
onStepFinish,
|
|
107419
|
-
abortSignal
|
|
107590
|
+
abortSignal,
|
|
107591
|
+
sandbox
|
|
107420
107592
|
} = opts;
|
|
107421
107593
|
super({
|
|
107422
107594
|
system: PENTEST_SYSTEM_PROMPT,
|
|
@@ -107427,6 +107599,7 @@ var init_agent3 = __esm(() => {
|
|
|
107427
107599
|
authConfig,
|
|
107428
107600
|
onStepFinish,
|
|
107429
107601
|
abortSignal,
|
|
107602
|
+
sandbox,
|
|
107430
107603
|
activeTools: [
|
|
107431
107604
|
"execute_command",
|
|
107432
107605
|
"http_request",
|
|
@@ -107809,7 +107982,7 @@ var init_spawnCodingAgent = __esm(() => {
|
|
|
107809
107982
|
|
|
107810
107983
|
// src/core/agents/offSecAgent/tools/provideComparisonResults.ts
|
|
107811
107984
|
import { join as join14 } from "path";
|
|
107812
|
-
import { writeFileSync as
|
|
107985
|
+
import { writeFileSync as writeFileSync11 } from "fs";
|
|
107813
107986
|
function provideComparisonResults(ctx4) {
|
|
107814
107987
|
return tool2({
|
|
107815
107988
|
description: `Provide the final comparison results with matched, missed, and extra findings.
|
|
@@ -107856,7 +108029,7 @@ Results will be saved to: comparison-results.json in the session directory.`,
|
|
|
107856
108029
|
precision
|
|
107857
108030
|
};
|
|
107858
108031
|
const resultsPath = join14(ctx4.session.rootPath, "comparison-results.json");
|
|
107859
|
-
|
|
108032
|
+
writeFileSync11(resultsPath, JSON.stringify(result, null, 2));
|
|
107860
108033
|
return {
|
|
107861
108034
|
success: true,
|
|
107862
108035
|
resultsPath,
|
|
@@ -108087,7 +108260,8 @@ var init_offensiveSecurityAgent = __esm(() => {
|
|
|
108087
108260
|
model: input.model,
|
|
108088
108261
|
authConfig: input.authConfig,
|
|
108089
108262
|
callbacks: input.callbacks,
|
|
108090
|
-
subagentCallbacks: input.subagentCallbacks
|
|
108263
|
+
subagentCallbacks: input.subagentCallbacks,
|
|
108264
|
+
sandbox: input.sandbox
|
|
108091
108265
|
});
|
|
108092
108266
|
let tools = input.extraTools ? { ...builtinTools, ...input.extraTools } : { ...builtinTools };
|
|
108093
108267
|
let capturedResponse = null;
|
|
@@ -108191,7 +108365,7 @@ __export(exports_blackboxAgent, {
|
|
|
108191
108365
|
BlackboxAttackSurfaceAgent: () => BlackboxAttackSurfaceAgent
|
|
108192
108366
|
});
|
|
108193
108367
|
import { join as join15 } from "path";
|
|
108194
|
-
import { existsSync as
|
|
108368
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync6, writeFileSync as writeFileSync12 } from "fs";
|
|
108195
108369
|
function buildPrompt4(target, session) {
|
|
108196
108370
|
const scopeConstraints = session.config?.scopeConstraints;
|
|
108197
108371
|
const authenticationInstructions = session.config?.authenticationInstructions;
|
|
@@ -108285,8 +108459,8 @@ var init_blackboxAgent = __esm(() => {
|
|
|
108285
108459
|
const resultsPath = join15(session.rootPath, "attack-surface-results.json");
|
|
108286
108460
|
const assetsPath = join15(session.rootPath, "assets");
|
|
108287
108461
|
const subagentFolder = join15(session.rootPath, "subagents", "attack-surface-agent");
|
|
108288
|
-
if (!
|
|
108289
|
-
|
|
108462
|
+
if (!existsSync15(subagentFolder)) {
|
|
108463
|
+
mkdirSync6(subagentFolder, { recursive: true });
|
|
108290
108464
|
}
|
|
108291
108465
|
super({
|
|
108292
108466
|
system: detectOSAndEnhancePrompt(SYSTEM),
|
|
@@ -108299,7 +108473,7 @@ var init_blackboxAgent = __esm(() => {
|
|
|
108299
108473
|
onStepFinish?.(e);
|
|
108300
108474
|
const messages = e.response.messages;
|
|
108301
108475
|
if (messages !== undefined) {
|
|
108302
|
-
|
|
108476
|
+
writeFileSync12(join15(subagentFolder, "attack-surface-agent.log"), JSON.stringify(messages, null, 2));
|
|
108303
108477
|
}
|
|
108304
108478
|
},
|
|
108305
108479
|
abortSignal,
|
|
@@ -108324,7 +108498,7 @@ var init_blackboxAgent = __esm(() => {
|
|
|
108324
108498
|
resolveResult: () => {
|
|
108325
108499
|
let results = null;
|
|
108326
108500
|
let targets = [];
|
|
108327
|
-
if (
|
|
108501
|
+
if (existsSync15(resultsPath)) {
|
|
108328
108502
|
try {
|
|
108329
108503
|
results = loadAttackSurfaceResults(resultsPath);
|
|
108330
108504
|
targets = results.targets || [];
|
|
@@ -135125,7 +135299,7 @@ var useTerminalDimensions = () => {
|
|
|
135125
135299
|
};
|
|
135126
135300
|
|
|
135127
135301
|
// src/tui/index.tsx
|
|
135128
|
-
var
|
|
135302
|
+
var import_react83 = __toESM(require_react(), 1);
|
|
135129
135303
|
|
|
135130
135304
|
// src/tui/components/footer.tsx
|
|
135131
135305
|
import os5 from "os";
|
|
@@ -142370,6 +142544,206 @@ function ResponsibleUseDisclosure({
|
|
|
142370
142544
|
}, undefined, true, undefined, this);
|
|
142371
142545
|
}
|
|
142372
142546
|
|
|
142547
|
+
// src/tui/context/toast.tsx
|
|
142548
|
+
var import_react53 = __toESM(require_react(), 1);
|
|
142549
|
+
var ToastContext = import_react53.createContext(null);
|
|
142550
|
+
var nextId = 0;
|
|
142551
|
+
var DEFAULT_DURATION = {
|
|
142552
|
+
default: 3000,
|
|
142553
|
+
warn: 4000,
|
|
142554
|
+
error: 5000
|
|
142555
|
+
};
|
|
142556
|
+
function ToastProvider({ children }) {
|
|
142557
|
+
const [toasts, setToasts] = import_react53.useState([]);
|
|
142558
|
+
const dismiss = import_react53.useCallback((id) => {
|
|
142559
|
+
setToasts((prev) => prev.filter((t2) => t2.id !== id));
|
|
142560
|
+
}, []);
|
|
142561
|
+
const toast = import_react53.useCallback((message, variant = "default", duration) => {
|
|
142562
|
+
const id = nextId++;
|
|
142563
|
+
const ms = duration ?? DEFAULT_DURATION[variant];
|
|
142564
|
+
setToasts((prev) => [...prev, { id, message, variant, duration: ms }]);
|
|
142565
|
+
setTimeout(() => dismiss(id), ms);
|
|
142566
|
+
}, [dismiss]);
|
|
142567
|
+
const value = import_react53.useMemo(() => ({ toasts, toast, dismiss }), [toasts, toast, dismiss]);
|
|
142568
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ToastContext.Provider, {
|
|
142569
|
+
value,
|
|
142570
|
+
children
|
|
142571
|
+
}, undefined, false, undefined, this);
|
|
142572
|
+
}
|
|
142573
|
+
function useToast() {
|
|
142574
|
+
const ctx4 = import_react53.useContext(ToastContext);
|
|
142575
|
+
if (!ctx4)
|
|
142576
|
+
throw new Error("useToast() must be used within <ToastProvider>");
|
|
142577
|
+
return ctx4;
|
|
142578
|
+
}
|
|
142579
|
+
|
|
142580
|
+
// src/tui/components/toast.tsx
|
|
142581
|
+
var VARIANT_ICONS = {
|
|
142582
|
+
default: "●",
|
|
142583
|
+
error: "✖",
|
|
142584
|
+
warn: "⚠"
|
|
142585
|
+
};
|
|
142586
|
+
function variantColor(variant, colors2) {
|
|
142587
|
+
switch (variant) {
|
|
142588
|
+
case "error":
|
|
142589
|
+
return colors2.error;
|
|
142590
|
+
case "warn":
|
|
142591
|
+
return colors2.warning;
|
|
142592
|
+
default:
|
|
142593
|
+
return colors2.info;
|
|
142594
|
+
}
|
|
142595
|
+
}
|
|
142596
|
+
function ToastItem({
|
|
142597
|
+
message,
|
|
142598
|
+
variant,
|
|
142599
|
+
onDismiss
|
|
142600
|
+
}) {
|
|
142601
|
+
const { colors: colors2 } = useTheme();
|
|
142602
|
+
const accent = variantColor(variant, colors2);
|
|
142603
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
142604
|
+
flexDirection: "row",
|
|
142605
|
+
gap: 1,
|
|
142606
|
+
paddingLeft: 1,
|
|
142607
|
+
paddingRight: 1,
|
|
142608
|
+
border: ["left"],
|
|
142609
|
+
borderColor: accent,
|
|
142610
|
+
backgroundColor: colors2.backgroundPanel,
|
|
142611
|
+
onMouseUp: () => onDismiss(),
|
|
142612
|
+
children: [
|
|
142613
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
142614
|
+
fg: accent,
|
|
142615
|
+
children: VARIANT_ICONS[variant]
|
|
142616
|
+
}, undefined, false, undefined, this),
|
|
142617
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
142618
|
+
fg: colors2.text,
|
|
142619
|
+
children: message
|
|
142620
|
+
}, undefined, false, undefined, this)
|
|
142621
|
+
]
|
|
142622
|
+
}, undefined, true, undefined, this);
|
|
142623
|
+
}
|
|
142624
|
+
function ToastContainer() {
|
|
142625
|
+
const { toasts, dismiss } = useToast();
|
|
142626
|
+
const dims = useTerminalDimensions();
|
|
142627
|
+
if (toasts.length === 0)
|
|
142628
|
+
return null;
|
|
142629
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
142630
|
+
position: "absolute",
|
|
142631
|
+
right: 1,
|
|
142632
|
+
top: 0,
|
|
142633
|
+
flexDirection: "column",
|
|
142634
|
+
gap: 0,
|
|
142635
|
+
alignItems: "flex-end",
|
|
142636
|
+
maxWidth: Math.min(60, dims.width - 4),
|
|
142637
|
+
zIndex: 9999,
|
|
142638
|
+
children: toasts.map((t2) => /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ToastItem, {
|
|
142639
|
+
message: t2.message,
|
|
142640
|
+
variant: t2.variant,
|
|
142641
|
+
onDismiss: () => dismiss(t2.id)
|
|
142642
|
+
}, t2.id, false, undefined, this))
|
|
142643
|
+
}, undefined, false, undefined, this);
|
|
142644
|
+
}
|
|
142645
|
+
|
|
142646
|
+
// src/tui/components/error-boundary.tsx
|
|
142647
|
+
var import_react55 = __toESM(require_react(), 1);
|
|
142648
|
+
|
|
142649
|
+
// src/core/logger/index.ts
|
|
142650
|
+
import {
|
|
142651
|
+
appendFileSync,
|
|
142652
|
+
existsSync as existsSync8,
|
|
142653
|
+
mkdirSync,
|
|
142654
|
+
readFileSync as readFileSync2,
|
|
142655
|
+
writeFileSync as writeFileSync2
|
|
142656
|
+
} from "fs";
|
|
142657
|
+
import os6 from "os";
|
|
142658
|
+
import path7 from "path";
|
|
142659
|
+
var ERROR_LOG_PATH = path7.join(os6.homedir(), ".pensar", "error.log");
|
|
142660
|
+
var RETENTION_DAYS = 7;
|
|
142661
|
+
var TIMESTAMP_RE = /^(\d{4}-\d{2}-\d{2}T[\d:.]+Z) - /;
|
|
142662
|
+
var hasPruned = false;
|
|
142663
|
+
function pruneErrorLog() {
|
|
142664
|
+
if (hasPruned)
|
|
142665
|
+
return;
|
|
142666
|
+
hasPruned = true;
|
|
142667
|
+
try {
|
|
142668
|
+
if (!existsSync8(ERROR_LOG_PATH))
|
|
142669
|
+
return;
|
|
142670
|
+
const cutoff = Date.now() - RETENTION_DAYS * 86400000;
|
|
142671
|
+
const raw = readFileSync2(ERROR_LOG_PATH, "utf8");
|
|
142672
|
+
const lines = raw.split(`
|
|
142673
|
+
`);
|
|
142674
|
+
const kept = [];
|
|
142675
|
+
let keeping = true;
|
|
142676
|
+
for (const line of lines) {
|
|
142677
|
+
const match = TIMESTAMP_RE.exec(line);
|
|
142678
|
+
if (match) {
|
|
142679
|
+
keeping = new Date(match[1]).getTime() >= cutoff;
|
|
142680
|
+
}
|
|
142681
|
+
if (keeping) {
|
|
142682
|
+
kept.push(line);
|
|
142683
|
+
}
|
|
142684
|
+
}
|
|
142685
|
+
writeFileSync2(ERROR_LOG_PATH, kept.join(`
|
|
142686
|
+
`), "utf8");
|
|
142687
|
+
} catch {}
|
|
142688
|
+
}
|
|
142689
|
+
function writeErrorLog(error, source) {
|
|
142690
|
+
try {
|
|
142691
|
+
pruneErrorLog();
|
|
142692
|
+
const dir = path7.dirname(ERROR_LOG_PATH);
|
|
142693
|
+
if (!existsSync8(dir)) {
|
|
142694
|
+
mkdirSync(dir, { recursive: true });
|
|
142695
|
+
}
|
|
142696
|
+
const timestamp = new Date().toISOString();
|
|
142697
|
+
const tag = source ? `[${source}] ` : "";
|
|
142698
|
+
const message = error instanceof Error ? `${error.message}
|
|
142699
|
+
${error.stack ?? ""}` : String(error);
|
|
142700
|
+
const entry = `${timestamp} - [ERROR] ${tag}${message}
|
|
142701
|
+
`;
|
|
142702
|
+
appendFileSync(ERROR_LOG_PATH, entry, "utf8");
|
|
142703
|
+
} catch {}
|
|
142704
|
+
}
|
|
142705
|
+
|
|
142706
|
+
// src/tui/components/error-boundary.tsx
|
|
142707
|
+
var MAX_ERRORS = 3;
|
|
142708
|
+
var ERROR_WINDOW_MS = 5000;
|
|
142709
|
+
|
|
142710
|
+
class ErrorBoundaryInner extends import_react55.default.Component {
|
|
142711
|
+
state = {
|
|
142712
|
+
hasError: false,
|
|
142713
|
+
errorTimestamps: [],
|
|
142714
|
+
halted: false
|
|
142715
|
+
};
|
|
142716
|
+
static getDerivedStateFromError() {
|
|
142717
|
+
return { hasError: true };
|
|
142718
|
+
}
|
|
142719
|
+
componentDidCatch(error) {
|
|
142720
|
+
console.error("[ErrorBoundary]", error);
|
|
142721
|
+
writeErrorLog(error, "TUI");
|
|
142722
|
+
this.props.onError(error.message);
|
|
142723
|
+
const now = Date.now();
|
|
142724
|
+
const recent = [...this.state.errorTimestamps, now].filter((t2) => now - t2 < ERROR_WINDOW_MS);
|
|
142725
|
+
if (recent.length >= MAX_ERRORS) {
|
|
142726
|
+
this.props.onError("Too many errors in quick succession — UI recovery halted.");
|
|
142727
|
+
this.setState({ halted: true, hasError: false, errorTimestamps: recent });
|
|
142728
|
+
return;
|
|
142729
|
+
}
|
|
142730
|
+
this.setState({ hasError: false, errorTimestamps: recent });
|
|
142731
|
+
}
|
|
142732
|
+
render() {
|
|
142733
|
+
if (this.state.halted) {
|
|
142734
|
+
return null;
|
|
142735
|
+
}
|
|
142736
|
+
return this.props.children;
|
|
142737
|
+
}
|
|
142738
|
+
}
|
|
142739
|
+
function ErrorBoundary2({ children }) {
|
|
142740
|
+
const { toast } = useToast();
|
|
142741
|
+
const handleError = import_react55.useCallback((message) => {
|
|
142742
|
+
toast(message, "error");
|
|
142743
|
+
}, [toast]);
|
|
142744
|
+
return import_react55.default.createElement(ErrorBoundaryInner, { onError: handleError }, children);
|
|
142745
|
+
}
|
|
142746
|
+
|
|
142373
142747
|
// src/tui/keybindings-registry.ts
|
|
142374
142748
|
var keybindings = [
|
|
142375
142749
|
{
|
|
@@ -142475,16 +142849,16 @@ function ShortcutsDialog({
|
|
|
142475
142849
|
}
|
|
142476
142850
|
|
|
142477
142851
|
// src/tui/components/commands/help-dialog.tsx
|
|
142478
|
-
var
|
|
142852
|
+
var import_react57 = __toESM(require_react(), 1);
|
|
142479
142853
|
function HelpDialog() {
|
|
142480
142854
|
const { colors: colors2 } = useTheme();
|
|
142481
142855
|
const { commands: commands2 } = useCommand();
|
|
142482
142856
|
const route = useRoute();
|
|
142483
142857
|
const dimensions = useTerminalDimensions();
|
|
142484
|
-
const [selectedIndex, setSelectedIndex] =
|
|
142485
|
-
const [showDetail, setShowDetail] =
|
|
142486
|
-
const scrollboxRef =
|
|
142487
|
-
const commandsByCategory =
|
|
142858
|
+
const [selectedIndex, setSelectedIndex] = import_react57.useState(0);
|
|
142859
|
+
const [showDetail, setShowDetail] = import_react57.useState(false);
|
|
142860
|
+
const scrollboxRef = import_react57.useRef(null);
|
|
142861
|
+
const commandsByCategory = import_react57.useMemo(() => {
|
|
142488
142862
|
const grouped = {};
|
|
142489
142863
|
for (const cmd of commands2) {
|
|
142490
142864
|
const category = cmd.category || "Other";
|
|
@@ -142495,15 +142869,15 @@ function HelpDialog() {
|
|
|
142495
142869
|
}
|
|
142496
142870
|
return grouped;
|
|
142497
142871
|
}, [commands2]);
|
|
142498
|
-
const flatCommands =
|
|
142872
|
+
const flatCommands = import_react57.useMemo(() => {
|
|
142499
142873
|
return commands2;
|
|
142500
142874
|
}, [commands2]);
|
|
142501
|
-
|
|
142875
|
+
import_react57.useEffect(() => {
|
|
142502
142876
|
if (selectedIndex >= flatCommands.length) {
|
|
142503
142877
|
setSelectedIndex(Math.max(0, flatCommands.length - 1));
|
|
142504
142878
|
}
|
|
142505
142879
|
}, [flatCommands.length, selectedIndex]);
|
|
142506
|
-
|
|
142880
|
+
import_react57.useEffect(() => {
|
|
142507
142881
|
scrollToIndex(scrollboxRef.current, selectedIndex, flatCommands, (cmd) => cmd.name);
|
|
142508
142882
|
}, [selectedIndex, flatCommands]);
|
|
142509
142883
|
const handleClose = () => {
|
|
@@ -142938,10 +143312,10 @@ function ModelsDisplay() {
|
|
|
142938
143312
|
}
|
|
142939
143313
|
|
|
142940
143314
|
// src/tui/context/keybinding.tsx
|
|
142941
|
-
var
|
|
143315
|
+
var import_react64 = __toESM(require_react(), 1);
|
|
142942
143316
|
|
|
142943
143317
|
// src/tui/keybindings/keybind.tsx
|
|
142944
|
-
var
|
|
143318
|
+
var import_react60 = __toESM(require_react(), 1);
|
|
142945
143319
|
|
|
142946
143320
|
// src/tui/keybindings/actions.ts
|
|
142947
143321
|
var movementActions = [
|
|
@@ -143193,7 +143567,7 @@ var allActions = [
|
|
|
143193
143567
|
var actionsByKey = new Map(allActions.map((action) => [action.key, action]));
|
|
143194
143568
|
var actionsById = new Map(allActions.map((action) => [action.id, action]));
|
|
143195
143569
|
// src/tui/keybindings/keybind.tsx
|
|
143196
|
-
var LeaderKeyContext =
|
|
143570
|
+
var LeaderKeyContext = import_react60.createContext(null);
|
|
143197
143571
|
// src/tui/keybindings/registry.ts
|
|
143198
143572
|
function createKeybindings(deps) {
|
|
143199
143573
|
const {
|
|
@@ -143399,7 +143773,7 @@ var Keybind;
|
|
|
143399
143773
|
})(Keybind ||= {});
|
|
143400
143774
|
|
|
143401
143775
|
// src/tui/context/keybinding.tsx
|
|
143402
|
-
var KeybindingContext =
|
|
143776
|
+
var KeybindingContext = import_react64.createContext(undefined);
|
|
143403
143777
|
function KeybindingProvider({
|
|
143404
143778
|
children,
|
|
143405
143779
|
deps
|
|
@@ -143438,15 +143812,15 @@ function KeybindingProvider({
|
|
|
143438
143812
|
}
|
|
143439
143813
|
|
|
143440
143814
|
// src/tui/components/pentest/pentest.tsx
|
|
143441
|
-
var
|
|
143442
|
-
import { existsSync as
|
|
143815
|
+
var import_react73 = __toESM(require_react(), 1);
|
|
143816
|
+
import { existsSync as existsSync17, readdirSync as readdirSync4, readFileSync as readFileSync7 } from "fs";
|
|
143443
143817
|
import { join as join17 } from "path";
|
|
143444
143818
|
import { exec as exec3 } from "child_process";
|
|
143445
143819
|
|
|
143446
143820
|
// src/core/workflows/pentest.ts
|
|
143447
143821
|
init_blackboxAgent();
|
|
143448
143822
|
init_agent3();
|
|
143449
|
-
import { existsSync as
|
|
143823
|
+
import { existsSync as existsSync16, readdirSync as readdirSync3, readFileSync as readFileSync6 } from "fs";
|
|
143450
143824
|
import { join as join16 } from "path";
|
|
143451
143825
|
|
|
143452
143826
|
// src/core/workflows/whiteboxAttackSurface.ts
|
|
@@ -143885,7 +144259,7 @@ async function runPentestWorkflow(input) {
|
|
|
143885
144259
|
findings,
|
|
143886
144260
|
findingsPath: session.findingsPath,
|
|
143887
144261
|
pocsPath: session.pocsPath,
|
|
143888
|
-
reportPath:
|
|
144262
|
+
reportPath: existsSync16(reportPath) ? reportPath : null
|
|
143889
144263
|
};
|
|
143890
144264
|
}
|
|
143891
144265
|
async function runWhiteboxPhase(opts) {
|
|
@@ -143955,12 +144329,12 @@ async function runWithBoundedConcurrency2(items, concurrency, fn) {
|
|
|
143955
144329
|
return results;
|
|
143956
144330
|
}
|
|
143957
144331
|
function loadFindings2(findingsPath) {
|
|
143958
|
-
if (!
|
|
144332
|
+
if (!existsSync16(findingsPath)) {
|
|
143959
144333
|
return [];
|
|
143960
144334
|
}
|
|
143961
144335
|
return readdirSync3(findingsPath).filter((f) => f.endsWith(".json")).map((f) => {
|
|
143962
144336
|
try {
|
|
143963
|
-
const content =
|
|
144337
|
+
const content = readFileSync6(join16(findingsPath, f), "utf-8");
|
|
143964
144338
|
return JSON.parse(content);
|
|
143965
144339
|
} catch {
|
|
143966
144340
|
return null;
|
|
@@ -143989,7 +144363,7 @@ Found ${findings.length} vulnerabilities`);
|
|
|
143989
144363
|
}
|
|
143990
144364
|
|
|
143991
144365
|
// src/tui/components/agent-display.tsx
|
|
143992
|
-
var
|
|
144366
|
+
var import_react71 = __toESM(require_react(), 1);
|
|
143993
144367
|
|
|
143994
144368
|
// node_modules/marked/lib/marked.esm.js
|
|
143995
144369
|
function L2() {
|
|
@@ -145755,14 +146129,14 @@ function getResultSummary(result, toolName) {
|
|
|
145755
146129
|
return null;
|
|
145756
146130
|
}
|
|
145757
146131
|
// src/tui/components/shared/ascii-spinner.tsx
|
|
145758
|
-
var
|
|
146132
|
+
var import_react65 = __toESM(require_react(), 1);
|
|
145759
146133
|
var SPINNER_FRAMES = ["/", "-", "\\", "|"];
|
|
145760
146134
|
var SPINNER_INTERVAL = 100;
|
|
145761
146135
|
function AsciiSpinner({ label, fg: fg2 }) {
|
|
145762
146136
|
const { colors: colors2 } = useTheme();
|
|
145763
146137
|
const spinnerColor = fg2 ?? colors2.info;
|
|
145764
|
-
const [frame, setFrame] =
|
|
145765
|
-
|
|
146138
|
+
const [frame, setFrame] = import_react65.useState(0);
|
|
146139
|
+
import_react65.useEffect(() => {
|
|
145766
146140
|
const interval = setInterval(() => {
|
|
145767
146141
|
setFrame((f) => (f + 1) % SPINNER_FRAMES.length);
|
|
145768
146142
|
}, SPINNER_INTERVAL);
|
|
@@ -145774,14 +146148,14 @@ function AsciiSpinner({ label, fg: fg2 }) {
|
|
|
145774
146148
|
}, undefined, false, undefined, this);
|
|
145775
146149
|
}
|
|
145776
146150
|
// src/tui/components/shared/tool-renderer.tsx
|
|
145777
|
-
var
|
|
145778
|
-
var ToolRenderer =
|
|
146151
|
+
var import_react66 = __toESM(require_react(), 1);
|
|
146152
|
+
var ToolRenderer = import_react66.memo(function ToolRenderer2({
|
|
145779
146153
|
message,
|
|
145780
146154
|
verbose = false,
|
|
145781
146155
|
expandedLogs = false
|
|
145782
146156
|
}) {
|
|
145783
146157
|
const { colors: colors2 } = useTheme();
|
|
145784
|
-
const [showOutput, setShowOutput] =
|
|
146158
|
+
const [showOutput, setShowOutput] = import_react66.useState(false);
|
|
145785
146159
|
if (!isToolMessage(message)) {
|
|
145786
146160
|
return null;
|
|
145787
146161
|
}
|
|
@@ -145878,8 +146252,8 @@ var ToolRenderer = import_react63.memo(function ToolRenderer2({
|
|
|
145878
146252
|
}, undefined, true, undefined, this);
|
|
145879
146253
|
});
|
|
145880
146254
|
// src/tui/components/shared/message-renderer.tsx
|
|
145881
|
-
var
|
|
145882
|
-
var MessageRenderer =
|
|
146255
|
+
var import_react67 = __toESM(require_react(), 1);
|
|
146256
|
+
var MessageRenderer = import_react67.memo(function MessageRenderer2({
|
|
145883
146257
|
message,
|
|
145884
146258
|
isStreaming = false,
|
|
145885
146259
|
verbose = false,
|
|
@@ -145889,7 +146263,7 @@ var MessageRenderer = import_react64.memo(function MessageRenderer2({
|
|
|
145889
146263
|
}) {
|
|
145890
146264
|
const { colors: colors2 } = useTheme();
|
|
145891
146265
|
const content = typeof message.content === "string" ? message.content : JSON.stringify(message.content);
|
|
145892
|
-
const displayContent =
|
|
146266
|
+
const displayContent = import_react67.useMemo(() => message.role === "assistant" ? markdownToStyledText(content, colors2) : content, [content, message.role, colors2]);
|
|
145893
146267
|
if (isToolMessage(message)) {
|
|
145894
146268
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ToolRenderer, {
|
|
145895
146269
|
message,
|
|
@@ -146001,9 +146375,9 @@ var MessageRenderer = import_react64.memo(function MessageRenderer2({
|
|
|
146001
146375
|
}, undefined, false, undefined, this);
|
|
146002
146376
|
});
|
|
146003
146377
|
// src/tui/components/shared/approval-prompt.tsx
|
|
146004
|
-
var
|
|
146378
|
+
var import_react68 = __toESM(require_react(), 1);
|
|
146005
146379
|
// src/tui/components/shared/message-reducer.ts
|
|
146006
|
-
var
|
|
146380
|
+
var import_react70 = __toESM(require_react(), 1);
|
|
146007
146381
|
// src/tui/components/agent-display.tsx
|
|
146008
146382
|
function getStableKey(item, contextId = "root") {
|
|
146009
146383
|
if ("messages" in item) {
|
|
@@ -146079,11 +146453,11 @@ function AgentDisplay({
|
|
|
146079
146453
|
]
|
|
146080
146454
|
}, undefined, true, undefined, this);
|
|
146081
146455
|
}
|
|
146082
|
-
var SubAgentDisplay =
|
|
146456
|
+
var SubAgentDisplay = import_react71.memo(function SubAgentDisplay2({
|
|
146083
146457
|
subagent
|
|
146084
146458
|
}) {
|
|
146085
146459
|
const { colors: colors2 } = useTheme();
|
|
146086
|
-
const [open, setOpen] =
|
|
146460
|
+
const [open, setOpen] = import_react71.useState(false);
|
|
146087
146461
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
146088
146462
|
height: open ? 40 : "auto",
|
|
146089
146463
|
onMouseDown: () => setOpen(!open),
|
|
@@ -146138,7 +146512,7 @@ var SubAgentDisplay = import_react68.memo(function SubAgentDisplay2({
|
|
|
146138
146512
|
]
|
|
146139
146513
|
}, undefined, true, undefined, this);
|
|
146140
146514
|
});
|
|
146141
|
-
var AgentMessage =
|
|
146515
|
+
var AgentMessage = import_react71.memo(function AgentMessage2({
|
|
146142
146516
|
message
|
|
146143
146517
|
}) {
|
|
146144
146518
|
const { colors: colors2 } = useTheme();
|
|
@@ -146251,8 +146625,8 @@ var AgentMessage = import_react68.memo(function AgentMessage2({
|
|
|
146251
146625
|
});
|
|
146252
146626
|
function ToolDetails({ message }) {
|
|
146253
146627
|
const { colors: colors2 } = useTheme();
|
|
146254
|
-
const [showArgs, setShowArgs] =
|
|
146255
|
-
const [showResult, setShowResult] =
|
|
146628
|
+
const [showArgs, setShowArgs] = import_react71.useState(false);
|
|
146629
|
+
const [showResult, setShowResult] = import_react71.useState(false);
|
|
146256
146630
|
if (message.role !== "tool") {
|
|
146257
146631
|
return null;
|
|
146258
146632
|
}
|
|
@@ -146329,24 +146703,24 @@ function Pentest({ sessionId }) {
|
|
|
146329
146703
|
const route = useRoute();
|
|
146330
146704
|
const { model, setThinking, setIsExecuting, isExecuting } = useAgent();
|
|
146331
146705
|
const { stack, externalDialogOpen } = useDialog();
|
|
146332
|
-
const [session, setSession] =
|
|
146333
|
-
const [error41, setError] =
|
|
146334
|
-
const [phase, setPhase] =
|
|
146335
|
-
const [abortController, setAbortController] =
|
|
146336
|
-
const [panelMessages, setPanelMessages] =
|
|
146337
|
-
const panelTextRef =
|
|
146338
|
-
const panelSourceRef =
|
|
146339
|
-
const [pentestAgents, setPentestAgents] =
|
|
146340
|
-
const pentestTextRefs =
|
|
146341
|
-
const [assets, setAssets] =
|
|
146342
|
-
const [viewMode, setViewMode] =
|
|
146343
|
-
const [selectedAgentId, setSelectedAgentId] =
|
|
146344
|
-
const [focusedIndex, setFocusedIndex] =
|
|
146345
|
-
const [showOrchestratorPanel, setShowOrchestratorPanel] =
|
|
146346
|
-
const [startTime, setStartTime] =
|
|
146347
|
-
const pentestAgentList =
|
|
146348
|
-
const selectedAgent =
|
|
146349
|
-
|
|
146706
|
+
const [session, setSession] = import_react73.useState(null);
|
|
146707
|
+
const [error41, setError] = import_react73.useState(null);
|
|
146708
|
+
const [phase, setPhase] = import_react73.useState("loading");
|
|
146709
|
+
const [abortController, setAbortController] = import_react73.useState(null);
|
|
146710
|
+
const [panelMessages, setPanelMessages] = import_react73.useState([]);
|
|
146711
|
+
const panelTextRef = import_react73.useRef("");
|
|
146712
|
+
const panelSourceRef = import_react73.useRef(null);
|
|
146713
|
+
const [pentestAgents, setPentestAgents] = import_react73.useState({});
|
|
146714
|
+
const pentestTextRefs = import_react73.useRef({});
|
|
146715
|
+
const [assets, setAssets] = import_react73.useState([]);
|
|
146716
|
+
const [viewMode, setViewMode] = import_react73.useState("overview");
|
|
146717
|
+
const [selectedAgentId, setSelectedAgentId] = import_react73.useState(null);
|
|
146718
|
+
const [focusedIndex, setFocusedIndex] = import_react73.useState(0);
|
|
146719
|
+
const [showOrchestratorPanel, setShowOrchestratorPanel] = import_react73.useState(false);
|
|
146720
|
+
const [startTime, setStartTime] = import_react73.useState(null);
|
|
146721
|
+
const pentestAgentList = import_react73.useMemo(() => Object.values(pentestAgents).sort((a, b3) => a.createdAt.getTime() - b3.createdAt.getTime()), [pentestAgents]);
|
|
146722
|
+
const selectedAgent = import_react73.useMemo(() => selectedAgentId ? pentestAgents[selectedAgentId] ?? null : null, [pentestAgents, selectedAgentId]);
|
|
146723
|
+
import_react73.useEffect(() => {
|
|
146350
146724
|
async function load() {
|
|
146351
146725
|
try {
|
|
146352
146726
|
const s = await sessions.get(sessionId);
|
|
@@ -146363,19 +146737,19 @@ function Pentest({ sessionId }) {
|
|
|
146363
146737
|
}
|
|
146364
146738
|
load();
|
|
146365
146739
|
}, [sessionId]);
|
|
146366
|
-
|
|
146740
|
+
import_react73.useEffect(() => {
|
|
146367
146741
|
if (!session)
|
|
146368
146742
|
return;
|
|
146369
146743
|
const assetsPath = join17(session.rootPath, "assets");
|
|
146370
146744
|
function readAssets() {
|
|
146371
|
-
if (!
|
|
146745
|
+
if (!existsSync17(assetsPath))
|
|
146372
146746
|
return;
|
|
146373
146747
|
try {
|
|
146374
146748
|
const files = readdirSync4(assetsPath).filter((f) => f.endsWith(".json"));
|
|
146375
146749
|
const loaded = [];
|
|
146376
146750
|
for (const file2 of files) {
|
|
146377
146751
|
try {
|
|
146378
|
-
const content =
|
|
146752
|
+
const content = readFileSync7(join17(assetsPath, file2), "utf-8");
|
|
146379
146753
|
loaded.push(JSON.parse(content));
|
|
146380
146754
|
} catch {}
|
|
146381
146755
|
}
|
|
@@ -146386,12 +146760,12 @@ function Pentest({ sessionId }) {
|
|
|
146386
146760
|
const interval = setInterval(readAssets, 2000);
|
|
146387
146761
|
return () => clearInterval(interval);
|
|
146388
146762
|
}, [session]);
|
|
146389
|
-
|
|
146763
|
+
import_react73.useEffect(() => {
|
|
146390
146764
|
return () => {
|
|
146391
146765
|
abortController?.abort();
|
|
146392
146766
|
};
|
|
146393
146767
|
}, [abortController]);
|
|
146394
|
-
const ensurePentestAgent =
|
|
146768
|
+
const ensurePentestAgent = import_react73.useCallback((subagentId) => {
|
|
146395
146769
|
setPentestAgents((prev) => {
|
|
146396
146770
|
if (prev[subagentId])
|
|
146397
146771
|
return prev;
|
|
@@ -146408,7 +146782,7 @@ function Pentest({ sessionId }) {
|
|
|
146408
146782
|
};
|
|
146409
146783
|
});
|
|
146410
146784
|
}, []);
|
|
146411
|
-
const handleSubagentSpawn =
|
|
146785
|
+
const handleSubagentSpawn = import_react73.useCallback(({
|
|
146412
146786
|
subagentId,
|
|
146413
146787
|
input
|
|
146414
146788
|
}) => {
|
|
@@ -146428,7 +146802,7 @@ function Pentest({ sessionId }) {
|
|
|
146428
146802
|
}
|
|
146429
146803
|
}));
|
|
146430
146804
|
}, []);
|
|
146431
|
-
const handleSubagentComplete =
|
|
146805
|
+
const handleSubagentComplete = import_react73.useCallback(({ subagentId, status }) => {
|
|
146432
146806
|
if (!subagentId.startsWith("pentest-agent-"))
|
|
146433
146807
|
return;
|
|
146434
146808
|
setPentestAgents((prev) => {
|
|
@@ -146441,7 +146815,7 @@ function Pentest({ sessionId }) {
|
|
|
146441
146815
|
};
|
|
146442
146816
|
});
|
|
146443
146817
|
}, []);
|
|
146444
|
-
const appendPanelText =
|
|
146818
|
+
const appendPanelText = import_react73.useCallback((source, text2) => {
|
|
146445
146819
|
if (panelSourceRef.current !== source) {
|
|
146446
146820
|
panelTextRef.current = "";
|
|
146447
146821
|
panelSourceRef.current = source;
|
|
@@ -146466,7 +146840,7 @@ function Pentest({ sessionId }) {
|
|
|
146466
146840
|
];
|
|
146467
146841
|
});
|
|
146468
146842
|
}, []);
|
|
146469
|
-
const appendPentestText =
|
|
146843
|
+
const appendPentestText = import_react73.useCallback((subagentId, text2) => {
|
|
146470
146844
|
ensurePentestAgent(subagentId);
|
|
146471
146845
|
if (!pentestTextRefs.current[subagentId]) {
|
|
146472
146846
|
pentestTextRefs.current[subagentId] = "";
|
|
@@ -146499,7 +146873,7 @@ function Pentest({ sessionId }) {
|
|
|
146499
146873
|
};
|
|
146500
146874
|
});
|
|
146501
146875
|
}, [ensurePentestAgent]);
|
|
146502
|
-
const addPanelToolCall =
|
|
146876
|
+
const addPanelToolCall = import_react73.useCallback((toolCallId, toolName, args) => {
|
|
146503
146877
|
panelTextRef.current = "";
|
|
146504
146878
|
panelSourceRef.current = null;
|
|
146505
146879
|
const description = typeof args?.toolCallDescription === "string" ? args.toolCallDescription : toolName;
|
|
@@ -146518,7 +146892,7 @@ function Pentest({ sessionId }) {
|
|
|
146518
146892
|
return [...prev, msg];
|
|
146519
146893
|
});
|
|
146520
146894
|
}, []);
|
|
146521
|
-
const addPentestToolCall =
|
|
146895
|
+
const addPentestToolCall = import_react73.useCallback((subagentId, toolCallId, toolName, args) => {
|
|
146522
146896
|
pentestTextRefs.current[subagentId] = "";
|
|
146523
146897
|
ensurePentestAgent(subagentId);
|
|
146524
146898
|
const description = typeof args?.toolCallDescription === "string" ? args.toolCallDescription : toolName;
|
|
@@ -146563,12 +146937,12 @@ function Pentest({ sessionId }) {
|
|
|
146563
146937
|
}
|
|
146564
146938
|
];
|
|
146565
146939
|
};
|
|
146566
|
-
const updatePanelToolResult =
|
|
146940
|
+
const updatePanelToolResult = import_react73.useCallback((toolCallId, toolName, result) => {
|
|
146567
146941
|
panelTextRef.current = "";
|
|
146568
146942
|
panelSourceRef.current = null;
|
|
146569
146943
|
setPanelMessages((prev) => toolResultUpdater(prev, toolCallId, toolName, result));
|
|
146570
146944
|
}, []);
|
|
146571
|
-
const updatePentestToolResult =
|
|
146945
|
+
const updatePentestToolResult = import_react73.useCallback((subagentId, toolCallId, toolName, result) => {
|
|
146572
146946
|
pentestTextRefs.current[subagentId] = "";
|
|
146573
146947
|
setPentestAgents((prev) => {
|
|
146574
146948
|
const agent = prev[subagentId];
|
|
@@ -146583,7 +146957,7 @@ function Pentest({ sessionId }) {
|
|
|
146583
146957
|
};
|
|
146584
146958
|
});
|
|
146585
146959
|
}, []);
|
|
146586
|
-
const startPentest =
|
|
146960
|
+
const startPentest = import_react73.useCallback(async (s) => {
|
|
146587
146961
|
setPhase("discovery");
|
|
146588
146962
|
setStartTime(new Date);
|
|
146589
146963
|
setIsExecuting(true);
|
|
@@ -146679,7 +147053,7 @@ function Pentest({ sessionId }) {
|
|
|
146679
147053
|
handleSubagentSpawn,
|
|
146680
147054
|
handleSubagentComplete
|
|
146681
147055
|
]);
|
|
146682
|
-
|
|
147056
|
+
import_react73.useEffect(() => {
|
|
146683
147057
|
if (session && phase === "loading") {
|
|
146684
147058
|
startPentest(session);
|
|
146685
147059
|
}
|
|
@@ -146741,11 +147115,11 @@ function Pentest({ sessionId }) {
|
|
|
146741
147115
|
}
|
|
146742
147116
|
}
|
|
146743
147117
|
});
|
|
146744
|
-
const openReport =
|
|
147118
|
+
const openReport = import_react73.useCallback(() => {
|
|
146745
147119
|
if (!session)
|
|
146746
147120
|
return;
|
|
146747
147121
|
const reportPath = join17(session.rootPath, "pentest-report.md");
|
|
146748
|
-
if (
|
|
147122
|
+
if (existsSync17(reportPath)) {
|
|
146749
147123
|
exec3(`open "${reportPath}"`);
|
|
146750
147124
|
} else {
|
|
146751
147125
|
exec3(`open "${session.rootPath}"`);
|
|
@@ -146933,7 +147307,7 @@ function OrchestratorPanel({
|
|
|
146933
147307
|
}) {
|
|
146934
147308
|
const { colors: colors2 } = useTheme();
|
|
146935
147309
|
const isRunning = phase !== "loading" && phase !== "completed" && phase !== "error";
|
|
146936
|
-
const assetSummary =
|
|
147310
|
+
const assetSummary = import_react73.useMemo(() => {
|
|
146937
147311
|
const byType = {};
|
|
146938
147312
|
for (const a of assets) {
|
|
146939
147313
|
const key = a.assetType;
|
|
@@ -147182,7 +147556,7 @@ function AgentCardGrid({
|
|
|
147182
147556
|
onSelectAgent
|
|
147183
147557
|
}) {
|
|
147184
147558
|
const { colors: colors2 } = useTheme();
|
|
147185
|
-
const rows =
|
|
147559
|
+
const rows = import_react73.useMemo(() => {
|
|
147186
147560
|
const result = [];
|
|
147187
147561
|
for (let i = 0;i < agents.length; i += 2) {
|
|
147188
147562
|
result.push(agents.slice(i, i + 2));
|
|
@@ -147230,14 +147604,14 @@ function AgentCard({
|
|
|
147230
147604
|
completed: colors2.primary,
|
|
147231
147605
|
failed: colors2.error
|
|
147232
147606
|
}[agent.status];
|
|
147233
|
-
const lastActivity =
|
|
147607
|
+
const lastActivity = import_react73.useMemo(() => {
|
|
147234
147608
|
const last = agent.messages[agent.messages.length - 1];
|
|
147235
147609
|
if (!last)
|
|
147236
147610
|
return "Starting...";
|
|
147237
147611
|
const text2 = typeof last.content === "string" ? last.content.replace(/\n/g, " ").trim() : "Working...";
|
|
147238
147612
|
return text2.length > 50 ? text2.substring(0, 47) + "..." : text2;
|
|
147239
147613
|
}, [agent.messages]);
|
|
147240
|
-
const toolCalls =
|
|
147614
|
+
const toolCalls = import_react73.useMemo(() => agent.messages.filter((m3) => m3.role === "tool").length, [agent.messages]);
|
|
147241
147615
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
147242
147616
|
flexGrow: 1,
|
|
147243
147617
|
flexBasis: 0,
|
|
@@ -147424,8 +147798,8 @@ function MetricsBar({
|
|
|
147424
147798
|
isExecuting
|
|
147425
147799
|
}) {
|
|
147426
147800
|
const { colors: colors2 } = useTheme();
|
|
147427
|
-
const [now2, setNow] =
|
|
147428
|
-
|
|
147801
|
+
const [now2, setNow] = import_react73.useState(Date.now());
|
|
147802
|
+
import_react73.useEffect(() => {
|
|
147429
147803
|
if (!isExecuting)
|
|
147430
147804
|
return;
|
|
147431
147805
|
const interval = setInterval(() => setNow(Date.now()), 1000);
|
|
@@ -147568,7 +147942,7 @@ function MetricsBar({
|
|
|
147568
147942
|
}
|
|
147569
147943
|
|
|
147570
147944
|
// src/tui/components/operator-dashboard/index.tsx
|
|
147571
|
-
var
|
|
147945
|
+
var import_react78 = __toESM(require_react(), 1);
|
|
147572
147946
|
|
|
147573
147947
|
// src/core/api/offesecAgent.ts
|
|
147574
147948
|
init_offensiveSecurityAgent();
|
|
@@ -147665,7 +148039,7 @@ function InlineApprovalPrompt2({ approval }) {
|
|
|
147665
148039
|
}
|
|
147666
148040
|
|
|
147667
148041
|
// src/tui/components/chat/loading-indicator.tsx
|
|
147668
|
-
var
|
|
148042
|
+
var import_react75 = __toESM(require_react(), 1);
|
|
147669
148043
|
var SPINNER_FRAMES2 = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
147670
148044
|
var SPINNER_INTERVAL2 = 80;
|
|
147671
148045
|
var DOTS_FRAMES = ["", ".", "..", "..."];
|
|
@@ -147676,15 +148050,15 @@ function LoadingIndicator({
|
|
|
147676
148050
|
toolName
|
|
147677
148051
|
}) {
|
|
147678
148052
|
const { colors: colors2 } = useTheme();
|
|
147679
|
-
const [spinnerFrame, setSpinnerFrame] =
|
|
147680
|
-
const [dotsFrame, setDotsFrame] =
|
|
147681
|
-
|
|
148053
|
+
const [spinnerFrame, setSpinnerFrame] = import_react75.useState(0);
|
|
148054
|
+
const [dotsFrame, setDotsFrame] = import_react75.useState(0);
|
|
148055
|
+
import_react75.useEffect(() => {
|
|
147682
148056
|
const interval = setInterval(() => {
|
|
147683
148057
|
setSpinnerFrame((f) => (f + 1) % SPINNER_FRAMES2.length);
|
|
147684
148058
|
}, SPINNER_INTERVAL2);
|
|
147685
148059
|
return () => clearInterval(interval);
|
|
147686
148060
|
}, []);
|
|
147687
|
-
|
|
148061
|
+
import_react75.useEffect(() => {
|
|
147688
148062
|
const interval = setInterval(() => {
|
|
147689
148063
|
setDotsFrame((f) => (f + 1) % DOTS_FRAMES.length);
|
|
147690
148064
|
}, DOTS_INTERVAL);
|
|
@@ -147954,7 +148328,7 @@ function MessageList({
|
|
|
147954
148328
|
}
|
|
147955
148329
|
|
|
147956
148330
|
// src/tui/components/chat/input-area.tsx
|
|
147957
|
-
var
|
|
148331
|
+
var import_react76 = __toESM(require_react(), 1);
|
|
147958
148332
|
function NormalInputAreaInner({
|
|
147959
148333
|
value,
|
|
147960
148334
|
onChange,
|
|
@@ -147969,17 +148343,17 @@ function NormalInputAreaInner({
|
|
|
147969
148343
|
}) {
|
|
147970
148344
|
const { colors: colors2 } = useTheme();
|
|
147971
148345
|
const { inputValue, setInputValue } = useInput();
|
|
147972
|
-
const promptRef =
|
|
147973
|
-
const isExternalUpdate =
|
|
148346
|
+
const promptRef = import_react76.useRef(null);
|
|
148347
|
+
const isExternalUpdate = import_react76.useRef(false);
|
|
147974
148348
|
const isDisabled = status === "running";
|
|
147975
|
-
|
|
148349
|
+
import_react76.useEffect(() => {
|
|
147976
148350
|
if (value !== inputValue) {
|
|
147977
148351
|
isExternalUpdate.current = true;
|
|
147978
148352
|
setInputValue(value);
|
|
147979
148353
|
promptRef.current?.setValue(value);
|
|
147980
148354
|
}
|
|
147981
148355
|
}, [value]);
|
|
147982
|
-
|
|
148356
|
+
import_react76.useEffect(() => {
|
|
147983
148357
|
if (isExternalUpdate.current) {
|
|
147984
148358
|
isExternalUpdate.current = false;
|
|
147985
148359
|
return;
|
|
@@ -148129,7 +148503,7 @@ function ApprovalInputArea2({
|
|
|
148129
148503
|
lastDeclineNote
|
|
148130
148504
|
}) {
|
|
148131
148505
|
const { colors: colors2 } = useTheme();
|
|
148132
|
-
const [focusedElement, setFocusedElement] =
|
|
148506
|
+
const [focusedElement, setFocusedElement] = import_react76.useState(0);
|
|
148133
148507
|
const tierColor = getTierColor(colors2, approval.tier);
|
|
148134
148508
|
useKeyboard((key) => {
|
|
148135
148509
|
if (key.name === "up") {
|
|
@@ -148251,20 +148625,20 @@ function OperatorDashboard({
|
|
|
148251
148625
|
const route = useRoute();
|
|
148252
148626
|
const config4 = useConfig();
|
|
148253
148627
|
const { model, setThinking, setIsExecuting } = useAgent();
|
|
148254
|
-
const [session, setSession] =
|
|
148255
|
-
const [loading, setLoading] =
|
|
148256
|
-
const [error41, setError] =
|
|
148257
|
-
const [status, setStatus] =
|
|
148258
|
-
const abortControllerRef =
|
|
148259
|
-
const [messages, setMessages] =
|
|
148260
|
-
const textRef =
|
|
148261
|
-
const [inputValue, setInputValue] =
|
|
148262
|
-
const [operatorState, setOperatorState] =
|
|
148263
|
-
const [pendingApprovals] =
|
|
148264
|
-
const [lastApprovedAction] =
|
|
148265
|
-
const [verboseMode, setVerboseMode] =
|
|
148266
|
-
const [expandedLogs, setExpandedLogs] =
|
|
148267
|
-
|
|
148628
|
+
const [session, setSession] = import_react78.useState(null);
|
|
148629
|
+
const [loading, setLoading] = import_react78.useState(true);
|
|
148630
|
+
const [error41, setError] = import_react78.useState(null);
|
|
148631
|
+
const [status, setStatus] = import_react78.useState("idle");
|
|
148632
|
+
const abortControllerRef = import_react78.useRef(null);
|
|
148633
|
+
const [messages, setMessages] = import_react78.useState([]);
|
|
148634
|
+
const textRef = import_react78.useRef("");
|
|
148635
|
+
const [inputValue, setInputValue] = import_react78.useState("");
|
|
148636
|
+
const [operatorState, setOperatorState] = import_react78.useState(() => createInitialOperatorState("manual", 2));
|
|
148637
|
+
const [pendingApprovals] = import_react78.useState([]);
|
|
148638
|
+
const [lastApprovedAction] = import_react78.useState(null);
|
|
148639
|
+
const [verboseMode, setVerboseMode] = import_react78.useState(false);
|
|
148640
|
+
const [expandedLogs, setExpandedLogs] = import_react78.useState(false);
|
|
148641
|
+
import_react78.useEffect(() => {
|
|
148268
148642
|
async function loadSession() {
|
|
148269
148643
|
try {
|
|
148270
148644
|
const s = await sessions.get(sessionId);
|
|
@@ -148296,7 +148670,7 @@ function OperatorDashboard({
|
|
|
148296
148670
|
}
|
|
148297
148671
|
loadSession();
|
|
148298
148672
|
}, [sessionId, isResume]);
|
|
148299
|
-
const appendText =
|
|
148673
|
+
const appendText = import_react78.useCallback((text2) => {
|
|
148300
148674
|
textRef.current += text2;
|
|
148301
148675
|
const accumulated = textRef.current;
|
|
148302
148676
|
setMessages((prev) => {
|
|
@@ -148312,7 +148686,7 @@ function OperatorDashboard({
|
|
|
148312
148686
|
];
|
|
148313
148687
|
});
|
|
148314
148688
|
}, []);
|
|
148315
|
-
const addToolCall =
|
|
148689
|
+
const addToolCall = import_react78.useCallback((toolCallId, toolName, args) => {
|
|
148316
148690
|
textRef.current = "";
|
|
148317
148691
|
setMessages((prev) => [
|
|
148318
148692
|
...prev,
|
|
@@ -148327,7 +148701,7 @@ function OperatorDashboard({
|
|
|
148327
148701
|
}
|
|
148328
148702
|
]);
|
|
148329
148703
|
}, []);
|
|
148330
|
-
const updateToolResult =
|
|
148704
|
+
const updateToolResult = import_react78.useCallback((toolCallId, _toolName, result) => {
|
|
148331
148705
|
textRef.current = "";
|
|
148332
148706
|
setMessages((prev) => {
|
|
148333
148707
|
const idx = prev.findIndex((m3) => isToolMessage(m3) && m3.toolCallId === toolCallId);
|
|
@@ -148338,7 +148712,7 @@ function OperatorDashboard({
|
|
|
148338
148712
|
return updated;
|
|
148339
148713
|
});
|
|
148340
148714
|
}, []);
|
|
148341
|
-
const runAgent =
|
|
148715
|
+
const runAgent = import_react78.useCallback(async (prompt) => {
|
|
148342
148716
|
if (!session)
|
|
148343
148717
|
return;
|
|
148344
148718
|
setStatus("running");
|
|
@@ -148417,13 +148791,13 @@ function OperatorDashboard({
|
|
|
148417
148791
|
setThinking,
|
|
148418
148792
|
setIsExecuting
|
|
148419
148793
|
]);
|
|
148420
|
-
const handleSubmit =
|
|
148794
|
+
const handleSubmit = import_react78.useCallback((value) => {
|
|
148421
148795
|
if (!value.trim() || status === "running")
|
|
148422
148796
|
return;
|
|
148423
148797
|
setInputValue("");
|
|
148424
148798
|
runAgent(value.trim());
|
|
148425
148799
|
}, [status, runAgent]);
|
|
148426
|
-
const handleAbort =
|
|
148800
|
+
const handleAbort = import_react78.useCallback(() => {
|
|
148427
148801
|
if (abortControllerRef.current) {
|
|
148428
148802
|
abortControllerRef.current.abort();
|
|
148429
148803
|
abortControllerRef.current = null;
|
|
@@ -148634,7 +149008,7 @@ Session paths:
|
|
|
148634
149008
|
}
|
|
148635
149009
|
|
|
148636
149010
|
// src/tui/components/commands/theme-picker.tsx
|
|
148637
|
-
var
|
|
149011
|
+
var import_react80 = __toESM(require_react(), 1);
|
|
148638
149012
|
function ThemePicker() {
|
|
148639
149013
|
const dimensions = useTerminalDimensions();
|
|
148640
149014
|
const route = useRoute();
|
|
@@ -148647,15 +149021,15 @@ function ThemePicker() {
|
|
|
148647
149021
|
toggleMode,
|
|
148648
149022
|
setMode
|
|
148649
149023
|
} = useTheme();
|
|
148650
|
-
const [selectedIndex, setSelectedIndex] =
|
|
148651
|
-
const originalThemeRef =
|
|
148652
|
-
const originalModeRef =
|
|
148653
|
-
const handleClose =
|
|
149024
|
+
const [selectedIndex, setSelectedIndex] = import_react80.useState(() => Math.max(0, availableThemes.indexOf(theme.name)));
|
|
149025
|
+
const originalThemeRef = import_react80.useRef(theme.name);
|
|
149026
|
+
const originalModeRef = import_react80.useRef(mode);
|
|
149027
|
+
const handleClose = import_react80.useCallback(() => {
|
|
148654
149028
|
setTheme(originalThemeRef.current);
|
|
148655
149029
|
setMode(originalModeRef.current);
|
|
148656
149030
|
route.navigate({ type: "base", path: "home" });
|
|
148657
149031
|
}, [setTheme, setMode, route]);
|
|
148658
|
-
const handleConfirm =
|
|
149032
|
+
const handleConfirm = import_react80.useCallback(async () => {
|
|
148659
149033
|
const currentThemeName = availableThemes[selectedIndex];
|
|
148660
149034
|
if (currentThemeName) {
|
|
148661
149035
|
await config.update({ theme: currentThemeName });
|
|
@@ -151182,52 +151556,47 @@ async function detectTerminalMode(timeoutMs = 1000) {
|
|
|
151182
151556
|
}
|
|
151183
151557
|
|
|
151184
151558
|
// src/tui/index.tsx
|
|
151185
|
-
function App(
|
|
151186
|
-
const
|
|
151187
|
-
const [
|
|
151188
|
-
const [
|
|
151189
|
-
const [
|
|
151190
|
-
const [
|
|
151191
|
-
const [
|
|
151192
|
-
const [
|
|
151193
|
-
const [showShortcutsDialog, setShowShortcutsDialog] = import_react80.useState(false);
|
|
151559
|
+
function App({ appConfig }) {
|
|
151560
|
+
const [focusIndex, setFocusIndex] = import_react83.useState(0);
|
|
151561
|
+
const [cwd, setCwd] = import_react83.useState(process.cwd());
|
|
151562
|
+
const [ctrlCPressTime, setCtrlCPressTime] = import_react83.useState(null);
|
|
151563
|
+
const [showExitWarning, setShowExitWarning] = import_react83.useState(false);
|
|
151564
|
+
const [inputKey, setInputKey] = import_react83.useState(0);
|
|
151565
|
+
const [showSessionsDialog, setShowSessionsDialog] = import_react83.useState(false);
|
|
151566
|
+
const [showShortcutsDialog, setShowShortcutsDialog] = import_react83.useState(false);
|
|
151194
151567
|
const navigableItems = ["command-input"];
|
|
151195
|
-
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(
|
|
151196
|
-
|
|
151197
|
-
|
|
151198
|
-
|
|
151199
|
-
|
|
151200
|
-
|
|
151201
|
-
|
|
151202
|
-
|
|
151203
|
-
|
|
151204
|
-
|
|
151205
|
-
|
|
151206
|
-
|
|
151207
|
-
|
|
151208
|
-
|
|
151209
|
-
|
|
151210
|
-
|
|
151211
|
-
|
|
151212
|
-
|
|
151213
|
-
|
|
151214
|
-
|
|
151215
|
-
|
|
151216
|
-
|
|
151217
|
-
|
|
151218
|
-
|
|
151219
|
-
|
|
151220
|
-
|
|
151221
|
-
|
|
151222
|
-
|
|
151223
|
-
|
|
151224
|
-
|
|
151225
|
-
|
|
151226
|
-
|
|
151227
|
-
setShowExitWarning,
|
|
151228
|
-
inputKey,
|
|
151229
|
-
setInputKey
|
|
151230
|
-
}, undefined, false, undefined, this)
|
|
151568
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ConfigProvider, {
|
|
151569
|
+
config: appConfig,
|
|
151570
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(SessionProvider, {
|
|
151571
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(RouteProvider, {
|
|
151572
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(FocusProvider, {
|
|
151573
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(InputProvider, {
|
|
151574
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(DialogProvider, {
|
|
151575
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(AgentProvider, {
|
|
151576
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(CommandProvider, {
|
|
151577
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(KeybindingProvider, {
|
|
151578
|
+
deps: {
|
|
151579
|
+
ctrlCPressTime,
|
|
151580
|
+
setCtrlCPressTime,
|
|
151581
|
+
setShowExitWarning,
|
|
151582
|
+
setInputKey,
|
|
151583
|
+
setShowSessionsDialog,
|
|
151584
|
+
setShowShortcutsDialog,
|
|
151585
|
+
setFocusIndex,
|
|
151586
|
+
navigableItems
|
|
151587
|
+
},
|
|
151588
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(AppContent, {
|
|
151589
|
+
focusIndex,
|
|
151590
|
+
showSessionsDialog,
|
|
151591
|
+
setShowSessionsDialog,
|
|
151592
|
+
showShortcutsDialog,
|
|
151593
|
+
setShowShortcutsDialog,
|
|
151594
|
+
cwd,
|
|
151595
|
+
setCtrlCPressTime,
|
|
151596
|
+
showExitWarning,
|
|
151597
|
+
setShowExitWarning,
|
|
151598
|
+
inputKey,
|
|
151599
|
+
setInputKey
|
|
151231
151600
|
}, undefined, false, undefined, this)
|
|
151232
151601
|
}, undefined, false, undefined, this)
|
|
151233
151602
|
}, undefined, false, undefined, this)
|
|
@@ -151257,7 +151626,7 @@ function AppContent({
|
|
|
151257
151626
|
const { colors: colors2 } = useTheme();
|
|
151258
151627
|
const { refocusPrompt } = useFocus();
|
|
151259
151628
|
const { setExternalDialogOpen } = useDialog();
|
|
151260
|
-
|
|
151629
|
+
import_react83.useEffect(() => {
|
|
151261
151630
|
if (route.data.type !== "base")
|
|
151262
151631
|
return;
|
|
151263
151632
|
if (!config4.data.responsibleUseAccepted && route.data.path !== "disclosure") {
|
|
@@ -151266,7 +151635,7 @@ function AppContent({
|
|
|
151266
151635
|
route.navigate({ type: "base", path: "providers" });
|
|
151267
151636
|
}
|
|
151268
151637
|
}, [config4.data.responsibleUseAccepted, route.data]);
|
|
151269
|
-
|
|
151638
|
+
import_react83.useEffect(() => {
|
|
151270
151639
|
if (showExitWarning) {
|
|
151271
151640
|
const timer = setTimeout(() => {
|
|
151272
151641
|
setShowExitWarning(false);
|
|
@@ -151449,17 +151818,28 @@ async function main2() {
|
|
|
151449
151818
|
process.on("uncaughtException", (err) => {
|
|
151450
151819
|
renderer.destroy();
|
|
151451
151820
|
console.error("Uncaught exception:", err);
|
|
151821
|
+
writeErrorLog(err, "UNCAUGHT");
|
|
151452
151822
|
process.exit(1);
|
|
151453
151823
|
});
|
|
151454
151824
|
process.on("unhandledRejection", (reason) => {
|
|
151455
151825
|
renderer.destroy();
|
|
151456
151826
|
console.error("Unhandled rejection:", reason);
|
|
151827
|
+
writeErrorLog(reason, "UNHANDLED_REJECTION");
|
|
151457
151828
|
process.exit(1);
|
|
151458
151829
|
});
|
|
151459
|
-
createRoot(renderer).render(/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(
|
|
151460
|
-
appConfig,
|
|
151830
|
+
createRoot(renderer).render(/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ThemeProvider, {
|
|
151461
151831
|
initialTheme: themeName,
|
|
151462
|
-
initialMode: mode
|
|
151832
|
+
initialMode: mode,
|
|
151833
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ToastProvider, {
|
|
151834
|
+
children: [
|
|
151835
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ErrorBoundary2, {
|
|
151836
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(App, {
|
|
151837
|
+
appConfig
|
|
151838
|
+
}, undefined, false, undefined, this)
|
|
151839
|
+
}, undefined, false, undefined, this),
|
|
151840
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ToastContainer, {}, undefined, false, undefined, this)
|
|
151841
|
+
]
|
|
151842
|
+
}, undefined, true, undefined, this)
|
|
151463
151843
|
}, undefined, false, undefined, this));
|
|
151464
151844
|
}
|
|
151465
151845
|
main2();
|