@pensar/apex 0.0.91 → 0.0.92-canary.1e2cfc8f
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 +594 -524
- package/package.json +1 -1
package/build/index.js
CHANGED
|
@@ -31971,7 +31971,7 @@ var package_default2;
|
|
|
31971
31971
|
var init_package = __esm(() => {
|
|
31972
31972
|
package_default2 = {
|
|
31973
31973
|
name: "@pensar/apex",
|
|
31974
|
-
version: "0.0.
|
|
31974
|
+
version: "0.0.92-canary.1e2cfc8f",
|
|
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",
|
|
@@ -32165,7 +32165,6 @@ async function get() {
|
|
|
32165
32165
|
inceptionAPIKey: process.env.INCEPTION_API_KEY ?? parsedConfig.inceptionAPIKey,
|
|
32166
32166
|
bedrockAPIKey: process.env.BEDROCK_API_KEY ?? parsedConfig.bedrockAPIKey,
|
|
32167
32167
|
pensarAPIKey: process.env.PENSAR_API_KEY ?? parsedConfig.pensarAPIKey,
|
|
32168
|
-
pensarApiUrl: process.env.PENSAR_API_URL ?? parsedConfig.pensarApiUrl,
|
|
32169
32168
|
daytonaAPIKey: process.env.DAYTONA_API_KEY ?? parsedConfig.daytonaAPIKey,
|
|
32170
32169
|
daytonaOrgId: process.env.DAYTONA_ORG_ID ?? parsedConfig.daytonaOrgId,
|
|
32171
32170
|
runloopAPIKey: process.env.RUNLOOP_API_KEY ?? parsedConfig.runloopAPIKey
|
|
@@ -88130,13 +88129,13 @@ __export(exports_constants, {
|
|
|
88130
88129
|
PENSAR_CONSOLE_BASE_URL: () => PENSAR_CONSOLE_BASE_URL,
|
|
88131
88130
|
PENSAR_API_BASE_URL: () => PENSAR_API_BASE_URL
|
|
88132
88131
|
});
|
|
88133
|
-
function getPensarApiUrl(
|
|
88134
|
-
return
|
|
88132
|
+
function getPensarApiUrl() {
|
|
88133
|
+
return PENSAR_API_BASE_URL;
|
|
88135
88134
|
}
|
|
88136
88135
|
function getPensarConsoleUrl() {
|
|
88137
88136
|
return process.env.PENSAR_CONSOLE_URL || PENSAR_CONSOLE_BASE_URL;
|
|
88138
88137
|
}
|
|
88139
|
-
var PENSAR_API_BASE_URL = "https://api.
|
|
88138
|
+
var PENSAR_API_BASE_URL = "https://api.pensar.dev", PENSAR_CONSOLE_BASE_URL = "https://console.pensar.dev";
|
|
88140
88139
|
|
|
88141
88140
|
// src/core/config/index.ts
|
|
88142
88141
|
var config2;
|
|
@@ -88200,7 +88199,7 @@ async function ensureValidToken(cfg) {
|
|
|
88200
88199
|
return { token: cfg.accessToken, type: "workos" };
|
|
88201
88200
|
}
|
|
88202
88201
|
if (cfg.refreshToken) {
|
|
88203
|
-
const clientId = await fetchWorkOSClientId(
|
|
88202
|
+
const clientId = await fetchWorkOSClientId();
|
|
88204
88203
|
if (clientId) {
|
|
88205
88204
|
const newToken = await refreshAccessToken(clientId, cfg.refreshToken);
|
|
88206
88205
|
if (newToken) {
|
|
@@ -88214,12 +88213,12 @@ async function ensureValidToken(cfg) {
|
|
|
88214
88213
|
}
|
|
88215
88214
|
return null;
|
|
88216
88215
|
}
|
|
88217
|
-
async function fetchWorkOSClientId(
|
|
88216
|
+
async function fetchWorkOSClientId() {
|
|
88218
88217
|
if (cachedClientId)
|
|
88219
88218
|
return cachedClientId;
|
|
88220
88219
|
try {
|
|
88221
88220
|
const { getPensarApiUrl: getPensarApiUrl2 } = await Promise.resolve().then(() => exports_constants);
|
|
88222
|
-
const apiUrl = getPensarApiUrl2(
|
|
88221
|
+
const apiUrl = getPensarApiUrl2();
|
|
88223
88222
|
const response = await fetch(`${apiUrl}/api/cli/config`);
|
|
88224
88223
|
if (!response.ok)
|
|
88225
88224
|
return null;
|
|
@@ -88244,7 +88243,6 @@ function buildAuthConfig(cfg) {
|
|
|
88244
88243
|
openRouterAPIKey: cfg.openRouterAPIKey ?? undefined,
|
|
88245
88244
|
inceptionAPIKey: cfg.inceptionAPIKey ?? undefined,
|
|
88246
88245
|
pensarAPIKey: cfg.pensarAPIKey ?? undefined,
|
|
88247
|
-
pensarApiUrl: cfg.pensarApiUrl ?? undefined,
|
|
88248
88246
|
accessToken: cfg.accessToken ?? undefined,
|
|
88249
88247
|
refreshToken: cfg.refreshToken ?? undefined,
|
|
88250
88248
|
workspaceId: cfg.workspaceId ?? undefined,
|
|
@@ -88320,7 +88318,7 @@ function getProviderModel(model, authConfig) {
|
|
|
88320
88318
|
if (!pensarApiKey && !hasWorkOSAuth) {
|
|
88321
88319
|
throw new Error("Pensar not configured. Run /auth to connect to Pensar Console.");
|
|
88322
88320
|
}
|
|
88323
|
-
const pensarApiUrl =
|
|
88321
|
+
const pensarApiUrl = getPensarApiUrl();
|
|
88324
88322
|
const bedrockModelId = model.startsWith("pensar:") ? model.slice(7) : model;
|
|
88325
88323
|
if (process.env.PENSAR_DEBUG === "1" || process.env.PENSAR_DEBUG === "true") {
|
|
88326
88324
|
console.log(`[pensar] getProviderModel: ${model} → bedrock:${bedrockModelId} via ${pensarApiUrl}`);
|
|
@@ -88336,8 +88334,7 @@ function getProviderModel(model, authConfig) {
|
|
|
88336
88334
|
return ensureValidToken({
|
|
88337
88335
|
accessToken: freshConfig.accessToken,
|
|
88338
88336
|
refreshToken: freshConfig.refreshToken,
|
|
88339
|
-
pensarAPIKey: freshConfig.pensarAPIKey
|
|
88340
|
-
pensarApiUrl: freshConfig.pensarApiUrl
|
|
88337
|
+
pensarAPIKey: freshConfig.pensarAPIKey
|
|
88341
88338
|
});
|
|
88342
88339
|
};
|
|
88343
88340
|
}
|
|
@@ -89526,44 +89523,22 @@ import {
|
|
|
89526
89523
|
readdirSync as readdirSync2
|
|
89527
89524
|
} from "fs";
|
|
89528
89525
|
import { join as join4 } from "path";
|
|
89529
|
-
function
|
|
89530
|
-
const
|
|
89531
|
-
if (
|
|
89532
|
-
return
|
|
89533
|
-
|
|
89534
|
-
|
|
89535
|
-
|
|
89536
|
-
|
|
89537
|
-
|
|
89538
|
-
type: "tool-call",
|
|
89539
|
-
toolCallId: part.toolCallId,
|
|
89540
|
-
toolName: part.toolName,
|
|
89541
|
-
input: part.args ?? part.input
|
|
89542
|
-
};
|
|
89543
|
-
}
|
|
89544
|
-
if (part.type === "tool-result") {
|
|
89545
|
-
return {
|
|
89546
|
-
type: "tool-result",
|
|
89547
|
-
toolCallId: part.toolCallId,
|
|
89548
|
-
toolName: part.toolName,
|
|
89549
|
-
output: part.result ?? part.output
|
|
89550
|
-
};
|
|
89551
|
-
}
|
|
89552
|
-
return {
|
|
89553
|
-
type: "text",
|
|
89554
|
-
text: part.text ?? ""
|
|
89555
|
-
};
|
|
89556
|
-
});
|
|
89557
|
-
return { role: m2.role, content: mapped };
|
|
89526
|
+
function loadSubagentMessages(session, agentName) {
|
|
89527
|
+
const filePath = join4(session.rootPath, SUBAGENTS_DIR, `${agentName}.json`);
|
|
89528
|
+
if (!existsSync8(filePath))
|
|
89529
|
+
return [];
|
|
89530
|
+
try {
|
|
89531
|
+
const data = JSON.parse(readFileSync3(filePath, "utf-8"));
|
|
89532
|
+
return data.messages;
|
|
89533
|
+
} catch {
|
|
89534
|
+
return [];
|
|
89558
89535
|
}
|
|
89559
|
-
return { role: m2.role, content: String(m2.content) };
|
|
89560
89536
|
}
|
|
89561
89537
|
function saveSubagentData(session, data) {
|
|
89562
89538
|
const subagentsDir = join4(session.rootPath, SUBAGENTS_DIR);
|
|
89563
89539
|
mkdirSync2(subagentsDir, { recursive: true });
|
|
89564
89540
|
let toolCallCount = 0;
|
|
89565
89541
|
let stepCount = 0;
|
|
89566
|
-
const savedMessages = [];
|
|
89567
89542
|
for (const msg of data.messages) {
|
|
89568
89543
|
if (msg.role === "assistant") {
|
|
89569
89544
|
stepCount++;
|
|
@@ -89574,12 +89549,10 @@ function saveSubagentData(session, data) {
|
|
|
89574
89549
|
}
|
|
89575
89550
|
}
|
|
89576
89551
|
}
|
|
89577
|
-
savedMessages.push(mapToSavedMessage(msg));
|
|
89578
89552
|
}
|
|
89579
|
-
const now2 = new Date;
|
|
89580
89553
|
const savedData = {
|
|
89581
89554
|
agentName: data.agentName,
|
|
89582
|
-
timestamp:
|
|
89555
|
+
timestamp: new Date().toISOString(),
|
|
89583
89556
|
target: data.target,
|
|
89584
89557
|
objective: data.objective,
|
|
89585
89558
|
vulnerabilityClass: data.vulnerabilityClass,
|
|
@@ -89588,16 +89561,24 @@ function saveSubagentData(session, data) {
|
|
|
89588
89561
|
findingsCount: data.findingsCount ?? 0,
|
|
89589
89562
|
status: data.status,
|
|
89590
89563
|
error: data.error,
|
|
89591
|
-
messages:
|
|
89564
|
+
messages: data.messages
|
|
89592
89565
|
};
|
|
89593
|
-
|
|
89594
|
-
const filename = `${data.agentName}-${ts}.json`;
|
|
89595
|
-
writeFileSync2(join4(subagentsDir, filename), JSON.stringify(savedData, null, 2));
|
|
89566
|
+
writeFileSync2(join4(subagentsDir, `${data.agentName}.json`), JSON.stringify(savedData, null, 2));
|
|
89596
89567
|
}
|
|
89597
89568
|
function writeAgentManifest(session, entries2) {
|
|
89598
89569
|
const manifestPath = join4(session.rootPath, MANIFEST_FILE);
|
|
89599
89570
|
writeFileSync2(manifestPath, JSON.stringify(entries2, null, 2));
|
|
89600
89571
|
}
|
|
89572
|
+
function readAgentManifest(session) {
|
|
89573
|
+
const manifestPath = join4(session.rootPath, MANIFEST_FILE);
|
|
89574
|
+
if (!existsSync8(manifestPath))
|
|
89575
|
+
return [];
|
|
89576
|
+
try {
|
|
89577
|
+
return JSON.parse(readFileSync3(manifestPath, "utf-8"));
|
|
89578
|
+
} catch {
|
|
89579
|
+
return [];
|
|
89580
|
+
}
|
|
89581
|
+
}
|
|
89601
89582
|
function buildManifestEntries(targets) {
|
|
89602
89583
|
return targets.map((t2, i) => ({
|
|
89603
89584
|
id: `pentest-agent-${i + 1}`,
|
|
@@ -89610,18 +89591,31 @@ function buildManifestEntries(targets) {
|
|
|
89610
89591
|
}));
|
|
89611
89592
|
}
|
|
89612
89593
|
function finalizeManifest(session, entries2, results) {
|
|
89613
|
-
const finalManifest = entries2.map((entry, i) =>
|
|
89614
|
-
|
|
89615
|
-
|
|
89616
|
-
|
|
89617
|
-
|
|
89594
|
+
const finalManifest = entries2.map((entry, i) => {
|
|
89595
|
+
if (entry.status === "completed")
|
|
89596
|
+
return entry;
|
|
89597
|
+
return {
|
|
89598
|
+
...entry,
|
|
89599
|
+
status: results[i] != null ? "completed" : "failed",
|
|
89600
|
+
completedAt: new Date().toISOString()
|
|
89601
|
+
};
|
|
89602
|
+
});
|
|
89618
89603
|
writeAgentManifest(session, finalManifest);
|
|
89619
89604
|
}
|
|
89605
|
+
function updateManifestEntryStatus(session, agentId, status) {
|
|
89606
|
+
const manifest = readAgentManifest(session);
|
|
89607
|
+
const updated = manifest.map((e) => e.id === agentId ? { ...e, status, completedAt: new Date().toISOString() } : e);
|
|
89608
|
+
writeAgentManifest(session, updated);
|
|
89609
|
+
}
|
|
89610
|
+
function getCompletedAgentIds(session) {
|
|
89611
|
+
const manifest = readAgentManifest(session);
|
|
89612
|
+
return new Set(manifest.filter((e) => e.id.startsWith("pentest-agent-") && e.status === "completed").map((e) => e.id));
|
|
89613
|
+
}
|
|
89620
89614
|
function parseSubagentFilename(filename) {
|
|
89621
89615
|
if (filename.startsWith("attack-surface-agent")) {
|
|
89622
89616
|
return { agentType: "attack-surface", name: "Attack Surface Discovery" };
|
|
89623
89617
|
}
|
|
89624
|
-
const pentestMatch = filename.match(/^pentest-agent-(\d+)
|
|
89618
|
+
const pentestMatch = filename.match(/^pentest-agent-(\d+)/);
|
|
89625
89619
|
if (pentestMatch) {
|
|
89626
89620
|
return {
|
|
89627
89621
|
agentType: "pentest",
|
|
@@ -89673,7 +89667,8 @@ function convertMessagesToUI(messages, baseTime) {
|
|
|
89673
89667
|
createdAt
|
|
89674
89668
|
});
|
|
89675
89669
|
} else if (part.type === "tool-call") {
|
|
89676
|
-
const
|
|
89670
|
+
const input = part.input;
|
|
89671
|
+
const toolDescription = typeof input?.toolCallDescription === "string" ? input.toolCallDescription : part.toolName || "tool";
|
|
89677
89672
|
const result = part.toolCallId ? toolResults.get(part.toolCallId) : undefined;
|
|
89678
89673
|
uiMessages.push({
|
|
89679
89674
|
role: "tool",
|
|
@@ -89681,7 +89676,7 @@ function convertMessagesToUI(messages, baseTime) {
|
|
|
89681
89676
|
createdAt,
|
|
89682
89677
|
toolCallId: part.toolCallId,
|
|
89683
89678
|
toolName: part.toolName,
|
|
89684
|
-
args:
|
|
89679
|
+
args: input,
|
|
89685
89680
|
result,
|
|
89686
89681
|
status: "completed"
|
|
89687
89682
|
});
|
|
@@ -89692,8 +89687,7 @@ function convertMessagesToUI(messages, baseTime) {
|
|
|
89692
89687
|
return uiMessages;
|
|
89693
89688
|
}
|
|
89694
89689
|
function convertModelMessagesToUI(messages) {
|
|
89695
|
-
|
|
89696
|
-
return convertMessagesToUI(saved, new Date);
|
|
89690
|
+
return convertMessagesToUI(messages, new Date);
|
|
89697
89691
|
}
|
|
89698
89692
|
function loadSubagents(rootPath) {
|
|
89699
89693
|
const subagentsPath = join4(rootPath, SUBAGENTS_DIR);
|
|
@@ -89701,11 +89695,7 @@ function loadSubagents(rootPath) {
|
|
|
89701
89695
|
const agentNameIndex = new Map;
|
|
89702
89696
|
if (existsSync8(subagentsPath)) {
|
|
89703
89697
|
const files = readdirSync2(subagentsPath).filter((f) => f.endsWith(".json"));
|
|
89704
|
-
files.sort(
|
|
89705
|
-
const timeA = a.match(/\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}/)?.[0] || "";
|
|
89706
|
-
const timeB = b2.match(/\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}/)?.[0] || "";
|
|
89707
|
-
return timeA.localeCompare(timeB);
|
|
89708
|
-
});
|
|
89698
|
+
files.sort();
|
|
89709
89699
|
for (const file2 of files) {
|
|
89710
89700
|
if (file2.startsWith("orchestrator-"))
|
|
89711
89701
|
continue;
|
|
@@ -89729,9 +89719,9 @@ function loadSubagents(rootPath) {
|
|
|
89729
89719
|
}
|
|
89730
89720
|
break;
|
|
89731
89721
|
}
|
|
89732
|
-
|
|
89722
|
+
agentNameIndex.set(data.agentName, subagents.length);
|
|
89733
89723
|
subagents.push({
|
|
89734
|
-
id:
|
|
89724
|
+
id: data.agentName,
|
|
89735
89725
|
name: data.agentName === "attack-surface-agent" ? "Attack Surface Discovery" : name26,
|
|
89736
89726
|
type: agentType,
|
|
89737
89727
|
target: data.target || "Unknown",
|
|
@@ -89739,7 +89729,6 @@ function loadSubagents(rootPath) {
|
|
|
89739
89729
|
createdAt: timestamp,
|
|
89740
89730
|
status
|
|
89741
89731
|
});
|
|
89742
|
-
agentNameIndex.set(data.agentName, idx);
|
|
89743
89732
|
} catch (e) {
|
|
89744
89733
|
console.error(`Failed to load subagent file ${file2}:`, e);
|
|
89745
89734
|
}
|
|
@@ -89787,6 +89776,116 @@ function loadSubagents(rootPath) {
|
|
|
89787
89776
|
var SUBAGENTS_DIR = "subagents", MANIFEST_FILE = "agent-manifest.json";
|
|
89788
89777
|
var init_persistence = () => {};
|
|
89789
89778
|
|
|
89779
|
+
// src/core/session/loader.ts
|
|
89780
|
+
import { join as join5 } from "path";
|
|
89781
|
+
import { existsSync as existsSync9, readFileSync as readFileSync4 } from "fs";
|
|
89782
|
+
function loadAttackSurfaceResults(rootPath) {
|
|
89783
|
+
const resultsPath = join5(rootPath, "attack-surface-results.json");
|
|
89784
|
+
if (!existsSync9(resultsPath)) {
|
|
89785
|
+
return null;
|
|
89786
|
+
}
|
|
89787
|
+
try {
|
|
89788
|
+
return JSON.parse(readFileSync4(resultsPath, "utf-8"));
|
|
89789
|
+
} catch (e) {
|
|
89790
|
+
console.error("Failed to load attack surface results:", e);
|
|
89791
|
+
return null;
|
|
89792
|
+
}
|
|
89793
|
+
}
|
|
89794
|
+
function hasReport(rootPath) {
|
|
89795
|
+
const reportPath = join5(rootPath, REPORT_FILENAME_MD);
|
|
89796
|
+
return existsSync9(reportPath);
|
|
89797
|
+
}
|
|
89798
|
+
function createDiscoveryFromLogs(rootPath, session) {
|
|
89799
|
+
const logPath = join5(rootPath, "logs", "streamlined-pentest.log");
|
|
89800
|
+
if (!existsSync9(logPath)) {
|
|
89801
|
+
return null;
|
|
89802
|
+
}
|
|
89803
|
+
try {
|
|
89804
|
+
const logContent = readFileSync4(logPath, "utf-8");
|
|
89805
|
+
const lines = logContent.split(`
|
|
89806
|
+
`).filter(Boolean);
|
|
89807
|
+
const messages = [];
|
|
89808
|
+
for (const line of lines) {
|
|
89809
|
+
const match = line.match(/^(\d{4}-\d{2}-\d{2}T[\d:.]+Z) - \[(\w+)\] (.+)$/);
|
|
89810
|
+
if (!match)
|
|
89811
|
+
continue;
|
|
89812
|
+
const [, timestamp, _level, content] = match;
|
|
89813
|
+
const createdAt = new Date(timestamp);
|
|
89814
|
+
if (content.startsWith("[Tool]")) {
|
|
89815
|
+
const toolMatch = content.match(/\[Tool\] (\w+): (.+)/);
|
|
89816
|
+
if (toolMatch) {
|
|
89817
|
+
messages.push({
|
|
89818
|
+
role: "tool",
|
|
89819
|
+
content: `✓ ${toolMatch[2]}`,
|
|
89820
|
+
createdAt,
|
|
89821
|
+
toolName: toolMatch[1],
|
|
89822
|
+
status: "completed"
|
|
89823
|
+
});
|
|
89824
|
+
}
|
|
89825
|
+
} else if (content.startsWith("[Step")) {
|
|
89826
|
+
const stepMatch = content.match(/\[Step \d+\] (.+)/);
|
|
89827
|
+
if (stepMatch) {
|
|
89828
|
+
messages.push({
|
|
89829
|
+
role: "assistant",
|
|
89830
|
+
content: stepMatch[1],
|
|
89831
|
+
createdAt
|
|
89832
|
+
});
|
|
89833
|
+
}
|
|
89834
|
+
}
|
|
89835
|
+
}
|
|
89836
|
+
if (messages.length === 0) {
|
|
89837
|
+
return null;
|
|
89838
|
+
}
|
|
89839
|
+
return {
|
|
89840
|
+
id: "discovery-from-logs",
|
|
89841
|
+
name: "Attack Surface Discovery",
|
|
89842
|
+
type: "attack-surface",
|
|
89843
|
+
target: session.targets[0] || "Unknown",
|
|
89844
|
+
messages,
|
|
89845
|
+
createdAt: new Date(session.time.created),
|
|
89846
|
+
status: "completed"
|
|
89847
|
+
};
|
|
89848
|
+
} catch (e) {
|
|
89849
|
+
console.error("Failed to parse logs:", e);
|
|
89850
|
+
return null;
|
|
89851
|
+
}
|
|
89852
|
+
}
|
|
89853
|
+
async function loadSessionState(session) {
|
|
89854
|
+
const rootPath = session.rootPath;
|
|
89855
|
+
let subagents = loadSubagents(rootPath);
|
|
89856
|
+
const hasAttackSurfaceAgent = subagents.some((s) => s.type === "attack-surface");
|
|
89857
|
+
if (!hasAttackSurfaceAgent) {
|
|
89858
|
+
const discoveryAgent = createDiscoveryFromLogs(rootPath, session);
|
|
89859
|
+
if (discoveryAgent) {
|
|
89860
|
+
subagents = [discoveryAgent, ...subagents];
|
|
89861
|
+
}
|
|
89862
|
+
}
|
|
89863
|
+
const attackSurfaceResults = loadAttackSurfaceResults(rootPath);
|
|
89864
|
+
const hasReportFile = hasReport(rootPath);
|
|
89865
|
+
const hasDiscoverySubagent = subagents.some((s) => s.type === "attack-surface");
|
|
89866
|
+
const interruptedDuringDiscovery = !attackSurfaceResults && !hasReportFile && hasDiscoverySubagent;
|
|
89867
|
+
if (interruptedDuringDiscovery) {
|
|
89868
|
+
for (let i = 0;i < subagents.length; i++) {
|
|
89869
|
+
if (subagents[i].type === "attack-surface" && subagents[i].status === "completed") {
|
|
89870
|
+
subagents[i] = { ...subagents[i], status: "paused" };
|
|
89871
|
+
}
|
|
89872
|
+
}
|
|
89873
|
+
}
|
|
89874
|
+
const isComplete = hasReportFile;
|
|
89875
|
+
return {
|
|
89876
|
+
session,
|
|
89877
|
+
subagents,
|
|
89878
|
+
attackSurfaceResults,
|
|
89879
|
+
isComplete,
|
|
89880
|
+
hasReport: hasReportFile,
|
|
89881
|
+
interruptedDuringDiscovery
|
|
89882
|
+
};
|
|
89883
|
+
}
|
|
89884
|
+
var init_loader = __esm(() => {
|
|
89885
|
+
init_persistence();
|
|
89886
|
+
init_report();
|
|
89887
|
+
});
|
|
89888
|
+
|
|
89790
89889
|
// src/core/agents/specialized/attackSurface/prompts.ts
|
|
89791
89890
|
var SYSTEM = `You are an autonomous attack surface analysis agent. Your mission is to comprehensively map the attack surface of a target and produce a structured report of all discovered assets and pentest objectives.
|
|
89792
89891
|
|
|
@@ -105652,9 +105751,10 @@ class PlaywrightMcpSession {
|
|
|
105652
105751
|
}
|
|
105653
105752
|
function createBrowserTools(targetUrl, evidenceDir, mode = "pentest", logger, abortSignal, headless) {
|
|
105654
105753
|
const session = new PlaywrightMcpSession(headless ?? defaultHeadless);
|
|
105655
|
-
|
|
105656
|
-
session.disconnect().catch(() => {});
|
|
105657
|
-
|
|
105754
|
+
if (abortSignal) {
|
|
105755
|
+
const onAbort = () => session.disconnect().catch(() => {});
|
|
105756
|
+
abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
105757
|
+
}
|
|
105658
105758
|
if (!existsSync11(evidenceDir)) {
|
|
105659
105759
|
mkdirSync3(evidenceDir, { recursive: true });
|
|
105660
105760
|
}
|
|
@@ -108517,9 +108617,17 @@ function runScript(runner, scriptPath, timeout, abortSignal) {
|
|
|
108517
108617
|
let stderr = "";
|
|
108518
108618
|
let killed = false;
|
|
108519
108619
|
let resolved = false;
|
|
108620
|
+
let abortCleanup;
|
|
108621
|
+
if (abortSignal) {
|
|
108622
|
+
const handler = () => killProcess();
|
|
108623
|
+
abortSignal.addEventListener("abort", handler, { once: true });
|
|
108624
|
+
abortCleanup = () => abortSignal.removeEventListener("abort", handler);
|
|
108625
|
+
}
|
|
108520
108626
|
const safeResolve = (result) => {
|
|
108521
108627
|
if (!resolved) {
|
|
108522
108628
|
resolved = true;
|
|
108629
|
+
clearTimeout(timeoutTimer);
|
|
108630
|
+
abortCleanup?.();
|
|
108523
108631
|
resolve4(result);
|
|
108524
108632
|
}
|
|
108525
108633
|
};
|
|
@@ -108553,18 +108661,11 @@ function runScript(runner, scriptPath, timeout, abortSignal) {
|
|
|
108553
108661
|
stderr += data.toString();
|
|
108554
108662
|
});
|
|
108555
108663
|
child.on("close", (code) => {
|
|
108556
|
-
clearTimeout(timeoutTimer);
|
|
108557
108664
|
safeResolve({ stdout, stderr, exitCode: code ?? 1 });
|
|
108558
108665
|
});
|
|
108559
108666
|
child.on("error", (err) => {
|
|
108560
|
-
clearTimeout(timeoutTimer);
|
|
108561
108667
|
safeResolve({ stdout, stderr, exitCode: 1 });
|
|
108562
108668
|
});
|
|
108563
|
-
if (abortSignal) {
|
|
108564
|
-
const handler = () => killProcess();
|
|
108565
|
-
abortSignal.addEventListener("abort", handler, { once: true });
|
|
108566
|
-
child.on("close", () => abortSignal.removeEventListener("abort", handler));
|
|
108567
|
-
}
|
|
108568
108669
|
});
|
|
108569
108670
|
}
|
|
108570
108671
|
var MAX_POC_ATTEMPTS = 3, createPocInputSchema;
|
|
@@ -108799,6 +108900,23 @@ search with flags or a more specific directory if results are truncated.`,
|
|
|
108799
108900
|
});
|
|
108800
108901
|
let stdout = "";
|
|
108801
108902
|
let stderr = "";
|
|
108903
|
+
let resolved = false;
|
|
108904
|
+
let abortCleanup;
|
|
108905
|
+
if (ctx4.abortSignal) {
|
|
108906
|
+
const abortHandler = () => child.kill("SIGTERM");
|
|
108907
|
+
ctx4.abortSignal.addEventListener("abort", abortHandler, {
|
|
108908
|
+
once: true
|
|
108909
|
+
});
|
|
108910
|
+
abortCleanup = () => ctx4.abortSignal.removeEventListener("abort", abortHandler);
|
|
108911
|
+
}
|
|
108912
|
+
const safeResolve = (result) => {
|
|
108913
|
+
if (resolved)
|
|
108914
|
+
return;
|
|
108915
|
+
resolved = true;
|
|
108916
|
+
clearTimeout(timeout);
|
|
108917
|
+
abortCleanup?.();
|
|
108918
|
+
resolve4(result);
|
|
108919
|
+
};
|
|
108802
108920
|
const timeout = setTimeout(() => {
|
|
108803
108921
|
child.kill("SIGTERM");
|
|
108804
108922
|
}, 30000);
|
|
@@ -108809,7 +108927,6 @@ search with flags or a more specific directory if results are truncated.`,
|
|
|
108809
108927
|
stderr += data.toString();
|
|
108810
108928
|
});
|
|
108811
108929
|
child.on("close", (code) => {
|
|
108812
|
-
clearTimeout(timeout);
|
|
108813
108930
|
const noMatch = code === 1 && stderr === "";
|
|
108814
108931
|
const matchCount = stdout ? stdout.trimEnd().split(`
|
|
108815
108932
|
`).length : 0;
|
|
@@ -108817,7 +108934,7 @@ search with flags or a more specific directory if results are truncated.`,
|
|
|
108817
108934
|
const output = truncated ? `${stdout.substring(0, 50000)}
|
|
108818
108935
|
|
|
108819
108936
|
(truncated — narrow your search)` : stdout || "(no matches)";
|
|
108820
|
-
|
|
108937
|
+
safeResolve({
|
|
108821
108938
|
success: code === 0 || noMatch,
|
|
108822
108939
|
error: noMatch || code === 0 ? "" : stderr || `Exit code: ${code}`,
|
|
108823
108940
|
output,
|
|
@@ -108826,8 +108943,7 @@ search with flags or a more specific directory if results are truncated.`,
|
|
|
108826
108943
|
});
|
|
108827
108944
|
});
|
|
108828
108945
|
child.on("error", (err) => {
|
|
108829
|
-
|
|
108830
|
-
resolve4({
|
|
108946
|
+
safeResolve({
|
|
108831
108947
|
success: false,
|
|
108832
108948
|
error: err.message,
|
|
108833
108949
|
output: "",
|
|
@@ -108835,15 +108951,6 @@ search with flags or a more specific directory if results are truncated.`,
|
|
|
108835
108951
|
command
|
|
108836
108952
|
});
|
|
108837
108953
|
});
|
|
108838
|
-
if (ctx4.abortSignal) {
|
|
108839
|
-
const abortHandler = () => child.kill("SIGTERM");
|
|
108840
|
-
ctx4.abortSignal.addEventListener("abort", abortHandler, {
|
|
108841
|
-
once: true
|
|
108842
|
-
});
|
|
108843
|
-
child.on("close", () => {
|
|
108844
|
-
ctx4.abortSignal.removeEventListener("abort", abortHandler);
|
|
108845
|
-
});
|
|
108846
|
-
}
|
|
108847
108954
|
});
|
|
108848
108955
|
}
|
|
108849
108956
|
});
|
|
@@ -194191,6 +194298,7 @@ var init_offensiveSecurityAgent = __esm(() => {
|
|
|
194191
194298
|
resolveResult;
|
|
194192
194299
|
subagentId;
|
|
194193
194300
|
persistentShell;
|
|
194301
|
+
abortSignal;
|
|
194194
194302
|
_session;
|
|
194195
194303
|
static async create(input) {
|
|
194196
194304
|
let session = input.session;
|
|
@@ -194212,6 +194320,7 @@ var init_offensiveSecurityAgent = __esm(() => {
|
|
|
194212
194320
|
constructor(input) {
|
|
194213
194321
|
this._session = input.session;
|
|
194214
194322
|
this.subagentId = input.subagentId;
|
|
194323
|
+
this.abortSignal = input.abortSignal;
|
|
194215
194324
|
if (!input.sandbox) {
|
|
194216
194325
|
this.persistentShell = new PersistentShell({
|
|
194217
194326
|
cwd: input.session.rootPath
|
|
@@ -194375,6 +194484,9 @@ var init_offensiveSecurityAgent = __esm(() => {
|
|
|
194375
194484
|
}
|
|
194376
194485
|
}
|
|
194377
194486
|
this.persistentShell?.dispose();
|
|
194487
|
+
if (this.abortSignal?.aborted) {
|
|
194488
|
+
throw new DOMException("Agent aborted by user", "AbortError");
|
|
194489
|
+
}
|
|
194378
194490
|
if (this.resolveResult) {
|
|
194379
194491
|
return this.resolveResult(this.streamResult);
|
|
194380
194492
|
}
|
|
@@ -194483,6 +194595,7 @@ var init_blackboxAgent = __esm(() => {
|
|
|
194483
194595
|
onStepFinish,
|
|
194484
194596
|
abortSignal,
|
|
194485
194597
|
attackSurfaceRegistry,
|
|
194598
|
+
messages: opts.messages,
|
|
194486
194599
|
activeTools: [
|
|
194487
194600
|
"execute_command",
|
|
194488
194601
|
"document_asset",
|
|
@@ -194758,7 +194871,8 @@ var init_agent4 = __esm(() => {
|
|
|
194758
194871
|
onStepFinish,
|
|
194759
194872
|
abortSignal,
|
|
194760
194873
|
sandbox,
|
|
194761
|
-
findingsRegistry
|
|
194874
|
+
findingsRegistry,
|
|
194875
|
+
messages
|
|
194762
194876
|
} = opts;
|
|
194763
194877
|
super({
|
|
194764
194878
|
system: buildSystemPrompt(session),
|
|
@@ -194771,6 +194885,7 @@ var init_agent4 = __esm(() => {
|
|
|
194771
194885
|
abortSignal,
|
|
194772
194886
|
sandbox,
|
|
194773
194887
|
findingsRegistry,
|
|
194888
|
+
messages,
|
|
194774
194889
|
activeTools: [
|
|
194775
194890
|
"execute_command",
|
|
194776
194891
|
"http_request",
|
|
@@ -194880,7 +194995,7 @@ var EXECUTION_METRICS_FILENAME = "execution-metrics.json";
|
|
|
194880
194995
|
var init_execution_metrics = () => {};
|
|
194881
194996
|
|
|
194882
194997
|
// src/core/utils/concurrency.ts
|
|
194883
|
-
async function runWithBoundedConcurrency(items, concurrency, fn) {
|
|
194998
|
+
async function runWithBoundedConcurrency(items, concurrency, fn, abortSignal) {
|
|
194884
194999
|
const results = new Array(items.length).fill(null);
|
|
194885
195000
|
let nextIdx = 0;
|
|
194886
195001
|
let completed = 0;
|
|
@@ -194891,11 +195006,11 @@ async function runWithBoundedConcurrency(items, concurrency, fn) {
|
|
|
194891
195006
|
}
|
|
194892
195007
|
let active = 0;
|
|
194893
195008
|
function next() {
|
|
194894
|
-
if (completed === items.length) {
|
|
195009
|
+
if (completed >= nextIdx && (nextIdx === items.length || abortSignal?.aborted)) {
|
|
194895
195010
|
resolve4();
|
|
194896
195011
|
return;
|
|
194897
195012
|
}
|
|
194898
|
-
while (active < concurrency && nextIdx < items.length) {
|
|
195013
|
+
while (active < concurrency && nextIdx < items.length && !abortSignal?.aborted) {
|
|
194899
195014
|
const idx = nextIdx++;
|
|
194900
195015
|
active++;
|
|
194901
195016
|
fn(items[idx], idx).then((r2) => {
|
|
@@ -195485,10 +195600,21 @@ async function runPentestSwarm(input) {
|
|
|
195485
195600
|
concurrency = DEFAULT_CONCURRENCY4,
|
|
195486
195601
|
onStepFinish
|
|
195487
195602
|
} = input;
|
|
195488
|
-
const
|
|
195603
|
+
const completedIds = getCompletedAgentIds(session);
|
|
195604
|
+
const existingManifest = readAgentManifest(session);
|
|
195605
|
+
const freshEntries = buildManifestEntries(targets);
|
|
195606
|
+
const manifestEntries = freshEntries.map((fresh) => {
|
|
195607
|
+
const existing = existingManifest.find((e2) => e2.id === fresh.id);
|
|
195608
|
+
if (existing && existing.status === "completed")
|
|
195609
|
+
return existing;
|
|
195610
|
+
return fresh;
|
|
195611
|
+
});
|
|
195489
195612
|
writeAgentManifest(session, manifestEntries);
|
|
195490
195613
|
const results = await runWithBoundedConcurrency(targets, concurrency, async (target, index) => {
|
|
195491
195614
|
const subagentId = `pentest-agent-${index + 1}`;
|
|
195615
|
+
if (completedIds.has(subagentId))
|
|
195616
|
+
return null;
|
|
195617
|
+
const previousMessages = loadSubagentMessages(session, subagentId);
|
|
195492
195618
|
let lastMessages = [];
|
|
195493
195619
|
const handleStepFinish = (e2) => {
|
|
195494
195620
|
if (e2.response.messages) {
|
|
@@ -195522,7 +195648,8 @@ async function runPentestSwarm(input) {
|
|
|
195522
195648
|
authConfig,
|
|
195523
195649
|
abortSignal,
|
|
195524
195650
|
findingsRegistry,
|
|
195525
|
-
onStepFinish: handleStepFinish
|
|
195651
|
+
onStepFinish: handleStepFinish,
|
|
195652
|
+
messages: previousMessages.length > 0 ? previousMessages : undefined
|
|
195526
195653
|
});
|
|
195527
195654
|
const result = await agent.consume({
|
|
195528
195655
|
onError: (e2) => onError?.(e2),
|
|
@@ -195534,8 +195661,9 @@ async function runPentestSwarm(input) {
|
|
|
195534
195661
|
objective: target.objectives.join("; "),
|
|
195535
195662
|
status: "completed",
|
|
195536
195663
|
findingsCount: result.findings.length,
|
|
195537
|
-
messages: lastMessages
|
|
195664
|
+
messages: [...previousMessages, ...lastMessages]
|
|
195538
195665
|
});
|
|
195666
|
+
updateManifestEntryStatus(session, subagentId, "completed");
|
|
195539
195667
|
subagentCallbacks?.onSubagentComplete?.({
|
|
195540
195668
|
subagentId,
|
|
195541
195669
|
input: { target: target.target, objectives: target.objectives },
|
|
@@ -195549,8 +195677,9 @@ async function runPentestSwarm(input) {
|
|
|
195549
195677
|
objective: target.objectives.join("; "),
|
|
195550
195678
|
status: "failed",
|
|
195551
195679
|
error: error40 instanceof Error ? error40.message : String(error40),
|
|
195552
|
-
messages: lastMessages
|
|
195680
|
+
messages: [...previousMessages, ...lastMessages]
|
|
195553
195681
|
});
|
|
195682
|
+
updateManifestEntryStatus(session, subagentId, "failed");
|
|
195554
195683
|
subagentCallbacks?.onSubagentComplete?.({
|
|
195555
195684
|
subagentId,
|
|
195556
195685
|
input: { target: target.target, objectives: target.objectives },
|
|
@@ -195558,7 +195687,7 @@ async function runPentestSwarm(input) {
|
|
|
195558
195687
|
});
|
|
195559
195688
|
throw error40;
|
|
195560
195689
|
}
|
|
195561
|
-
});
|
|
195690
|
+
}, abortSignal);
|
|
195562
195691
|
finalizeManifest(session, manifestEntries, results);
|
|
195563
195692
|
return results;
|
|
195564
195693
|
}
|
|
@@ -195576,7 +195705,13 @@ async function runPentestWorkflow(input) {
|
|
|
195576
195705
|
try {
|
|
195577
195706
|
const mode = cwd ? "whitebox" : "blackbox";
|
|
195578
195707
|
let swarmTargets;
|
|
195579
|
-
|
|
195708
|
+
const existingResults = loadAttackSurfaceResults(session.rootPath);
|
|
195709
|
+
if (existingResults?.targets && existingResults.targets.length > 0) {
|
|
195710
|
+
swarmTargets = existingResults.targets.map((t3) => ({
|
|
195711
|
+
target: t3.target,
|
|
195712
|
+
objectives: [t3.objective]
|
|
195713
|
+
}));
|
|
195714
|
+
} else if (mode === "whitebox") {
|
|
195580
195715
|
swarmTargets = await runWhiteboxPhase({
|
|
195581
195716
|
codebasePath: cwd,
|
|
195582
195717
|
baseTarget: target,
|
|
@@ -195598,6 +195733,9 @@ async function runPentestWorkflow(input) {
|
|
|
195598
195733
|
onStepFinish
|
|
195599
195734
|
});
|
|
195600
195735
|
}
|
|
195736
|
+
if (abortSignal?.aborted) {
|
|
195737
|
+
throw new DOMException("Pentest aborted by user", "AbortError");
|
|
195738
|
+
}
|
|
195601
195739
|
if (swarmTargets.length === 0) {
|
|
195602
195740
|
const report2 = buildPentestReport([], {
|
|
195603
195741
|
target,
|
|
@@ -195621,17 +195759,23 @@ async function runPentestWorkflow(input) {
|
|
|
195621
195759
|
authConfig,
|
|
195622
195760
|
abortSignal
|
|
195623
195761
|
});
|
|
195624
|
-
|
|
195625
|
-
|
|
195626
|
-
|
|
195627
|
-
|
|
195628
|
-
|
|
195629
|
-
|
|
195630
|
-
|
|
195631
|
-
|
|
195632
|
-
|
|
195633
|
-
|
|
195634
|
-
|
|
195762
|
+
const completedCount = getCompletedAgentIds(session).size;
|
|
195763
|
+
if (completedCount < swarmTargets.length) {
|
|
195764
|
+
await runPentestSwarm({
|
|
195765
|
+
targets: swarmTargets,
|
|
195766
|
+
model,
|
|
195767
|
+
session,
|
|
195768
|
+
authConfig,
|
|
195769
|
+
abortSignal,
|
|
195770
|
+
findingsRegistry,
|
|
195771
|
+
subagentCallbacks: callbacks?.subagentCallbacks,
|
|
195772
|
+
onError: (e2) => callbacks?.onError?.(e2),
|
|
195773
|
+
onStepFinish
|
|
195774
|
+
});
|
|
195775
|
+
}
|
|
195776
|
+
if (abortSignal?.aborted) {
|
|
195777
|
+
throw new DOMException("Pentest aborted by user", "AbortError");
|
|
195778
|
+
}
|
|
195635
195779
|
const findings = loadFindings2(session.findingsPath);
|
|
195636
195780
|
const report = buildPentestReport(findings, {
|
|
195637
195781
|
target,
|
|
@@ -195743,6 +195887,7 @@ var init_pentest = __esm(() => {
|
|
|
195743
195887
|
init_report();
|
|
195744
195888
|
init_persistence();
|
|
195745
195889
|
init_execution_metrics();
|
|
195890
|
+
init_loader();
|
|
195746
195891
|
init_whiteboxAttackSurface();
|
|
195747
195892
|
});
|
|
195748
195893
|
|
|
@@ -272350,7 +272495,7 @@ var useTerminalDimensions = () => {
|
|
|
272350
272495
|
};
|
|
272351
272496
|
|
|
272352
272497
|
// src/tui/index.tsx
|
|
272353
|
-
var
|
|
272498
|
+
var import_react87 = __toESM(require_react(), 1);
|
|
272354
272499
|
|
|
272355
272500
|
// src/tui/components/footer.tsx
|
|
272356
272501
|
import os6 from "os";
|
|
@@ -273821,7 +273966,7 @@ function CommandProvider({
|
|
|
273821
273966
|
}
|
|
273822
273967
|
|
|
273823
273968
|
// src/tui/components/commands/sessions-display.tsx
|
|
273824
|
-
var
|
|
273969
|
+
var import_react24 = __toESM(require_react(), 1);
|
|
273825
273970
|
|
|
273826
273971
|
// src/tui/context/focus.tsx
|
|
273827
273972
|
var import_react18 = __toESM(require_react(), 1);
|
|
@@ -273890,10 +274035,29 @@ function openSessionReport(sessionRootPath) {
|
|
|
273890
274035
|
}
|
|
273891
274036
|
}
|
|
273892
274037
|
|
|
274038
|
+
// src/tui/context/dimensions.tsx
|
|
274039
|
+
var import_react19 = __toESM(require_react(), 1);
|
|
274040
|
+
var DimensionsContext = import_react19.createContext(null);
|
|
274041
|
+
function TerminalDimensionsProvider({
|
|
274042
|
+
children
|
|
274043
|
+
}) {
|
|
274044
|
+
const dimensions = useTerminalDimensions();
|
|
274045
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(DimensionsContext.Provider, {
|
|
274046
|
+
value: dimensions,
|
|
274047
|
+
children
|
|
274048
|
+
}, undefined, false, undefined, this);
|
|
274049
|
+
}
|
|
274050
|
+
function useDimensions() {
|
|
274051
|
+
const ctx3 = import_react19.useContext(DimensionsContext);
|
|
274052
|
+
if (!ctx3)
|
|
274053
|
+
throw new Error("useDimensions() must be used within <TerminalDimensionsProvider>");
|
|
274054
|
+
return ctx3;
|
|
274055
|
+
}
|
|
274056
|
+
|
|
273893
274057
|
// src/tui/context/dialog.tsx
|
|
273894
|
-
var
|
|
274058
|
+
var import_react22 = __toESM(require_react(), 1);
|
|
273895
274059
|
function Dialog({ size = "medium", onClose, children }) {
|
|
273896
|
-
const dimensions =
|
|
274060
|
+
const dimensions = useDimensions();
|
|
273897
274061
|
const renderer = useRenderer();
|
|
273898
274062
|
const { colors: themeColors } = useTheme();
|
|
273899
274063
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
@@ -273928,14 +274092,14 @@ function Dialog({ size = "medium", onClose, children }) {
|
|
|
273928
274092
|
}, undefined, false, undefined, this)
|
|
273929
274093
|
}, undefined, false, undefined, this);
|
|
273930
274094
|
}
|
|
273931
|
-
var DialogContext =
|
|
274095
|
+
var DialogContext = import_react22.createContext(null);
|
|
273932
274096
|
function DialogProvider({ children }) {
|
|
273933
|
-
const [stack, setStack] =
|
|
273934
|
-
const [size, setSize] =
|
|
273935
|
-
const [externalDialogOpen, setExternalDialogOpen] =
|
|
274097
|
+
const [stack, setStack] = import_react22.useState([]);
|
|
274098
|
+
const [size, setSize] = import_react22.useState("medium");
|
|
274099
|
+
const [externalDialogOpen, setExternalDialogOpen] = import_react22.useState(false);
|
|
273936
274100
|
const renderer = useRenderer();
|
|
273937
|
-
const focusRef =
|
|
273938
|
-
const refocus =
|
|
274101
|
+
const focusRef = import_react22.useRef(null);
|
|
274102
|
+
const refocus = import_react22.useCallback(() => {
|
|
273939
274103
|
setTimeout(() => {
|
|
273940
274104
|
const focus = focusRef.current;
|
|
273941
274105
|
if (!focus)
|
|
@@ -273957,7 +274121,7 @@ function DialogProvider({ children }) {
|
|
|
273957
274121
|
focus.focus();
|
|
273958
274122
|
}, 1);
|
|
273959
274123
|
}, [renderer]);
|
|
273960
|
-
const clear =
|
|
274124
|
+
const clear = import_react22.useCallback(() => {
|
|
273961
274125
|
for (const item of stack) {
|
|
273962
274126
|
if (item.onClose)
|
|
273963
274127
|
item.onClose();
|
|
@@ -273966,7 +274130,7 @@ function DialogProvider({ children }) {
|
|
|
273966
274130
|
setStack([]);
|
|
273967
274131
|
refocus();
|
|
273968
274132
|
}, [stack, refocus]);
|
|
273969
|
-
const replace =
|
|
274133
|
+
const replace = import_react22.useCallback((element, onClose) => {
|
|
273970
274134
|
if (stack.length === 0) {
|
|
273971
274135
|
focusRef.current = renderer.currentFocusedRenderable;
|
|
273972
274136
|
}
|
|
@@ -274011,7 +274175,7 @@ function DialogProvider({ children }) {
|
|
|
274011
274175
|
}, undefined, true, undefined, this);
|
|
274012
274176
|
}
|
|
274013
274177
|
function useDialog() {
|
|
274014
|
-
const value =
|
|
274178
|
+
const value = import_react22.useContext(DialogContext);
|
|
274015
274179
|
if (!value) {
|
|
274016
274180
|
throw new Error("useDialog must be used within a DialogProvider");
|
|
274017
274181
|
}
|
|
@@ -274076,7 +274240,7 @@ function findChildById(scrollBox, id) {
|
|
|
274076
274240
|
// src/tui/hooks/use-sessions-list.ts
|
|
274077
274241
|
init_session();
|
|
274078
274242
|
init_report();
|
|
274079
|
-
var
|
|
274243
|
+
var import_react23 = __toESM(require_react(), 1);
|
|
274080
274244
|
import { existsSync as existsSync7, readdirSync } from "fs";
|
|
274081
274245
|
import { join as join3 } from "path";
|
|
274082
274246
|
function countFindings(findingsPath) {
|
|
@@ -274092,10 +274256,10 @@ function checkHasReport(rootPath) {
|
|
|
274092
274256
|
return existsSync7(join3(rootPath, REPORT_FILENAME_MD));
|
|
274093
274257
|
}
|
|
274094
274258
|
function useSessionsList() {
|
|
274095
|
-
const [allSessions, setAllSessions] =
|
|
274096
|
-
const [loading, setLoading] =
|
|
274097
|
-
const [searchTerm, setSearchTerm] =
|
|
274098
|
-
const loadSessions =
|
|
274259
|
+
const [allSessions, setAllSessions] = import_react23.useState([]);
|
|
274260
|
+
const [loading, setLoading] = import_react23.useState(true);
|
|
274261
|
+
const [searchTerm, setSearchTerm] = import_react23.useState("");
|
|
274262
|
+
const loadSessions = import_react23.useCallback(async () => {
|
|
274099
274263
|
setLoading(true);
|
|
274100
274264
|
try {
|
|
274101
274265
|
const enriched = [];
|
|
@@ -274118,10 +274282,10 @@ function useSessionsList() {
|
|
|
274118
274282
|
setLoading(false);
|
|
274119
274283
|
}
|
|
274120
274284
|
}, []);
|
|
274121
|
-
|
|
274285
|
+
import_react23.useEffect(() => {
|
|
274122
274286
|
loadSessions();
|
|
274123
274287
|
}, [loadSessions]);
|
|
274124
|
-
const deleteSession =
|
|
274288
|
+
const deleteSession = import_react23.useCallback(async (id) => {
|
|
274125
274289
|
await sessions.remove({ sessionId: id });
|
|
274126
274290
|
await loadSessions();
|
|
274127
274291
|
}, [loadSessions]);
|
|
@@ -274180,10 +274344,10 @@ function useSessionsList() {
|
|
|
274180
274344
|
function SessionsDisplay({ onClose }) {
|
|
274181
274345
|
const { colors: colors2 } = useTheme();
|
|
274182
274346
|
const { refocusPrompt } = useFocus();
|
|
274183
|
-
const [selectedIndex, setSelectedIndex] =
|
|
274184
|
-
const [statusMessage, setStatusMessage] =
|
|
274347
|
+
const [selectedIndex, setSelectedIndex] = import_react24.useState(0);
|
|
274348
|
+
const [statusMessage, setStatusMessage] = import_react24.useState("");
|
|
274185
274349
|
const route = useRoute();
|
|
274186
|
-
const scroll =
|
|
274350
|
+
const scroll = import_react24.useRef(null);
|
|
274187
274351
|
const {
|
|
274188
274352
|
groupedSessions,
|
|
274189
274353
|
visualOrderSessions,
|
|
@@ -274199,7 +274363,7 @@ function SessionsDisplay({ onClose }) {
|
|
|
274199
274363
|
setTimeout(() => setStatusMessage(""), 2000);
|
|
274200
274364
|
}
|
|
274201
274365
|
}
|
|
274202
|
-
|
|
274366
|
+
import_react24.useEffect(() => {
|
|
274203
274367
|
if (visualOrderSessions.length > 0 && selectedIndex >= visualOrderSessions.length) {
|
|
274204
274368
|
setSelectedIndex(visualOrderSessions.length - 1);
|
|
274205
274369
|
} else if (visualOrderSessions.length === 0) {
|
|
@@ -274235,7 +274399,7 @@ function SessionsDisplay({ onClose }) {
|
|
|
274235
274399
|
setTimeout(() => setStatusMessage(""), 2000);
|
|
274236
274400
|
return;
|
|
274237
274401
|
}
|
|
274238
|
-
const isOperator = currentSelection.config?.mode === "operator" || currentSelection.hasOperatorState;
|
|
274402
|
+
const isOperator = currentSelection.config?.mode === "operator" || !currentSelection.config?.mode && currentSelection.hasOperatorState;
|
|
274239
274403
|
refocusPrompt();
|
|
274240
274404
|
onClose();
|
|
274241
274405
|
route.navigate({
|
|
@@ -274281,6 +274445,11 @@ function SessionsDisplay({ onClose }) {
|
|
|
274281
274445
|
const currentSelection = visualOrderSessions[selectedIndex];
|
|
274282
274446
|
if (!currentSelection)
|
|
274283
274447
|
return;
|
|
274448
|
+
if (!currentSelection.hasReport) {
|
|
274449
|
+
setStatusMessage("No report available");
|
|
274450
|
+
setTimeout(() => setStatusMessage(""), 2000);
|
|
274451
|
+
return;
|
|
274452
|
+
}
|
|
274284
274453
|
openReport(currentSelection.id);
|
|
274285
274454
|
return;
|
|
274286
274455
|
}
|
|
@@ -274384,6 +274553,7 @@ function SessionsDisplay({ onClose }) {
|
|
|
274384
274553
|
});
|
|
274385
274554
|
const mode = session.config?.mode || "auto";
|
|
274386
274555
|
const modeBadge = mode === "operator" ? "[operator]" : "[auto]";
|
|
274556
|
+
const statusBadge = session.hasReport ? "✓" : "…";
|
|
274387
274557
|
const findingsText = session.findingsCount > 0 ? `${session.findingsCount} finding${session.findingsCount > 1 ? "s" : ""}` : "";
|
|
274388
274558
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
274389
274559
|
id: session.id,
|
|
@@ -274408,6 +274578,10 @@ function SessionsDisplay({ onClose }) {
|
|
|
274408
274578
|
fg: isSelected ? colors2.text : colors2.textMuted,
|
|
274409
274579
|
children: session.name
|
|
274410
274580
|
}, undefined, false, undefined, this),
|
|
274581
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
274582
|
+
fg: session.hasReport ? colors2.primary : colors2.textMuted,
|
|
274583
|
+
children: statusBadge
|
|
274584
|
+
}, undefined, false, undefined, this),
|
|
274411
274585
|
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
274412
274586
|
fg: mode === "operator" ? colors2.primary : colors2.textMuted,
|
|
274413
274587
|
children: modeBadge
|
|
@@ -274471,7 +274645,7 @@ function SessionsDisplay({ onClose }) {
|
|
|
274471
274645
|
}
|
|
274472
274646
|
|
|
274473
274647
|
// src/tui/components/commands/config-dialog.tsx
|
|
274474
|
-
var
|
|
274648
|
+
var import_react27 = __toESM(require_react(), 1);
|
|
274475
274649
|
|
|
274476
274650
|
// src/tui/components/alert-dialog.tsx
|
|
274477
274651
|
function AlertDialog({
|
|
@@ -274484,7 +274658,7 @@ function AlertDialog({
|
|
|
274484
274658
|
size = "medium"
|
|
274485
274659
|
}) {
|
|
274486
274660
|
const { colors: colors2 } = useTheme();
|
|
274487
|
-
const dimensions =
|
|
274661
|
+
const dimensions = useDimensions();
|
|
274488
274662
|
const renderer = useRenderer();
|
|
274489
274663
|
useKeyboard((key) => {
|
|
274490
274664
|
if (!open)
|
|
@@ -274558,8 +274732,8 @@ function AlertDialog({
|
|
|
274558
274732
|
init_config2();
|
|
274559
274733
|
function ConfigDialog() {
|
|
274560
274734
|
const route = useRoute();
|
|
274561
|
-
const [open, setOpen] =
|
|
274562
|
-
|
|
274735
|
+
const [open, setOpen] = import_react27.useState(false);
|
|
274736
|
+
import_react27.useEffect(() => {
|
|
274563
274737
|
if (route.data.type === "base" && route.data.path === "config") {
|
|
274564
274738
|
setOpen(true);
|
|
274565
274739
|
} else {
|
|
@@ -274573,8 +274747,8 @@ function ConfigDialog() {
|
|
|
274573
274747
|
path: "home"
|
|
274574
274748
|
});
|
|
274575
274749
|
};
|
|
274576
|
-
const [appConfig, setAppConfig] =
|
|
274577
|
-
|
|
274750
|
+
const [appConfig, setAppConfig] = import_react27.useState(null);
|
|
274751
|
+
import_react27.useEffect(() => {
|
|
274578
274752
|
async function getConfig() {
|
|
274579
274753
|
const _appConfig = await config2.get();
|
|
274580
274754
|
setAppConfig(_appConfig);
|
|
@@ -274649,11 +274823,11 @@ var import_react38 = __toESM(require_react(), 1);
|
|
|
274649
274823
|
|
|
274650
274824
|
// src/tui/context/config.tsx
|
|
274651
274825
|
init_config2();
|
|
274652
|
-
var
|
|
274653
|
-
var ctx3 =
|
|
274826
|
+
var import_react28 = __toESM(require_react(), 1);
|
|
274827
|
+
var ctx3 = import_react28.createContext(null);
|
|
274654
274828
|
function ConfigProvider({ children, config: config3 }) {
|
|
274655
|
-
const [appConfig, setAppConfig] =
|
|
274656
|
-
const value =
|
|
274829
|
+
const [appConfig, setAppConfig] = import_react28.useState(config3);
|
|
274830
|
+
const value = import_react28.useMemo(() => ({
|
|
274657
274831
|
data: appConfig,
|
|
274658
274832
|
update: async (newConfig) => {
|
|
274659
274833
|
await config2.update(newConfig);
|
|
@@ -274673,7 +274847,7 @@ function ConfigProvider({ children, config: config3 }) {
|
|
|
274673
274847
|
}, undefined, false, undefined, this);
|
|
274674
274848
|
}
|
|
274675
274849
|
var useConfig = () => {
|
|
274676
|
-
const config3 =
|
|
274850
|
+
const config3 = import_react28.useContext(ctx3);
|
|
274677
274851
|
if (!config3) {
|
|
274678
274852
|
throw new Error("useConfig must be called within a ConfigProvider");
|
|
274679
274853
|
}
|
|
@@ -274681,10 +274855,10 @@ var useConfig = () => {
|
|
|
274681
274855
|
};
|
|
274682
274856
|
|
|
274683
274857
|
// src/tui/components/chat/home-view.tsx
|
|
274684
|
-
var
|
|
274858
|
+
var import_react33 = __toESM(require_react(), 1);
|
|
274685
274859
|
|
|
274686
274860
|
// src/tui/components/chat/petri-animation.tsx
|
|
274687
|
-
var
|
|
274861
|
+
var import_react29 = __toESM(require_react(), 1);
|
|
274688
274862
|
|
|
274689
274863
|
// src/tui/components/chat/lib/play-core/num.ts
|
|
274690
274864
|
function clamp(x2, min, max) {
|
|
@@ -274780,8 +274954,8 @@ function stopGlobalTick2() {
|
|
|
274780
274954
|
}
|
|
274781
274955
|
}
|
|
274782
274956
|
function useGlobalTick2() {
|
|
274783
|
-
const [, setTick] =
|
|
274784
|
-
|
|
274957
|
+
const [, setTick] = import_react29.useState(0);
|
|
274958
|
+
import_react29.useEffect(() => {
|
|
274785
274959
|
const listener = () => setTick((t2) => t2 + 1);
|
|
274786
274960
|
globalListeners2.add(listener);
|
|
274787
274961
|
startGlobalTick2();
|
|
@@ -274806,19 +274980,19 @@ function PetriAnimation({
|
|
|
274806
274980
|
height = 0.4,
|
|
274807
274981
|
width = "100%"
|
|
274808
274982
|
}) {
|
|
274809
|
-
const dimensions =
|
|
274983
|
+
const dimensions = useDimensions();
|
|
274810
274984
|
const tick = useGlobalTick2();
|
|
274811
274985
|
const { colors: colors2 } = useTheme();
|
|
274812
|
-
const simulationRef =
|
|
274813
|
-
const [frame, setFrame] =
|
|
274814
|
-
const gradientColors =
|
|
274815
|
-
const actualHeight =
|
|
274986
|
+
const simulationRef = import_react29.useRef(null);
|
|
274987
|
+
const [frame, setFrame] = import_react29.useState([]);
|
|
274988
|
+
const gradientColors = import_react29.useMemo(() => generateGradient(colors2.primary, 9), [colors2.primary]);
|
|
274989
|
+
const actualHeight = import_react29.useMemo(() => {
|
|
274816
274990
|
if (typeof height === "number" && height <= 1) {
|
|
274817
274991
|
return Math.floor(dimensions.height * height);
|
|
274818
274992
|
}
|
|
274819
274993
|
return typeof height === "number" ? height : Math.floor(dimensions.height * 0.4);
|
|
274820
274994
|
}, [height, dimensions.height]);
|
|
274821
|
-
const actualWidth =
|
|
274995
|
+
const actualWidth = import_react29.useMemo(() => {
|
|
274822
274996
|
if (typeof width === "number" && width <= 1) {
|
|
274823
274997
|
return Math.floor(dimensions.width * width);
|
|
274824
274998
|
}
|
|
@@ -274827,7 +275001,7 @@ function PetriAnimation({
|
|
|
274827
275001
|
}
|
|
274828
275002
|
return typeof width === "number" ? width : dimensions.width;
|
|
274829
275003
|
}, [width, dimensions.width]);
|
|
274830
|
-
|
|
275004
|
+
import_react29.useEffect(() => {
|
|
274831
275005
|
if (actualWidth <= 0 || actualHeight <= 0)
|
|
274832
275006
|
return;
|
|
274833
275007
|
if (!simulationRef.current) {
|
|
@@ -274836,7 +275010,7 @@ function PetriAnimation({
|
|
|
274836
275010
|
simulationRef.current.resize(actualWidth, actualHeight);
|
|
274837
275011
|
}
|
|
274838
275012
|
}, [actualWidth, actualHeight]);
|
|
274839
|
-
|
|
275013
|
+
import_react29.useEffect(() => {
|
|
274840
275014
|
if (simulationRef.current) {
|
|
274841
275015
|
simulationRef.current.step();
|
|
274842
275016
|
setFrame(simulationRef.current.render());
|
|
@@ -274862,7 +275036,7 @@ function getRowColor(rowIdx, totalRows, gradient) {
|
|
|
274862
275036
|
}
|
|
274863
275037
|
|
|
274864
275038
|
// src/tui/components/shared/prompt-input.tsx
|
|
274865
|
-
var
|
|
275039
|
+
var import_react31 = __toESM(require_react(), 1);
|
|
274866
275040
|
|
|
274867
275041
|
// src/tui/components/shared/prompt-input-logic.ts
|
|
274868
275042
|
function filterSuggestions(inputValue, options, maxSuggestions) {
|
|
@@ -274983,13 +275157,13 @@ function shouldResetHistory(historyIndex, isNavigatingHistory) {
|
|
|
274983
275157
|
}
|
|
274984
275158
|
|
|
274985
275159
|
// src/tui/components/shared/use-paste-extmarks.ts
|
|
274986
|
-
var
|
|
275160
|
+
var import_react30 = __toESM(require_react(), 1);
|
|
274987
275161
|
var LARGE_PASTE_MIN_LINES = 5;
|
|
274988
275162
|
var LARGE_PASTE_MIN_CHARS = 500;
|
|
274989
275163
|
function usePasteExtmarks(textareaRef) {
|
|
274990
|
-
const countRef =
|
|
274991
|
-
const typeIdRef =
|
|
274992
|
-
const dataRef =
|
|
275164
|
+
const countRef = import_react30.useRef(0);
|
|
275165
|
+
const typeIdRef = import_react30.useRef(-1);
|
|
275166
|
+
const dataRef = import_react30.useRef(new Map);
|
|
274993
275167
|
const clearPaste = () => {
|
|
274994
275168
|
textareaRef.current?.extmarks.clear();
|
|
274995
275169
|
countRef.current = 0;
|
|
@@ -275059,7 +275233,7 @@ var chatKeyBindings = [
|
|
|
275059
275233
|
{ name: "return", shift: true, action: "newline" },
|
|
275060
275234
|
{ name: "linefeed", shift: true, action: "newline" }
|
|
275061
275235
|
];
|
|
275062
|
-
var PromptInput =
|
|
275236
|
+
var PromptInput = import_react31.forwardRef(function PromptInput2({
|
|
275063
275237
|
width,
|
|
275064
275238
|
minHeight = 1,
|
|
275065
275239
|
maxHeight = 6,
|
|
@@ -275084,31 +275258,31 @@ var PromptInput = import_react30.forwardRef(function PromptInput2({
|
|
|
275084
275258
|
const { colors: colors2 } = useTheme();
|
|
275085
275259
|
const { inputValue, setInputValue } = useInput();
|
|
275086
275260
|
const { registerPromptRef } = useFocus();
|
|
275087
|
-
const textareaRef =
|
|
275088
|
-
const [selectedSuggestionIndex, setSelectedSuggestionIndex] =
|
|
275089
|
-
const [historyIndex, setHistoryIndex] =
|
|
275090
|
-
const savedInputRef =
|
|
275091
|
-
const historyRef =
|
|
275261
|
+
const textareaRef = import_react31.useRef(null);
|
|
275262
|
+
const [selectedSuggestionIndex, setSelectedSuggestionIndex] = import_react31.useState(-1);
|
|
275263
|
+
const [historyIndex, setHistoryIndex] = import_react31.useState(-1);
|
|
275264
|
+
const savedInputRef = import_react31.useRef("");
|
|
275265
|
+
const historyRef = import_react31.useRef(commandHistory);
|
|
275092
275266
|
historyRef.current = commandHistory;
|
|
275093
|
-
const isNavigatingHistoryRef =
|
|
275094
|
-
const selectedIndexRef =
|
|
275095
|
-
const suggestionsRef =
|
|
275096
|
-
const onCommandExecuteRef =
|
|
275267
|
+
const isNavigatingHistoryRef = import_react31.useRef(false);
|
|
275268
|
+
const selectedIndexRef = import_react31.useRef(selectedSuggestionIndex);
|
|
275269
|
+
const suggestionsRef = import_react31.useRef([]);
|
|
275270
|
+
const onCommandExecuteRef = import_react31.useRef(onCommandExecute);
|
|
275097
275271
|
onCommandExecuteRef.current = onCommandExecute;
|
|
275098
|
-
const onSubmitRef =
|
|
275272
|
+
const onSubmitRef = import_react31.useRef(onSubmit);
|
|
275099
275273
|
onSubmitRef.current = onSubmit;
|
|
275100
275274
|
const { handlePaste, resolveText, clearPaste } = usePasteExtmarks(textareaRef);
|
|
275101
|
-
const suggestions =
|
|
275102
|
-
|
|
275275
|
+
const suggestions = import_react31.useMemo(() => enableAutocomplete ? filterSuggestions(inputValue, autocompleteOptions, maxSuggestions) : [], [enableAutocomplete, autocompleteOptions, inputValue, maxSuggestions]);
|
|
275276
|
+
import_react31.useEffect(() => {
|
|
275103
275277
|
suggestionsRef.current = suggestions;
|
|
275104
275278
|
}, [suggestions]);
|
|
275105
|
-
|
|
275279
|
+
import_react31.useEffect(() => {
|
|
275106
275280
|
selectedIndexRef.current = selectedSuggestionIndex;
|
|
275107
275281
|
}, [selectedSuggestionIndex]);
|
|
275108
|
-
|
|
275282
|
+
import_react31.useEffect(() => {
|
|
275109
275283
|
setSelectedSuggestionIndex(suggestions.length > 0 ? 0 : -1);
|
|
275110
275284
|
}, [suggestions.length]);
|
|
275111
|
-
const imperativeRef =
|
|
275285
|
+
const imperativeRef = import_react31.useRef({
|
|
275112
275286
|
focus: () => textareaRef.current?.focus(),
|
|
275113
275287
|
blur: () => textareaRef.current?.blur(),
|
|
275114
275288
|
reset: () => {
|
|
@@ -275125,11 +275299,11 @@ var PromptInput = import_react30.forwardRef(function PromptInput2({
|
|
|
275125
275299
|
getValue: () => inputValue,
|
|
275126
275300
|
getTextareaRef: () => textareaRef.current
|
|
275127
275301
|
});
|
|
275128
|
-
|
|
275302
|
+
import_react31.useEffect(() => {
|
|
275129
275303
|
imperativeRef.current.getValue = () => inputValue;
|
|
275130
275304
|
}, [inputValue]);
|
|
275131
|
-
|
|
275132
|
-
|
|
275305
|
+
import_react31.useImperativeHandle(ref, () => imperativeRef.current, []);
|
|
275306
|
+
import_react31.useEffect(() => {
|
|
275133
275307
|
registerPromptRef(imperativeRef.current);
|
|
275134
275308
|
return () => registerPromptRef(null);
|
|
275135
275309
|
}, [registerPromptRef]);
|
|
@@ -275345,41 +275519,41 @@ function getEntries() {
|
|
|
275345
275519
|
// src/tui/components/chat/home-view.tsx
|
|
275346
275520
|
function HomeView({ onNavigate, onStartSession }) {
|
|
275347
275521
|
const { colors: colors2 } = useTheme();
|
|
275348
|
-
const dimensions =
|
|
275522
|
+
const dimensions = useDimensions();
|
|
275349
275523
|
const config3 = useConfig();
|
|
275350
275524
|
const route = useRoute();
|
|
275351
275525
|
const { executeCommand, autocompleteOptions, resolveSkillContent, skills } = useCommand();
|
|
275352
275526
|
const { setInputValue } = useInput();
|
|
275353
275527
|
const { promptRef } = useFocus();
|
|
275354
275528
|
const { externalDialogOpen, stack } = useDialog();
|
|
275355
|
-
const [hintMessage, setHintMessage] =
|
|
275356
|
-
const [commandHistory, setCommandHistory] =
|
|
275357
|
-
|
|
275529
|
+
const [hintMessage, setHintMessage] = import_react33.useState(null);
|
|
275530
|
+
const [commandHistory, setCommandHistory] = import_react33.useState(getEntries);
|
|
275531
|
+
import_react33.useEffect(() => {
|
|
275358
275532
|
load().then(setCommandHistory);
|
|
275359
275533
|
}, []);
|
|
275360
|
-
const launchOperator =
|
|
275534
|
+
const launchOperator = import_react33.useCallback((message, options) => {
|
|
275361
275535
|
route.navigate({
|
|
275362
275536
|
type: "operator",
|
|
275363
275537
|
initialMessage: message,
|
|
275364
275538
|
initialConfig: { requireApproval: options?.requireApproval ?? true }
|
|
275365
275539
|
});
|
|
275366
275540
|
}, [route]);
|
|
275367
|
-
const pushHistory =
|
|
275541
|
+
const pushHistory = import_react33.useCallback((entry) => {
|
|
275368
275542
|
push(entry).then(() => setCommandHistory([...getEntries()]));
|
|
275369
275543
|
}, []);
|
|
275370
|
-
const handleSubmit =
|
|
275544
|
+
const handleSubmit = import_react33.useCallback((value) => {
|
|
275371
275545
|
if (!value.trim())
|
|
275372
275546
|
return;
|
|
275373
275547
|
pushHistory(value.trim());
|
|
275374
275548
|
launchOperator(value.trim());
|
|
275375
275549
|
}, [launchOperator, pushHistory]);
|
|
275376
|
-
|
|
275550
|
+
import_react33.useEffect(() => {
|
|
275377
275551
|
if (!hintMessage)
|
|
275378
275552
|
return;
|
|
275379
275553
|
const timer = setTimeout(() => setHintMessage(null), 3000);
|
|
275380
275554
|
return () => clearTimeout(timer);
|
|
275381
275555
|
}, [hintMessage]);
|
|
275382
|
-
const handleCommandExecute =
|
|
275556
|
+
const handleCommandExecute = import_react33.useCallback(async (command) => {
|
|
275383
275557
|
const trimmed = command.trim();
|
|
275384
275558
|
pushHistory(trimmed);
|
|
275385
275559
|
const parts = trimmed.replace(/^\/+/, "").split(/\s+/);
|
|
@@ -278243,7 +278417,7 @@ function ToastItem({
|
|
|
278243
278417
|
}
|
|
278244
278418
|
function ToastContainer() {
|
|
278245
278419
|
const { toasts, dismiss } = useToast();
|
|
278246
|
-
const dims =
|
|
278420
|
+
const dims = useDimensions();
|
|
278247
278421
|
if (toasts.length === 0)
|
|
278248
278422
|
return null;
|
|
278249
278423
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
@@ -278264,11 +278438,11 @@ function ToastContainer() {
|
|
|
278264
278438
|
}
|
|
278265
278439
|
|
|
278266
278440
|
// src/tui/components/error-boundary.tsx
|
|
278267
|
-
var
|
|
278441
|
+
var import_react52 = __toESM(require_react(), 1);
|
|
278268
278442
|
var MAX_ERRORS = 3;
|
|
278269
278443
|
var ERROR_WINDOW_MS = 5000;
|
|
278270
278444
|
|
|
278271
|
-
class ErrorBoundaryInner extends
|
|
278445
|
+
class ErrorBoundaryInner extends import_react52.default.Component {
|
|
278272
278446
|
state = {
|
|
278273
278447
|
hasError: false,
|
|
278274
278448
|
errorTimestamps: [],
|
|
@@ -278299,10 +278473,10 @@ class ErrorBoundaryInner extends import_react53.default.Component {
|
|
|
278299
278473
|
}
|
|
278300
278474
|
function ErrorBoundary2({ children }) {
|
|
278301
278475
|
const { toast } = useToast();
|
|
278302
|
-
const handleError =
|
|
278476
|
+
const handleError = import_react52.useCallback((message) => {
|
|
278303
278477
|
toast(message, "error");
|
|
278304
278478
|
}, [toast]);
|
|
278305
|
-
return
|
|
278479
|
+
return import_react52.default.createElement(ErrorBoundaryInner, { onError: handleError }, children);
|
|
278306
278480
|
}
|
|
278307
278481
|
|
|
278308
278482
|
// src/tui/index.tsx
|
|
@@ -278413,16 +278587,16 @@ function ShortcutsDialog({
|
|
|
278413
278587
|
}
|
|
278414
278588
|
|
|
278415
278589
|
// src/tui/components/commands/help-dialog.tsx
|
|
278416
|
-
var
|
|
278590
|
+
var import_react54 = __toESM(require_react(), 1);
|
|
278417
278591
|
function HelpDialog() {
|
|
278418
278592
|
const { colors: colors2 } = useTheme();
|
|
278419
278593
|
const { commands: commands2 } = useCommand();
|
|
278420
278594
|
const route = useRoute();
|
|
278421
|
-
const dimensions =
|
|
278422
|
-
const [selectedIndex, setSelectedIndex] =
|
|
278423
|
-
const [showDetail, setShowDetail] =
|
|
278424
|
-
const scrollboxRef =
|
|
278425
|
-
const commandsByCategory =
|
|
278595
|
+
const dimensions = useDimensions();
|
|
278596
|
+
const [selectedIndex, setSelectedIndex] = import_react54.useState(0);
|
|
278597
|
+
const [showDetail, setShowDetail] = import_react54.useState(false);
|
|
278598
|
+
const scrollboxRef = import_react54.useRef(null);
|
|
278599
|
+
const commandsByCategory = import_react54.useMemo(() => {
|
|
278426
278600
|
const grouped = {};
|
|
278427
278601
|
for (const cmd of commands2) {
|
|
278428
278602
|
const category = cmd.category || "Other";
|
|
@@ -278433,15 +278607,15 @@ function HelpDialog() {
|
|
|
278433
278607
|
}
|
|
278434
278608
|
return grouped;
|
|
278435
278609
|
}, [commands2]);
|
|
278436
|
-
const flatCommands =
|
|
278610
|
+
const flatCommands = import_react54.useMemo(() => {
|
|
278437
278611
|
return commands2;
|
|
278438
278612
|
}, [commands2]);
|
|
278439
|
-
|
|
278613
|
+
import_react54.useEffect(() => {
|
|
278440
278614
|
if (selectedIndex >= flatCommands.length) {
|
|
278441
278615
|
setSelectedIndex(Math.max(0, flatCommands.length - 1));
|
|
278442
278616
|
}
|
|
278443
278617
|
}, [flatCommands.length, selectedIndex]);
|
|
278444
|
-
|
|
278618
|
+
import_react54.useEffect(() => {
|
|
278445
278619
|
scrollToIndex(scrollboxRef.current, selectedIndex, flatCommands, (cmd) => cmd.name);
|
|
278446
278620
|
}, [selectedIndex, flatCommands]);
|
|
278447
278621
|
const handleClose = () => {
|
|
@@ -278876,24 +279050,24 @@ function ModelsDisplay() {
|
|
|
278876
279050
|
}
|
|
278877
279051
|
|
|
278878
279052
|
// src/tui/components/commands/auth-flow.tsx
|
|
278879
|
-
var
|
|
279053
|
+
var import_react57 = __toESM(require_react(), 1);
|
|
278880
279054
|
init_config2();
|
|
278881
279055
|
function AuthFlow({ onClose }) {
|
|
278882
279056
|
const { colors: colors2 } = useTheme();
|
|
278883
279057
|
const appConfig = useConfig();
|
|
278884
279058
|
const isConnected = !!(appConfig.data.accessToken || appConfig.data.pensarAPIKey);
|
|
278885
|
-
const [step, setStep] =
|
|
278886
|
-
const [error40, setError] =
|
|
278887
|
-
const [authMode, setAuthMode] =
|
|
278888
|
-
const [deviceInfo, setDeviceInfo] =
|
|
278889
|
-
const [legacyDeviceInfo, setLegacyDeviceInfo] =
|
|
278890
|
-
const [workspaces, setWorkspaces] =
|
|
278891
|
-
const [selectedWorkspace, setSelectedWorkspace] =
|
|
278892
|
-
const [selectedIndex, setSelectedIndex] =
|
|
278893
|
-
const [billingUrl, setBillingUrl] =
|
|
278894
|
-
const [balance, setBalance] =
|
|
278895
|
-
const pollingRef =
|
|
278896
|
-
const cancelledRef =
|
|
279059
|
+
const [step, setStep] = import_react57.useState(isConnected ? "success" : "start");
|
|
279060
|
+
const [error40, setError] = import_react57.useState(null);
|
|
279061
|
+
const [authMode, setAuthMode] = import_react57.useState(null);
|
|
279062
|
+
const [deviceInfo, setDeviceInfo] = import_react57.useState(null);
|
|
279063
|
+
const [legacyDeviceInfo, setLegacyDeviceInfo] = import_react57.useState(null);
|
|
279064
|
+
const [workspaces, setWorkspaces] = import_react57.useState([]);
|
|
279065
|
+
const [selectedWorkspace, setSelectedWorkspace] = import_react57.useState(null);
|
|
279066
|
+
const [selectedIndex, setSelectedIndex] = import_react57.useState(0);
|
|
279067
|
+
const [billingUrl, setBillingUrl] = import_react57.useState(null);
|
|
279068
|
+
const [balance, setBalance] = import_react57.useState(null);
|
|
279069
|
+
const pollingRef = import_react57.useRef(null);
|
|
279070
|
+
const cancelledRef = import_react57.useRef(false);
|
|
278897
279071
|
const connectedWorkspace = appConfig.data.workspaceSlug ? { name: appConfig.data.workspaceSlug, slug: appConfig.data.workspaceSlug } : null;
|
|
278898
279072
|
const goHome = () => {
|
|
278899
279073
|
onClose();
|
|
@@ -278905,7 +279079,7 @@ function AuthFlow({ onClose }) {
|
|
|
278905
279079
|
pollingRef.current = null;
|
|
278906
279080
|
}
|
|
278907
279081
|
};
|
|
278908
|
-
|
|
279082
|
+
import_react57.useEffect(() => {
|
|
278909
279083
|
return cleanup;
|
|
278910
279084
|
}, []);
|
|
278911
279085
|
const openUrl = (url2) => {
|
|
@@ -278924,7 +279098,7 @@ function AuthFlow({ onClose }) {
|
|
|
278924
279098
|
setStep("requesting");
|
|
278925
279099
|
setError(null);
|
|
278926
279100
|
cancelledRef.current = false;
|
|
278927
|
-
const apiUrl = getPensarApiUrl(
|
|
279101
|
+
const apiUrl = getPensarApiUrl();
|
|
278928
279102
|
console.error(`[auth] apiUrl=${apiUrl}`);
|
|
278929
279103
|
try {
|
|
278930
279104
|
console.error(`[auth] fetching ${apiUrl}/api/cli/config`);
|
|
@@ -279194,7 +279368,7 @@ function AuthFlow({ onClose }) {
|
|
|
279194
279368
|
}
|
|
279195
279369
|
if (key.name === "return" && workspaces[selectedIndex]) {
|
|
279196
279370
|
const currentConfig = appConfig.data;
|
|
279197
|
-
const apiUrl = getPensarApiUrl(
|
|
279371
|
+
const apiUrl = getPensarApiUrl();
|
|
279198
279372
|
const accessToken = currentConfig.accessToken;
|
|
279199
279373
|
selectWorkspace(apiUrl, accessToken, workspaces[selectedIndex]);
|
|
279200
279374
|
}
|
|
@@ -279538,14 +279712,14 @@ function AuthFlow({ onClose }) {
|
|
|
279538
279712
|
}
|
|
279539
279713
|
|
|
279540
279714
|
// src/tui/components/commands/credits-flow.tsx
|
|
279541
|
-
var
|
|
279715
|
+
var import_react59 = __toESM(require_react(), 1);
|
|
279542
279716
|
init_tokenRefresh();
|
|
279543
279717
|
function CreditsFlow({ onOpenAuthDialog }) {
|
|
279544
279718
|
const route = useRoute();
|
|
279545
279719
|
const appConfig = useConfig();
|
|
279546
|
-
const [step, setStep] =
|
|
279547
|
-
const [credits, setCredits] =
|
|
279548
|
-
const [error40, setError] =
|
|
279720
|
+
const [step, setStep] = import_react59.useState("loading");
|
|
279721
|
+
const [credits, setCredits] = import_react59.useState(null);
|
|
279722
|
+
const [error40, setError] = import_react59.useState(null);
|
|
279549
279723
|
const creditsUrl = `${getPensarConsoleUrl()}/credits`;
|
|
279550
279724
|
const goHome = () => {
|
|
279551
279725
|
route.navigate({ type: "base", path: "home" });
|
|
@@ -279568,8 +279742,7 @@ function CreditsFlow({ onOpenAuthDialog }) {
|
|
|
279568
279742
|
const tokenResult = await ensureValidToken({
|
|
279569
279743
|
accessToken: appConfig.data.accessToken,
|
|
279570
279744
|
refreshToken: appConfig.data.refreshToken,
|
|
279571
|
-
pensarAPIKey: appConfig.data.pensarAPIKey
|
|
279572
|
-
pensarApiUrl: appConfig.data.pensarApiUrl
|
|
279745
|
+
pensarAPIKey: appConfig.data.pensarAPIKey
|
|
279573
279746
|
});
|
|
279574
279747
|
if (!tokenResult) {
|
|
279575
279748
|
setStep("no-auth");
|
|
@@ -279578,7 +279751,7 @@ function CreditsFlow({ onOpenAuthDialog }) {
|
|
|
279578
279751
|
setStep("loading");
|
|
279579
279752
|
setError(null);
|
|
279580
279753
|
try {
|
|
279581
|
-
const apiUrl = getPensarApiUrl(
|
|
279754
|
+
const apiUrl = getPensarApiUrl();
|
|
279582
279755
|
const headers = {
|
|
279583
279756
|
Authorization: `Bearer ${tokenResult.token}`
|
|
279584
279757
|
};
|
|
@@ -279603,7 +279776,7 @@ function CreditsFlow({ onOpenAuthDialog }) {
|
|
|
279603
279776
|
setStep("display");
|
|
279604
279777
|
}
|
|
279605
279778
|
};
|
|
279606
|
-
|
|
279779
|
+
import_react59.useEffect(() => {
|
|
279607
279780
|
fetchBalance();
|
|
279608
279781
|
}, []);
|
|
279609
279782
|
useKeyboard((key) => {
|
|
@@ -279842,10 +280015,10 @@ function CreditsFlow({ onOpenAuthDialog }) {
|
|
|
279842
280015
|
}
|
|
279843
280016
|
|
|
279844
280017
|
// src/tui/context/keybinding.tsx
|
|
279845
|
-
var
|
|
280018
|
+
var import_react65 = __toESM(require_react(), 1);
|
|
279846
280019
|
|
|
279847
280020
|
// src/tui/keybindings/keybind.tsx
|
|
279848
|
-
var
|
|
280021
|
+
var import_react61 = __toESM(require_react(), 1);
|
|
279849
280022
|
|
|
279850
280023
|
// src/tui/keybindings/actions.ts
|
|
279851
280024
|
var movementActions = [
|
|
@@ -280097,7 +280270,7 @@ var allActions = [
|
|
|
280097
280270
|
var actionsByKey = new Map(allActions.map((action) => [action.key, action]));
|
|
280098
280271
|
var actionsById = new Map(allActions.map((action) => [action.id, action]));
|
|
280099
280272
|
// src/tui/keybindings/keybind.tsx
|
|
280100
|
-
var LeaderKeyContext =
|
|
280273
|
+
var LeaderKeyContext = import_react61.createContext(null);
|
|
280101
280274
|
// src/tui/keybindings/registry.ts
|
|
280102
280275
|
function createKeybindings(deps) {
|
|
280103
280276
|
const {
|
|
@@ -280278,7 +280451,7 @@ function matchesKeybind(pressed, combo) {
|
|
|
280278
280451
|
}
|
|
280279
280452
|
|
|
280280
280453
|
// src/tui/context/keybinding.tsx
|
|
280281
|
-
var KeybindingContext =
|
|
280454
|
+
var KeybindingContext = import_react65.createContext(undefined);
|
|
280282
280455
|
function KeybindingProvider({
|
|
280283
280456
|
children,
|
|
280284
280457
|
deps
|
|
@@ -280318,121 +280491,12 @@ function KeybindingProvider({
|
|
|
280318
280491
|
}
|
|
280319
280492
|
|
|
280320
280493
|
// src/tui/components/pentest/pentest.tsx
|
|
280321
|
-
var
|
|
280494
|
+
var import_react73 = __toESM(require_react(), 1);
|
|
280322
280495
|
init_report();
|
|
280323
280496
|
import { existsSync as existsSync26, readdirSync as readdirSync6, readFileSync as readFileSync12 } from "fs";
|
|
280324
280497
|
import { join as join27 } from "path";
|
|
280325
280498
|
init_session();
|
|
280326
|
-
|
|
280327
|
-
// src/core/session/loader.ts
|
|
280328
|
-
init_persistence();
|
|
280329
|
-
init_report();
|
|
280330
|
-
import { join as join5 } from "path";
|
|
280331
|
-
import { existsSync as existsSync9, readFileSync as readFileSync4 } from "fs";
|
|
280332
|
-
function loadAttackSurfaceResults(rootPath) {
|
|
280333
|
-
const resultsPath = join5(rootPath, "attack-surface-results.json");
|
|
280334
|
-
if (!existsSync9(resultsPath)) {
|
|
280335
|
-
return null;
|
|
280336
|
-
}
|
|
280337
|
-
try {
|
|
280338
|
-
return JSON.parse(readFileSync4(resultsPath, "utf-8"));
|
|
280339
|
-
} catch (e) {
|
|
280340
|
-
console.error("Failed to load attack surface results:", e);
|
|
280341
|
-
return null;
|
|
280342
|
-
}
|
|
280343
|
-
}
|
|
280344
|
-
function hasReport(rootPath) {
|
|
280345
|
-
const reportPath = join5(rootPath, REPORT_FILENAME_MD);
|
|
280346
|
-
return existsSync9(reportPath);
|
|
280347
|
-
}
|
|
280348
|
-
function createDiscoveryFromLogs(rootPath, session) {
|
|
280349
|
-
const logPath = join5(rootPath, "logs", "streamlined-pentest.log");
|
|
280350
|
-
if (!existsSync9(logPath)) {
|
|
280351
|
-
return null;
|
|
280352
|
-
}
|
|
280353
|
-
try {
|
|
280354
|
-
const logContent = readFileSync4(logPath, "utf-8");
|
|
280355
|
-
const lines = logContent.split(`
|
|
280356
|
-
`).filter(Boolean);
|
|
280357
|
-
const messages = [];
|
|
280358
|
-
for (const line of lines) {
|
|
280359
|
-
const match = line.match(/^(\d{4}-\d{2}-\d{2}T[\d:.]+Z) - \[(\w+)\] (.+)$/);
|
|
280360
|
-
if (!match)
|
|
280361
|
-
continue;
|
|
280362
|
-
const [, timestamp, _level, content] = match;
|
|
280363
|
-
const createdAt = new Date(timestamp);
|
|
280364
|
-
if (content.startsWith("[Tool]")) {
|
|
280365
|
-
const toolMatch = content.match(/\[Tool\] (\w+): (.+)/);
|
|
280366
|
-
if (toolMatch) {
|
|
280367
|
-
messages.push({
|
|
280368
|
-
role: "tool",
|
|
280369
|
-
content: `✓ ${toolMatch[2]}`,
|
|
280370
|
-
createdAt,
|
|
280371
|
-
toolName: toolMatch[1],
|
|
280372
|
-
status: "completed"
|
|
280373
|
-
});
|
|
280374
|
-
}
|
|
280375
|
-
} else if (content.startsWith("[Step")) {
|
|
280376
|
-
const stepMatch = content.match(/\[Step \d+\] (.+)/);
|
|
280377
|
-
if (stepMatch) {
|
|
280378
|
-
messages.push({
|
|
280379
|
-
role: "assistant",
|
|
280380
|
-
content: stepMatch[1],
|
|
280381
|
-
createdAt
|
|
280382
|
-
});
|
|
280383
|
-
}
|
|
280384
|
-
}
|
|
280385
|
-
}
|
|
280386
|
-
if (messages.length === 0) {
|
|
280387
|
-
return null;
|
|
280388
|
-
}
|
|
280389
|
-
return {
|
|
280390
|
-
id: "discovery-from-logs",
|
|
280391
|
-
name: "Attack Surface Discovery",
|
|
280392
|
-
type: "attack-surface",
|
|
280393
|
-
target: session.targets[0] || "Unknown",
|
|
280394
|
-
messages,
|
|
280395
|
-
createdAt: new Date(session.time.created),
|
|
280396
|
-
status: "completed"
|
|
280397
|
-
};
|
|
280398
|
-
} catch (e) {
|
|
280399
|
-
console.error("Failed to parse logs:", e);
|
|
280400
|
-
return null;
|
|
280401
|
-
}
|
|
280402
|
-
}
|
|
280403
|
-
async function loadSessionState(session) {
|
|
280404
|
-
const rootPath = session.rootPath;
|
|
280405
|
-
let subagents = loadSubagents(rootPath);
|
|
280406
|
-
const hasAttackSurfaceAgent = subagents.some((s) => s.type === "attack-surface");
|
|
280407
|
-
if (!hasAttackSurfaceAgent) {
|
|
280408
|
-
const discoveryAgent = createDiscoveryFromLogs(rootPath, session);
|
|
280409
|
-
if (discoveryAgent) {
|
|
280410
|
-
subagents = [discoveryAgent, ...subagents];
|
|
280411
|
-
}
|
|
280412
|
-
}
|
|
280413
|
-
const attackSurfaceResults = loadAttackSurfaceResults(rootPath);
|
|
280414
|
-
const hasReportFile = hasReport(rootPath);
|
|
280415
|
-
const hasDiscoverySubagent = subagents.some((s) => s.type === "attack-surface");
|
|
280416
|
-
const interruptedDuringDiscovery = !attackSurfaceResults && !hasReportFile && hasDiscoverySubagent;
|
|
280417
|
-
if (interruptedDuringDiscovery) {
|
|
280418
|
-
for (let i = 0;i < subagents.length; i++) {
|
|
280419
|
-
if (subagents[i].type === "attack-surface" && subagents[i].status === "completed") {
|
|
280420
|
-
subagents[i] = { ...subagents[i], status: "paused" };
|
|
280421
|
-
}
|
|
280422
|
-
}
|
|
280423
|
-
}
|
|
280424
|
-
const pentestSubagents = subagents.filter((s) => s.type === "pentest");
|
|
280425
|
-
const allPentestDone = pentestSubagents.length > 0 && pentestSubagents.every((s) => s.status === "completed" || s.status === "failed");
|
|
280426
|
-
const isComplete = hasReportFile || attackSurfaceResults?.summary?.analysisComplete === true && allPentestDone;
|
|
280427
|
-
return {
|
|
280428
|
-
session,
|
|
280429
|
-
subagents,
|
|
280430
|
-
attackSurfaceResults,
|
|
280431
|
-
isComplete,
|
|
280432
|
-
hasReport: hasReportFile,
|
|
280433
|
-
interruptedDuringDiscovery
|
|
280434
|
-
};
|
|
280435
|
-
}
|
|
280499
|
+
init_loader();
|
|
280436
280500
|
|
|
280437
280501
|
// src/core/api/blackboxPentest.ts
|
|
280438
280502
|
init_pentest();
|
|
@@ -280459,7 +280523,7 @@ Found ${findings.length} vulnerabilities`);
|
|
|
280459
280523
|
init_utils();
|
|
280460
280524
|
|
|
280461
280525
|
// src/tui/components/agent-display.tsx
|
|
280462
|
-
var
|
|
280526
|
+
var import_react72 = __toESM(require_react(), 1);
|
|
280463
280527
|
|
|
280464
280528
|
// node_modules/marked/lib/marked.esm.js
|
|
280465
280529
|
function L2() {
|
|
@@ -282791,14 +282855,14 @@ ${preview}${suffix}` : preview + suffix || "POC passed",
|
|
|
282791
282855
|
return null;
|
|
282792
282856
|
}
|
|
282793
282857
|
// src/tui/components/shared/ascii-spinner.tsx
|
|
282794
|
-
var
|
|
282858
|
+
var import_react66 = __toESM(require_react(), 1);
|
|
282795
282859
|
var SPINNER_FRAMES = ["/", "-", "\\", "|"];
|
|
282796
282860
|
var SPINNER_INTERVAL = 100;
|
|
282797
282861
|
function AsciiSpinner({ label, fg: fg2 }) {
|
|
282798
282862
|
const { colors: colors2 } = useTheme();
|
|
282799
282863
|
const spinnerColor = fg2 ?? colors2.info;
|
|
282800
|
-
const [frame, setFrame] =
|
|
282801
|
-
|
|
282864
|
+
const [frame, setFrame] = import_react66.useState(0);
|
|
282865
|
+
import_react66.useEffect(() => {
|
|
282802
282866
|
const interval = setInterval(() => {
|
|
282803
282867
|
setFrame((f3) => (f3 + 1) % SPINNER_FRAMES.length);
|
|
282804
282868
|
}, SPINNER_INTERVAL);
|
|
@@ -282810,7 +282874,7 @@ function AsciiSpinner({ label, fg: fg2 }) {
|
|
|
282810
282874
|
}, undefined, false, undefined, this);
|
|
282811
282875
|
}
|
|
282812
282876
|
// src/tui/components/shared/tool-renderer.tsx
|
|
282813
|
-
var
|
|
282877
|
+
var import_react67 = __toESM(require_react(), 1);
|
|
282814
282878
|
var TOOLS_WITH_LOG_WINDOW = new Set([
|
|
282815
282879
|
"execute_command",
|
|
282816
282880
|
"run_attack_surface",
|
|
@@ -282823,13 +282887,13 @@ var TOOLS_WITH_LOG_WINDOW = new Set([
|
|
|
282823
282887
|
"document_vulnerability"
|
|
282824
282888
|
]);
|
|
282825
282889
|
var DEFAULT_SUBAGENT_LOG_LINES = 5;
|
|
282826
|
-
var ToolRenderer =
|
|
282890
|
+
var ToolRenderer = import_react67.memo(function ToolRenderer2({
|
|
282827
282891
|
message,
|
|
282828
282892
|
verbose = false,
|
|
282829
282893
|
expandedLogs = false
|
|
282830
282894
|
}) {
|
|
282831
282895
|
const { colors: colors2 } = useTheme();
|
|
282832
|
-
const [showOutput, setShowOutput] =
|
|
282896
|
+
const [showOutput, setShowOutput] = import_react67.useState(false);
|
|
282833
282897
|
if (!isToolMessage(message)) {
|
|
282834
282898
|
return null;
|
|
282835
282899
|
}
|
|
@@ -282969,7 +283033,7 @@ var ToolRenderer = import_react68.memo(function ToolRenderer2({
|
|
|
282969
283033
|
]
|
|
282970
283034
|
}, undefined, true, undefined, this);
|
|
282971
283035
|
});
|
|
282972
|
-
var SubagentLogWindow =
|
|
283036
|
+
var SubagentLogWindow = import_react67.memo(function SubagentLogWindow2({
|
|
282973
283037
|
subagentId,
|
|
282974
283038
|
entry,
|
|
282975
283039
|
expandedLogs
|
|
@@ -283026,8 +283090,8 @@ var SubagentLogWindow = import_react68.memo(function SubagentLogWindow2({
|
|
|
283026
283090
|
}, undefined, true, undefined, this);
|
|
283027
283091
|
});
|
|
283028
283092
|
// src/tui/components/shared/message-renderer.tsx
|
|
283029
|
-
var
|
|
283030
|
-
var MessageRenderer =
|
|
283093
|
+
var import_react68 = __toESM(require_react(), 1);
|
|
283094
|
+
var MessageRenderer = import_react68.memo(function MessageRenderer2({
|
|
283031
283095
|
message,
|
|
283032
283096
|
isStreaming = false,
|
|
283033
283097
|
verbose = false,
|
|
@@ -283037,7 +283101,7 @@ var MessageRenderer = import_react69.memo(function MessageRenderer2({
|
|
|
283037
283101
|
}) {
|
|
283038
283102
|
const { colors: colors2 } = useTheme();
|
|
283039
283103
|
const content = typeof message.content === "string" ? message.content : JSON.stringify(message.content);
|
|
283040
|
-
const displayContent =
|
|
283104
|
+
const displayContent = import_react68.useMemo(() => message.role === "assistant" ? markdownToStyledText(content, colors2) : content, [content, message.role, colors2]);
|
|
283041
283105
|
if (isToolMessage(message)) {
|
|
283042
283106
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ToolRenderer, {
|
|
283043
283107
|
message,
|
|
@@ -283149,9 +283213,9 @@ var MessageRenderer = import_react69.memo(function MessageRenderer2({
|
|
|
283149
283213
|
}, undefined, false, undefined, this);
|
|
283150
283214
|
});
|
|
283151
283215
|
// src/tui/components/shared/approval-prompt.tsx
|
|
283152
|
-
var
|
|
283216
|
+
var import_react69 = __toESM(require_react(), 1);
|
|
283153
283217
|
// src/tui/components/shared/message-reducer.ts
|
|
283154
|
-
var
|
|
283218
|
+
var import_react71 = __toESM(require_react(), 1);
|
|
283155
283219
|
// src/tui/components/agent-display.tsx
|
|
283156
283220
|
function getStableKey(item, contextId = "root") {
|
|
283157
283221
|
if ("messages" in item) {
|
|
@@ -283227,11 +283291,11 @@ function AgentDisplay({
|
|
|
283227
283291
|
]
|
|
283228
283292
|
}, undefined, true, undefined, this);
|
|
283229
283293
|
}
|
|
283230
|
-
var SubAgentDisplay =
|
|
283294
|
+
var SubAgentDisplay = import_react72.memo(function SubAgentDisplay2({
|
|
283231
283295
|
subagent
|
|
283232
283296
|
}) {
|
|
283233
283297
|
const { colors: colors2 } = useTheme();
|
|
283234
|
-
const [open, setOpen] =
|
|
283298
|
+
const [open, setOpen] = import_react72.useState(false);
|
|
283235
283299
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
283236
283300
|
height: open ? 40 : "auto",
|
|
283237
283301
|
onMouseDown: () => setOpen(!open),
|
|
@@ -283286,11 +283350,11 @@ var SubAgentDisplay = import_react73.memo(function SubAgentDisplay2({
|
|
|
283286
283350
|
]
|
|
283287
283351
|
}, undefined, true, undefined, this);
|
|
283288
283352
|
});
|
|
283289
|
-
var AgentMessage =
|
|
283353
|
+
var AgentMessage = import_react72.memo(function AgentMessage2({
|
|
283290
283354
|
message
|
|
283291
283355
|
}) {
|
|
283292
283356
|
const { colors: colors2 } = useTheme();
|
|
283293
|
-
const dimensions =
|
|
283357
|
+
const dimensions = useDimensions();
|
|
283294
283358
|
let content = "";
|
|
283295
283359
|
if (typeof message.content === "string") {
|
|
283296
283360
|
content = message.content;
|
|
@@ -283395,8 +283459,8 @@ var AgentMessage = import_react73.memo(function AgentMessage2({
|
|
|
283395
283459
|
});
|
|
283396
283460
|
function ToolDetails({ message }) {
|
|
283397
283461
|
const { colors: colors2 } = useTheme();
|
|
283398
|
-
const [showArgs, setShowArgs] =
|
|
283399
|
-
const [showResult, setShowResult] =
|
|
283462
|
+
const [showArgs, setShowArgs] = import_react72.useState(false);
|
|
283463
|
+
const [showResult, setShowResult] = import_react72.useState(false);
|
|
283400
283464
|
if (message.role !== "tool") {
|
|
283401
283465
|
return null;
|
|
283402
283466
|
}
|
|
@@ -283502,27 +283566,27 @@ function Pentest({
|
|
|
283502
283566
|
const config3 = useConfig();
|
|
283503
283567
|
const { model, setThinking, setIsExecuting, isExecuting } = useAgent();
|
|
283504
283568
|
const { stack, externalDialogOpen } = useDialog();
|
|
283505
|
-
const [session, setSession] =
|
|
283506
|
-
const [error40, setError] =
|
|
283507
|
-
const [phase, setPhase] =
|
|
283508
|
-
const [abortController, setAbortController] =
|
|
283509
|
-
const [panelMessages, setPanelMessages] =
|
|
283510
|
-
const panelTextRef =
|
|
283511
|
-
const panelSourceRef =
|
|
283512
|
-
const [pentestAgents, setPentestAgents] =
|
|
283513
|
-
const pentestTextRefs =
|
|
283514
|
-
const [assets, setAssets] =
|
|
283515
|
-
const [viewMode, setViewMode] =
|
|
283516
|
-
const [selectedAgentId, setSelectedAgentId] =
|
|
283517
|
-
const [focusedIndex, setFocusedIndex] =
|
|
283518
|
-
const [showOrchestratorPanel, setShowOrchestratorPanel] =
|
|
283519
|
-
const [startTime, setStartTime] =
|
|
283520
|
-
const pentestAgentList =
|
|
283521
|
-
const selectedAgent =
|
|
283522
|
-
const { width: termWidth } =
|
|
283569
|
+
const [session, setSession] = import_react73.useState(null);
|
|
283570
|
+
const [error40, setError] = import_react73.useState(null);
|
|
283571
|
+
const [phase, setPhase] = import_react73.useState("loading");
|
|
283572
|
+
const [abortController, setAbortController] = import_react73.useState(null);
|
|
283573
|
+
const [panelMessages, setPanelMessages] = import_react73.useState([]);
|
|
283574
|
+
const panelTextRef = import_react73.useRef("");
|
|
283575
|
+
const panelSourceRef = import_react73.useRef(null);
|
|
283576
|
+
const [pentestAgents, setPentestAgents] = import_react73.useState({});
|
|
283577
|
+
const pentestTextRefs = import_react73.useRef({});
|
|
283578
|
+
const [assets, setAssets] = import_react73.useState([]);
|
|
283579
|
+
const [viewMode, setViewMode] = import_react73.useState("overview");
|
|
283580
|
+
const [selectedAgentId, setSelectedAgentId] = import_react73.useState(null);
|
|
283581
|
+
const [focusedIndex, setFocusedIndex] = import_react73.useState(0);
|
|
283582
|
+
const [showOrchestratorPanel, setShowOrchestratorPanel] = import_react73.useState(false);
|
|
283583
|
+
const [startTime, setStartTime] = import_react73.useState(null);
|
|
283584
|
+
const pentestAgentList = import_react73.useMemo(() => Object.values(pentestAgents).sort((a, b3) => a.createdAt.getTime() - b3.createdAt.getTime()), [pentestAgents]);
|
|
283585
|
+
const selectedAgent = import_react73.useMemo(() => selectedAgentId ? pentestAgents[selectedAgentId] ?? null : null, [pentestAgents, selectedAgentId]);
|
|
283586
|
+
const { width: termWidth } = useDimensions();
|
|
283523
283587
|
const gridAvailableWidth = showOrchestratorPanel ? Math.floor((termWidth - 4) / 2) - 2 : termWidth - ORCHESTRATOR_PANEL_WIDTH - GRID_OUTER_PADDING;
|
|
283524
283588
|
const gridColumns = Math.max(1, Math.floor((gridAvailableWidth + GRID_GAP) / (CARD_MIN_WIDTH + GRID_GAP)));
|
|
283525
|
-
|
|
283589
|
+
import_react73.useEffect(() => {
|
|
283526
283590
|
async function load2() {
|
|
283527
283591
|
try {
|
|
283528
283592
|
let s2;
|
|
@@ -283568,6 +283632,9 @@ function Pentest({
|
|
|
283568
283632
|
if (attackSurfaceAgents.some((sa) => sa.messages.length > 0)) {
|
|
283569
283633
|
setShowOrchestratorPanel(true);
|
|
283570
283634
|
}
|
|
283635
|
+
if (state.attackSurfaceResults?.summary?.analysisComplete) {
|
|
283636
|
+
setPhase("pentesting");
|
|
283637
|
+
}
|
|
283571
283638
|
startPentest(s2);
|
|
283572
283639
|
}
|
|
283573
283640
|
} else {
|
|
@@ -283580,7 +283647,7 @@ function Pentest({
|
|
|
283580
283647
|
}
|
|
283581
283648
|
load2();
|
|
283582
283649
|
}, [sessionId]);
|
|
283583
|
-
|
|
283650
|
+
import_react73.useEffect(() => {
|
|
283584
283651
|
if (!session)
|
|
283585
283652
|
return;
|
|
283586
283653
|
const assetsPath = join27(session.rootPath, "assets");
|
|
@@ -283603,12 +283670,12 @@ function Pentest({
|
|
|
283603
283670
|
const interval = setInterval(readAssets, 2000);
|
|
283604
283671
|
return () => clearInterval(interval);
|
|
283605
283672
|
}, [session]);
|
|
283606
|
-
|
|
283673
|
+
import_react73.useEffect(() => {
|
|
283607
283674
|
return () => {
|
|
283608
283675
|
abortController?.abort();
|
|
283609
283676
|
};
|
|
283610
283677
|
}, [abortController]);
|
|
283611
|
-
const ensurePentestAgent =
|
|
283678
|
+
const ensurePentestAgent = import_react73.useCallback((subagentId) => {
|
|
283612
283679
|
setPentestAgents((prev) => {
|
|
283613
283680
|
if (prev[subagentId])
|
|
283614
283681
|
return prev;
|
|
@@ -283625,7 +283692,7 @@ function Pentest({
|
|
|
283625
283692
|
};
|
|
283626
283693
|
});
|
|
283627
283694
|
}, []);
|
|
283628
|
-
const handleSubagentSpawn =
|
|
283695
|
+
const handleSubagentSpawn = import_react73.useCallback(({
|
|
283629
283696
|
subagentId,
|
|
283630
283697
|
input
|
|
283631
283698
|
}) => {
|
|
@@ -283645,7 +283712,7 @@ function Pentest({
|
|
|
283645
283712
|
}
|
|
283646
283713
|
}));
|
|
283647
283714
|
}, []);
|
|
283648
|
-
const handleSubagentComplete =
|
|
283715
|
+
const handleSubagentComplete = import_react73.useCallback(({ subagentId, status }) => {
|
|
283649
283716
|
if (!subagentId.startsWith("pentest-agent-"))
|
|
283650
283717
|
return;
|
|
283651
283718
|
setPentestAgents((prev) => {
|
|
@@ -283658,7 +283725,7 @@ function Pentest({
|
|
|
283658
283725
|
};
|
|
283659
283726
|
});
|
|
283660
283727
|
}, []);
|
|
283661
|
-
const appendPanelText =
|
|
283728
|
+
const appendPanelText = import_react73.useCallback((source, text2) => {
|
|
283662
283729
|
if (panelSourceRef.current !== source) {
|
|
283663
283730
|
panelTextRef.current = "";
|
|
283664
283731
|
panelSourceRef.current = source;
|
|
@@ -283683,7 +283750,7 @@ function Pentest({
|
|
|
283683
283750
|
];
|
|
283684
283751
|
});
|
|
283685
283752
|
}, []);
|
|
283686
|
-
const appendPentestText =
|
|
283753
|
+
const appendPentestText = import_react73.useCallback((subagentId, text2) => {
|
|
283687
283754
|
ensurePentestAgent(subagentId);
|
|
283688
283755
|
if (!pentestTextRefs.current[subagentId]) {
|
|
283689
283756
|
pentestTextRefs.current[subagentId] = "";
|
|
@@ -283716,8 +283783,8 @@ function Pentest({
|
|
|
283716
283783
|
};
|
|
283717
283784
|
});
|
|
283718
283785
|
}, [ensurePentestAgent]);
|
|
283719
|
-
const toolArgsDeltaRef =
|
|
283720
|
-
const addPanelStreamingToolCall =
|
|
283786
|
+
const toolArgsDeltaRef = import_react73.useRef(new Map);
|
|
283787
|
+
const addPanelStreamingToolCall = import_react73.useCallback((toolCallId, toolName) => {
|
|
283721
283788
|
panelTextRef.current = "";
|
|
283722
283789
|
panelSourceRef.current = null;
|
|
283723
283790
|
toolArgsDeltaRef.current.set(toolCallId, "");
|
|
@@ -283736,7 +283803,7 @@ function Pentest({
|
|
|
283736
283803
|
return [...prev, msg];
|
|
283737
283804
|
});
|
|
283738
283805
|
}, []);
|
|
283739
|
-
const appendPanelToolCallDelta =
|
|
283806
|
+
const appendPanelToolCallDelta = import_react73.useCallback((toolCallId, argsTextDelta) => {
|
|
283740
283807
|
const prev = toolArgsDeltaRef.current.get(toolCallId) ?? "";
|
|
283741
283808
|
const accumulated = prev + argsTextDelta;
|
|
283742
283809
|
toolArgsDeltaRef.current.set(toolCallId, accumulated);
|
|
@@ -283759,7 +283826,7 @@ function Pentest({
|
|
|
283759
283826
|
return updated;
|
|
283760
283827
|
});
|
|
283761
283828
|
}, []);
|
|
283762
|
-
const addPanelToolCall =
|
|
283829
|
+
const addPanelToolCall = import_react73.useCallback((toolCallId, toolName, args) => {
|
|
283763
283830
|
panelTextRef.current = "";
|
|
283764
283831
|
panelSourceRef.current = null;
|
|
283765
283832
|
toolArgsDeltaRef.current.delete(toolCallId);
|
|
@@ -283791,7 +283858,7 @@ function Pentest({
|
|
|
283791
283858
|
];
|
|
283792
283859
|
});
|
|
283793
283860
|
}, []);
|
|
283794
|
-
const addPentestStreamingToolCall =
|
|
283861
|
+
const addPentestStreamingToolCall = import_react73.useCallback((subagentId, toolCallId, toolName) => {
|
|
283795
283862
|
pentestTextRefs.current[subagentId] = "";
|
|
283796
283863
|
ensurePentestAgent(subagentId);
|
|
283797
283864
|
toolArgsDeltaRef.current.set(toolCallId, "");
|
|
@@ -283816,7 +283883,7 @@ function Pentest({
|
|
|
283816
283883
|
};
|
|
283817
283884
|
});
|
|
283818
283885
|
}, [ensurePentestAgent]);
|
|
283819
|
-
const appendPentestToolCallDelta =
|
|
283886
|
+
const appendPentestToolCallDelta = import_react73.useCallback((subagentId, toolCallId, argsTextDelta) => {
|
|
283820
283887
|
const prev = toolArgsDeltaRef.current.get(toolCallId) ?? "";
|
|
283821
283888
|
const accumulated = prev + argsTextDelta;
|
|
283822
283889
|
toolArgsDeltaRef.current.set(toolCallId, accumulated);
|
|
@@ -283842,7 +283909,7 @@ function Pentest({
|
|
|
283842
283909
|
return { ...agents, [subagentId]: { ...agent, messages: updatedMsgs } };
|
|
283843
283910
|
});
|
|
283844
283911
|
}, []);
|
|
283845
|
-
const addPentestToolCall =
|
|
283912
|
+
const addPentestToolCall = import_react73.useCallback((subagentId, toolCallId, toolName, args) => {
|
|
283846
283913
|
pentestTextRefs.current[subagentId] = "";
|
|
283847
283914
|
ensurePentestAgent(subagentId);
|
|
283848
283915
|
toolArgsDeltaRef.current.delete(toolCallId);
|
|
@@ -283903,12 +283970,12 @@ function Pentest({
|
|
|
283903
283970
|
}
|
|
283904
283971
|
];
|
|
283905
283972
|
};
|
|
283906
|
-
const updatePanelToolResult =
|
|
283973
|
+
const updatePanelToolResult = import_react73.useCallback((toolCallId, toolName, result) => {
|
|
283907
283974
|
panelTextRef.current = "";
|
|
283908
283975
|
panelSourceRef.current = null;
|
|
283909
283976
|
setPanelMessages((prev) => toolResultUpdater(prev, toolCallId, toolName, result));
|
|
283910
283977
|
}, []);
|
|
283911
|
-
const updatePentestToolResult =
|
|
283978
|
+
const updatePentestToolResult = import_react73.useCallback((subagentId, toolCallId, toolName, result) => {
|
|
283912
283979
|
pentestTextRefs.current[subagentId] = "";
|
|
283913
283980
|
setPentestAgents((prev) => {
|
|
283914
283981
|
const agent = prev[subagentId];
|
|
@@ -283923,11 +283990,12 @@ function Pentest({
|
|
|
283923
283990
|
};
|
|
283924
283991
|
});
|
|
283925
283992
|
}, []);
|
|
283926
|
-
const startPentest =
|
|
283927
|
-
setPhase("discovery");
|
|
283993
|
+
const startPentest = import_react73.useCallback(async (s2) => {
|
|
283994
|
+
setPhase((prev) => prev === "pentesting" || prev === "reporting" ? prev : "discovery");
|
|
283928
283995
|
setStartTime(new Date);
|
|
283929
283996
|
setIsExecuting(true);
|
|
283930
|
-
|
|
283997
|
+
const discoveryDone = existsSync26(join27(s2.rootPath, "attack-surface-results.json"));
|
|
283998
|
+
setThinking(!discoveryDone);
|
|
283931
283999
|
const controller = new AbortController;
|
|
283932
284000
|
setAbortController(controller);
|
|
283933
284001
|
try {
|
|
@@ -284050,7 +284118,7 @@ function Pentest({
|
|
|
284050
284118
|
handleSubagentSpawn,
|
|
284051
284119
|
handleSubagentComplete
|
|
284052
284120
|
]);
|
|
284053
|
-
|
|
284121
|
+
import_react73.useEffect(() => {
|
|
284054
284122
|
if (phase === "completed") {
|
|
284055
284123
|
setFocusedIndex(pentestAgentList.length);
|
|
284056
284124
|
}
|
|
@@ -284113,7 +284181,7 @@ function Pentest({
|
|
|
284113
284181
|
}
|
|
284114
284182
|
}
|
|
284115
284183
|
});
|
|
284116
|
-
const openReport =
|
|
284184
|
+
const openReport = import_react73.useCallback(() => {
|
|
284117
284185
|
if (!session)
|
|
284118
284186
|
return;
|
|
284119
284187
|
const err = openSessionReport(session.rootPath);
|
|
@@ -284298,7 +284366,7 @@ function OrchestratorPanel({
|
|
|
284298
284366
|
}) {
|
|
284299
284367
|
const { colors: colors2 } = useTheme();
|
|
284300
284368
|
const isRunning = phase !== "loading" && phase !== "completed" && phase !== "error";
|
|
284301
|
-
const assetSummary =
|
|
284369
|
+
const assetSummary = import_react73.useMemo(() => {
|
|
284302
284370
|
const byType = {};
|
|
284303
284371
|
for (const a of assets) {
|
|
284304
284372
|
const key = a.assetType;
|
|
@@ -284541,13 +284609,13 @@ function AgentCardGrid({
|
|
|
284541
284609
|
onSelectAgent
|
|
284542
284610
|
}) {
|
|
284543
284611
|
const { colors: colors2 } = useTheme();
|
|
284544
|
-
const scrollRef =
|
|
284545
|
-
|
|
284612
|
+
const scrollRef = import_react73.useRef(null);
|
|
284613
|
+
import_react73.useEffect(() => {
|
|
284546
284614
|
const agent = agents[focusedIndex];
|
|
284547
284615
|
if (agent)
|
|
284548
284616
|
scrollToChild(scrollRef.current, agent.id);
|
|
284549
284617
|
}, [focusedIndex, agents]);
|
|
284550
|
-
const rows =
|
|
284618
|
+
const rows = import_react73.useMemo(() => {
|
|
284551
284619
|
const result = [];
|
|
284552
284620
|
for (let i2 = 0;i2 < agents.length; i2 += gridColumns) {
|
|
284553
284621
|
result.push(agents.slice(i2, i2 + gridColumns));
|
|
@@ -284604,14 +284672,14 @@ function AgentCard({
|
|
|
284604
284672
|
completed: colors2.primary,
|
|
284605
284673
|
failed: colors2.error
|
|
284606
284674
|
}[agent.status];
|
|
284607
|
-
const lastActivity =
|
|
284675
|
+
const lastActivity = import_react73.useMemo(() => {
|
|
284608
284676
|
const last = agent.messages[agent.messages.length - 1];
|
|
284609
284677
|
if (!last)
|
|
284610
284678
|
return "Starting...";
|
|
284611
284679
|
const text2 = typeof last.content === "string" ? last.content.replace(/\n/g, " ").trim() : "Working...";
|
|
284612
284680
|
return text2.length > 50 ? text2.substring(0, 47) + "..." : text2;
|
|
284613
284681
|
}, [agent.messages]);
|
|
284614
|
-
const toolCalls =
|
|
284682
|
+
const toolCalls = import_react73.useMemo(() => agent.messages.filter((m4) => m4.role === "tool").length, [agent.messages]);
|
|
284615
284683
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
284616
284684
|
id: agent.id,
|
|
284617
284685
|
flexGrow: 1,
|
|
@@ -284799,8 +284867,8 @@ function MetricsBar({
|
|
|
284799
284867
|
isExecuting
|
|
284800
284868
|
}) {
|
|
284801
284869
|
const { colors: colors2 } = useTheme();
|
|
284802
|
-
const [now2, setNow] =
|
|
284803
|
-
|
|
284870
|
+
const [now2, setNow] = import_react73.useState(Date.now());
|
|
284871
|
+
import_react73.useEffect(() => {
|
|
284804
284872
|
if (!isExecuting)
|
|
284805
284873
|
return;
|
|
284806
284874
|
const interval = setInterval(() => setNow(Date.now()), 1000);
|
|
@@ -284943,7 +285011,7 @@ function MetricsBar({
|
|
|
284943
285011
|
}
|
|
284944
285012
|
|
|
284945
285013
|
// src/tui/components/operator-dashboard/index.tsx
|
|
284946
|
-
var
|
|
285014
|
+
var import_react78 = __toESM(require_react(), 1);
|
|
284947
285015
|
init_session();
|
|
284948
285016
|
|
|
284949
285017
|
// src/core/api/offesecAgent.ts
|
|
@@ -285046,7 +285114,7 @@ function InlineApprovalPrompt2({ approval }) {
|
|
|
285046
285114
|
}
|
|
285047
285115
|
|
|
285048
285116
|
// src/tui/components/chat/loading-indicator.tsx
|
|
285049
|
-
var
|
|
285117
|
+
var import_react75 = __toESM(require_react(), 1);
|
|
285050
285118
|
var SPINNER_FRAMES2 = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
285051
285119
|
var SPINNER_INTERVAL2 = 80;
|
|
285052
285120
|
var DOTS_FRAMES = ["", ".", "..", "..."];
|
|
@@ -285057,15 +285125,15 @@ function LoadingIndicator({
|
|
|
285057
285125
|
toolName
|
|
285058
285126
|
}) {
|
|
285059
285127
|
const { colors: colors2 } = useTheme();
|
|
285060
|
-
const [spinnerFrame, setSpinnerFrame] =
|
|
285061
|
-
const [dotsFrame, setDotsFrame] =
|
|
285062
|
-
|
|
285128
|
+
const [spinnerFrame, setSpinnerFrame] = import_react75.useState(0);
|
|
285129
|
+
const [dotsFrame, setDotsFrame] = import_react75.useState(0);
|
|
285130
|
+
import_react75.useEffect(() => {
|
|
285063
285131
|
const interval = setInterval(() => {
|
|
285064
285132
|
setSpinnerFrame((f3) => (f3 + 1) % SPINNER_FRAMES2.length);
|
|
285065
285133
|
}, SPINNER_INTERVAL2);
|
|
285066
285134
|
return () => clearInterval(interval);
|
|
285067
285135
|
}, []);
|
|
285068
|
-
|
|
285136
|
+
import_react75.useEffect(() => {
|
|
285069
285137
|
const interval = setInterval(() => {
|
|
285070
285138
|
setDotsFrame((f3) => (f3 + 1) % DOTS_FRAMES.length);
|
|
285071
285139
|
}, DOTS_INTERVAL);
|
|
@@ -285319,7 +285387,7 @@ function MessageList({
|
|
|
285319
285387
|
}
|
|
285320
285388
|
|
|
285321
285389
|
// src/tui/components/chat/input-area.tsx
|
|
285322
|
-
var
|
|
285390
|
+
var import_react76 = __toESM(require_react(), 1);
|
|
285323
285391
|
function NormalInputAreaInner({
|
|
285324
285392
|
value,
|
|
285325
285393
|
onChange,
|
|
@@ -285341,10 +285409,10 @@ function NormalInputAreaInner({
|
|
|
285341
285409
|
}) {
|
|
285342
285410
|
const { colors: colors2, theme, mode: colorMode } = useTheme();
|
|
285343
285411
|
const { inputValue, setInputValue } = useInput();
|
|
285344
|
-
const promptRef =
|
|
285345
|
-
const isExternalUpdate =
|
|
285346
|
-
const prevValueRef =
|
|
285347
|
-
|
|
285412
|
+
const promptRef = import_react76.useRef(null);
|
|
285413
|
+
const isExternalUpdate = import_react76.useRef(false);
|
|
285414
|
+
const prevValueRef = import_react76.useRef(value);
|
|
285415
|
+
import_react76.useEffect(() => {
|
|
285348
285416
|
const prevValue = prevValueRef.current;
|
|
285349
285417
|
prevValueRef.current = value;
|
|
285350
285418
|
if (value !== prevValue && value !== inputValue) {
|
|
@@ -285353,7 +285421,7 @@ function NormalInputAreaInner({
|
|
|
285353
285421
|
promptRef.current?.setValue(value);
|
|
285354
285422
|
}
|
|
285355
285423
|
}, [value, inputValue, setInputValue]);
|
|
285356
|
-
|
|
285424
|
+
import_react76.useEffect(() => {
|
|
285357
285425
|
if (isExternalUpdate.current) {
|
|
285358
285426
|
isExternalUpdate.current = false;
|
|
285359
285427
|
return;
|
|
@@ -285528,7 +285596,7 @@ function ApprovalInputArea2({
|
|
|
285528
285596
|
lastDeclineNote
|
|
285529
285597
|
}) {
|
|
285530
285598
|
const { colors: colors2 } = useTheme();
|
|
285531
|
-
const [focusedElement, setFocusedElement] =
|
|
285599
|
+
const [focusedElement, setFocusedElement] = import_react76.useState(0);
|
|
285532
285600
|
useKeyboard((key) => {
|
|
285533
285601
|
if (key.name === "up") {
|
|
285534
285602
|
setFocusedElement((prev) => Math.max(0, prev - 1));
|
|
@@ -285855,29 +285923,29 @@ function OperatorDashboard({
|
|
|
285855
285923
|
clear: clearDialog,
|
|
285856
285924
|
setSize: setDialogSize
|
|
285857
285925
|
} = useDialog();
|
|
285858
|
-
const autocompleteOptions =
|
|
285926
|
+
const autocompleteOptions = import_react78.useMemo(() => {
|
|
285859
285927
|
const skillSlugs = new Set(skills.map((s2) => `/${slugify(s2.name)}`));
|
|
285860
285928
|
return filterOperatorAutocomplete(allAutocompleteOptions, skillSlugs);
|
|
285861
285929
|
}, [allAutocompleteOptions, skills]);
|
|
285862
|
-
const [session, setSession] =
|
|
285863
|
-
const [loading, setLoading] =
|
|
285864
|
-
const [error40, setError] =
|
|
285865
|
-
const pendingNameRef =
|
|
285866
|
-
const [status, setStatus] =
|
|
285867
|
-
const abortControllerRef =
|
|
285868
|
-
const generationRef =
|
|
285869
|
-
const cancelHandleRef =
|
|
285930
|
+
const [session, setSession] = import_react78.useState(null);
|
|
285931
|
+
const [loading, setLoading] = import_react78.useState(true);
|
|
285932
|
+
const [error40, setError] = import_react78.useState(null);
|
|
285933
|
+
const pendingNameRef = import_react78.useRef(null);
|
|
285934
|
+
const [status, setStatus] = import_react78.useState("idle");
|
|
285935
|
+
const abortControllerRef = import_react78.useRef(null);
|
|
285936
|
+
const generationRef = import_react78.useRef(0);
|
|
285937
|
+
const cancelHandleRef = import_react78.useRef({
|
|
285870
285938
|
cancel: () => false
|
|
285871
285939
|
});
|
|
285872
|
-
const commandCancelledRef =
|
|
285873
|
-
const [messages, setMessages] =
|
|
285874
|
-
const textRef =
|
|
285875
|
-
const conversationRef =
|
|
285876
|
-
const [inputValue, setInputValue] =
|
|
285877
|
-
const [queuedMessages, setQueuedMessages] =
|
|
285878
|
-
const [selectedQueueIndex, setSelectedQueueIndex] =
|
|
285879
|
-
const queuedMessagesRef =
|
|
285880
|
-
|
|
285940
|
+
const commandCancelledRef = import_react78.useRef(false);
|
|
285941
|
+
const [messages, setMessages] = import_react78.useState([]);
|
|
285942
|
+
const textRef = import_react78.useRef("");
|
|
285943
|
+
const conversationRef = import_react78.useRef([]);
|
|
285944
|
+
const [inputValue, setInputValue] = import_react78.useState("");
|
|
285945
|
+
const [queuedMessages, setQueuedMessages] = import_react78.useState([]);
|
|
285946
|
+
const [selectedQueueIndex, setSelectedQueueIndex] = import_react78.useState(-1);
|
|
285947
|
+
const queuedMessagesRef = import_react78.useRef([]);
|
|
285948
|
+
import_react78.useEffect(() => {
|
|
285881
285949
|
queuedMessagesRef.current = queuedMessages;
|
|
285882
285950
|
if (queuedMessages.length === 0) {
|
|
285883
285951
|
setSelectedQueueIndex(-1);
|
|
@@ -285885,17 +285953,17 @@ function OperatorDashboard({
|
|
|
285885
285953
|
setSelectedQueueIndex(queuedMessages.length - 1);
|
|
285886
285954
|
}
|
|
285887
285955
|
}, [queuedMessages, selectedQueueIndex]);
|
|
285888
|
-
const [operatorState, setOperatorState] =
|
|
285889
|
-
const approvalGateRef =
|
|
285890
|
-
const [pendingApprovals, setPendingApprovals] =
|
|
285891
|
-
const [lastApprovedAction, setLastApprovedAction] =
|
|
285892
|
-
const [verboseMode, setVerboseMode] =
|
|
285893
|
-
const [expandedLogs, setExpandedLogs] =
|
|
285894
|
-
const tokenUsageRef =
|
|
285895
|
-
|
|
285956
|
+
const [operatorState, setOperatorState] = import_react78.useState(() => createInitialOperatorState("manual", true));
|
|
285957
|
+
const approvalGateRef = import_react78.useRef(new ApprovalGate({ requireApproval: true }));
|
|
285958
|
+
const [pendingApprovals, setPendingApprovals] = import_react78.useState([]);
|
|
285959
|
+
const [lastApprovedAction, setLastApprovedAction] = import_react78.useState(null);
|
|
285960
|
+
const [verboseMode, setVerboseMode] = import_react78.useState(false);
|
|
285961
|
+
const [expandedLogs, setExpandedLogs] = import_react78.useState(false);
|
|
285962
|
+
const tokenUsageRef = import_react78.useRef(tokenUsage);
|
|
285963
|
+
import_react78.useEffect(() => {
|
|
285896
285964
|
tokenUsageRef.current = tokenUsage;
|
|
285897
285965
|
}, [tokenUsage]);
|
|
285898
|
-
|
|
285966
|
+
import_react78.useEffect(() => {
|
|
285899
285967
|
const gate = approvalGateRef.current;
|
|
285900
285968
|
const onApprovalNeeded = () => {
|
|
285901
285969
|
setPendingApprovals(gate.getPendingApprovals());
|
|
@@ -285917,7 +285985,7 @@ function OperatorDashboard({
|
|
|
285917
285985
|
gate.off("approval-resolved", onApprovalResolved);
|
|
285918
285986
|
};
|
|
285919
285987
|
}, []);
|
|
285920
|
-
|
|
285988
|
+
import_react78.useEffect(() => {
|
|
285921
285989
|
async function loadSession() {
|
|
285922
285990
|
try {
|
|
285923
285991
|
if (sessionId) {
|
|
@@ -285974,10 +286042,10 @@ function OperatorDashboard({
|
|
|
285974
286042
|
}
|
|
285975
286043
|
loadSession();
|
|
285976
286044
|
}, [sessionId]);
|
|
285977
|
-
|
|
286045
|
+
import_react78.useEffect(() => {
|
|
285978
286046
|
return () => setSessionCwd(null);
|
|
285979
286047
|
}, [setSessionCwd]);
|
|
285980
|
-
|
|
286048
|
+
import_react78.useEffect(() => {
|
|
285981
286049
|
if (!session)
|
|
285982
286050
|
return;
|
|
285983
286051
|
resetTokenUsage();
|
|
@@ -285995,7 +286063,7 @@ function OperatorDashboard({
|
|
|
285995
286063
|
});
|
|
285996
286064
|
} catch {}
|
|
285997
286065
|
}, [session, addTokenUsage, resetTokenUsage]);
|
|
285998
|
-
const appendText =
|
|
286066
|
+
const appendText = import_react78.useCallback((text2) => {
|
|
285999
286067
|
textRef.current += text2;
|
|
286000
286068
|
const accumulated = textRef.current;
|
|
286001
286069
|
setMessages((prev) => {
|
|
@@ -286011,8 +286079,8 @@ function OperatorDashboard({
|
|
|
286011
286079
|
];
|
|
286012
286080
|
});
|
|
286013
286081
|
}, []);
|
|
286014
|
-
const toolArgsDeltaRef =
|
|
286015
|
-
const addStreamingToolCall =
|
|
286082
|
+
const toolArgsDeltaRef = import_react78.useRef(new Map);
|
|
286083
|
+
const addStreamingToolCall = import_react78.useCallback((toolCallId, toolName) => {
|
|
286016
286084
|
textRef.current = "";
|
|
286017
286085
|
toolArgsDeltaRef.current.set(toolCallId, {
|
|
286018
286086
|
toolName,
|
|
@@ -286031,7 +286099,7 @@ function OperatorDashboard({
|
|
|
286031
286099
|
}
|
|
286032
286100
|
]);
|
|
286033
286101
|
}, []);
|
|
286034
|
-
const appendToolCallDelta =
|
|
286102
|
+
const appendToolCallDelta = import_react78.useCallback((toolCallId, argsTextDelta) => {
|
|
286035
286103
|
const entry = toolArgsDeltaRef.current.get(toolCallId);
|
|
286036
286104
|
const accumulated = (entry?.accumulated ?? "") + argsTextDelta;
|
|
286037
286105
|
toolArgsDeltaRef.current.set(toolCallId, {
|
|
@@ -286053,7 +286121,7 @@ function OperatorDashboard({
|
|
|
286053
286121
|
return updated;
|
|
286054
286122
|
});
|
|
286055
286123
|
}, []);
|
|
286056
|
-
const addToolCall =
|
|
286124
|
+
const addToolCall = import_react78.useCallback((toolCallId, toolName, args) => {
|
|
286057
286125
|
textRef.current = "";
|
|
286058
286126
|
toolArgsDeltaRef.current.delete(toolCallId);
|
|
286059
286127
|
setMessages((prev) => {
|
|
@@ -286082,7 +286150,7 @@ function OperatorDashboard({
|
|
|
286082
286150
|
];
|
|
286083
286151
|
});
|
|
286084
286152
|
}, []);
|
|
286085
|
-
const updateToolResult =
|
|
286153
|
+
const updateToolResult = import_react78.useCallback((toolCallId, _toolName, result) => {
|
|
286086
286154
|
textRef.current = "";
|
|
286087
286155
|
setMessages((prev) => {
|
|
286088
286156
|
const idx = prev.findIndex((m4) => isToolMessage(m4) && m4.toolCallId === toolCallId);
|
|
@@ -286093,10 +286161,10 @@ function OperatorDashboard({
|
|
|
286093
286161
|
return updated;
|
|
286094
286162
|
});
|
|
286095
286163
|
}, []);
|
|
286096
|
-
const cmdOutputBufRef =
|
|
286097
|
-
const cmdFlushTimerRef =
|
|
286164
|
+
const cmdOutputBufRef = import_react78.useRef("");
|
|
286165
|
+
const cmdFlushTimerRef = import_react78.useRef(null);
|
|
286098
286166
|
const MAX_LOG_LINES = 200;
|
|
286099
|
-
const flushCommandOutput =
|
|
286167
|
+
const flushCommandOutput = import_react78.useCallback(() => {
|
|
286100
286168
|
const buf = cmdOutputBufRef.current;
|
|
286101
286169
|
if (!buf)
|
|
286102
286170
|
return;
|
|
@@ -286126,7 +286194,7 @@ function OperatorDashboard({
|
|
|
286126
286194
|
return updated;
|
|
286127
286195
|
});
|
|
286128
286196
|
}, []);
|
|
286129
|
-
const onCommandOutput =
|
|
286197
|
+
const onCommandOutput = import_react78.useCallback((data) => {
|
|
286130
286198
|
cmdOutputBufRef.current += data;
|
|
286131
286199
|
if (!cmdFlushTimerRef.current) {
|
|
286132
286200
|
cmdFlushTimerRef.current = setInterval(() => {
|
|
@@ -286134,7 +286202,7 @@ function OperatorDashboard({
|
|
|
286134
286202
|
}, 150);
|
|
286135
286203
|
}
|
|
286136
286204
|
}, [flushCommandOutput]);
|
|
286137
|
-
|
|
286205
|
+
import_react78.useEffect(() => {
|
|
286138
286206
|
return () => {
|
|
286139
286207
|
if (cmdFlushTimerRef.current) {
|
|
286140
286208
|
clearInterval(cmdFlushTimerRef.current);
|
|
@@ -286142,7 +286210,7 @@ function OperatorDashboard({
|
|
|
286142
286210
|
}
|
|
286143
286211
|
};
|
|
286144
286212
|
}, []);
|
|
286145
|
-
const appendLogToActiveTool =
|
|
286213
|
+
const appendLogToActiveTool = import_react78.useCallback((line) => {
|
|
286146
286214
|
setMessages((prev) => {
|
|
286147
286215
|
const idx = prev.findLastIndex((m4) => isToolMessage(m4) && (m4.status === "pending" || m4.status === "streaming"));
|
|
286148
286216
|
if (idx === -1)
|
|
@@ -286157,7 +286225,7 @@ function OperatorDashboard({
|
|
|
286157
286225
|
return updated;
|
|
286158
286226
|
});
|
|
286159
286227
|
}, []);
|
|
286160
|
-
const initSubagent =
|
|
286228
|
+
const initSubagent = import_react78.useCallback((subagentId, name26) => {
|
|
286161
286229
|
setMessages((prev) => {
|
|
286162
286230
|
const idx = prev.findLastIndex((m4) => isToolMessage(m4) && (m4.status === "pending" || m4.status === "streaming"));
|
|
286163
286231
|
if (idx === -1)
|
|
@@ -286172,7 +286240,7 @@ function OperatorDashboard({
|
|
|
286172
286240
|
return updated;
|
|
286173
286241
|
});
|
|
286174
286242
|
}, []);
|
|
286175
|
-
const completeSubagent =
|
|
286243
|
+
const completeSubagent = import_react78.useCallback((subagentId, status2) => {
|
|
286176
286244
|
setMessages((prev) => {
|
|
286177
286245
|
const idx = prev.findLastIndex((m4) => isToolMessage(m4) && (m4.status === "pending" || m4.status === "streaming"));
|
|
286178
286246
|
if (idx === -1)
|
|
@@ -286190,7 +286258,7 @@ function OperatorDashboard({
|
|
|
286190
286258
|
return updated;
|
|
286191
286259
|
});
|
|
286192
286260
|
}, []);
|
|
286193
|
-
const appendLogToSubagent =
|
|
286261
|
+
const appendLogToSubagent = import_react78.useCallback((subagentId, line) => {
|
|
286194
286262
|
setMessages((prev) => {
|
|
286195
286263
|
const idx = prev.findLastIndex((m4) => isToolMessage(m4) && (m4.status === "pending" || m4.status === "streaming"));
|
|
286196
286264
|
if (idx === -1)
|
|
@@ -286212,13 +286280,13 @@ function OperatorDashboard({
|
|
|
286212
286280
|
return updated;
|
|
286213
286281
|
});
|
|
286214
286282
|
}, []);
|
|
286215
|
-
const handleApprove =
|
|
286283
|
+
const handleApprove = import_react78.useCallback(() => {
|
|
286216
286284
|
const pending = approvalGateRef.current.getPendingApprovals();
|
|
286217
286285
|
if (pending.length > 0) {
|
|
286218
286286
|
approvalGateRef.current.approve(pending[0].id);
|
|
286219
286287
|
}
|
|
286220
286288
|
}, []);
|
|
286221
|
-
const handleAutoApprove =
|
|
286289
|
+
const handleAutoApprove = import_react78.useCallback(() => {
|
|
286222
286290
|
approvalGateRef.current.updateConfig({ requireApproval: false });
|
|
286223
286291
|
setOperatorState((prev) => ({ ...prev, requireApproval: false }));
|
|
286224
286292
|
const pending = approvalGateRef.current.getPendingApprovals();
|
|
@@ -286226,7 +286294,7 @@ function OperatorDashboard({
|
|
|
286226
286294
|
approvalGateRef.current.approve(p.id);
|
|
286227
286295
|
}
|
|
286228
286296
|
}, []);
|
|
286229
|
-
const runAgent =
|
|
286297
|
+
const runAgent = import_react78.useCallback(async (prompt) => {
|
|
286230
286298
|
if (abortControllerRef.current) {
|
|
286231
286299
|
abortControllerRef.current.abort();
|
|
286232
286300
|
abortControllerRef.current = null;
|
|
@@ -286440,7 +286508,7 @@ function OperatorDashboard({
|
|
|
286440
286508
|
setThinking,
|
|
286441
286509
|
setIsExecuting
|
|
286442
286510
|
]);
|
|
286443
|
-
const handleSubmit =
|
|
286511
|
+
const handleSubmit = import_react78.useCallback((value) => {
|
|
286444
286512
|
const pending = approvalGateRef.current.getPendingApprovals();
|
|
286445
286513
|
const result = resolveSubmit(value, status, pending.length > 0);
|
|
286446
286514
|
if (result.denyPending) {
|
|
@@ -286458,16 +286526,16 @@ function OperatorDashboard({
|
|
|
286458
286526
|
setInputValue("");
|
|
286459
286527
|
runAgent(result.prompt);
|
|
286460
286528
|
}, [status, runAgent]);
|
|
286461
|
-
const initialMessageSentRef =
|
|
286462
|
-
const runAgentRef =
|
|
286529
|
+
const initialMessageSentRef = import_react78.useRef(false);
|
|
286530
|
+
const runAgentRef = import_react78.useRef(runAgent);
|
|
286463
286531
|
runAgentRef.current = runAgent;
|
|
286464
|
-
|
|
286532
|
+
import_react78.useEffect(() => {
|
|
286465
286533
|
if (!loading && initialMessage && !initialMessageSentRef.current) {
|
|
286466
286534
|
initialMessageSentRef.current = true;
|
|
286467
286535
|
runAgentRef.current(initialMessage);
|
|
286468
286536
|
}
|
|
286469
286537
|
}, [loading, initialMessage]);
|
|
286470
|
-
|
|
286538
|
+
import_react78.useEffect(() => {
|
|
286471
286539
|
if (status !== "idle")
|
|
286472
286540
|
return;
|
|
286473
286541
|
const queue = queuedMessagesRef.current;
|
|
@@ -286478,7 +286546,7 @@ function OperatorDashboard({
|
|
|
286478
286546
|
setSelectedQueueIndex(-1);
|
|
286479
286547
|
runAgentRef.current(next);
|
|
286480
286548
|
}, [status]);
|
|
286481
|
-
const showModelPicker =
|
|
286549
|
+
const showModelPicker = import_react78.useCallback(() => {
|
|
286482
286550
|
setDialogSize("large");
|
|
286483
286551
|
showDialog(/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
286484
286552
|
flexDirection: "column",
|
|
@@ -286540,7 +286608,7 @@ function OperatorDashboard({
|
|
|
286540
286608
|
clearDialog,
|
|
286541
286609
|
setDialogSize
|
|
286542
286610
|
]);
|
|
286543
|
-
const handleCommandExecute =
|
|
286611
|
+
const handleCommandExecute = import_react78.useCallback(async (command) => {
|
|
286544
286612
|
const action = routeCommand(command, resolveSkillContent);
|
|
286545
286613
|
switch (action.type) {
|
|
286546
286614
|
case "show-models":
|
|
@@ -286558,7 +286626,7 @@ function OperatorDashboard({
|
|
|
286558
286626
|
return;
|
|
286559
286627
|
}
|
|
286560
286628
|
}, [resolveSkillContent, handleSubmit, executeCommand2, showModelPicker]);
|
|
286561
|
-
const handleAbort =
|
|
286629
|
+
const handleAbort = import_react78.useCallback(() => {
|
|
286562
286630
|
if (!abortControllerRef.current)
|
|
286563
286631
|
return;
|
|
286564
286632
|
const action = resolveAbortAction(commandCancelledRef.current, () => cancelHandleRef.current.cancel());
|
|
@@ -286608,7 +286676,7 @@ function OperatorDashboard({
|
|
|
286608
286676
|
];
|
|
286609
286677
|
});
|
|
286610
286678
|
}, [session, setThinking, setIsExecuting]);
|
|
286611
|
-
const toggleApproval =
|
|
286679
|
+
const toggleApproval = import_react78.useCallback(() => {
|
|
286612
286680
|
setOperatorState((prev) => {
|
|
286613
286681
|
const newVal = !prev.requireApproval;
|
|
286614
286682
|
approvalGateRef.current.updateConfig({ requireApproval: newVal });
|
|
@@ -286842,10 +286910,10 @@ function OperatorDashboard({
|
|
|
286842
286910
|
}
|
|
286843
286911
|
|
|
286844
286912
|
// src/tui/components/commands/theme-picker.tsx
|
|
286845
|
-
var
|
|
286913
|
+
var import_react80 = __toESM(require_react(), 1);
|
|
286846
286914
|
init_config2();
|
|
286847
286915
|
function ThemePicker({ onClose }) {
|
|
286848
|
-
const dimensions =
|
|
286916
|
+
const dimensions = useDimensions();
|
|
286849
286917
|
const {
|
|
286850
286918
|
colors: colors2,
|
|
286851
286919
|
theme,
|
|
@@ -286855,15 +286923,15 @@ function ThemePicker({ onClose }) {
|
|
|
286855
286923
|
toggleMode,
|
|
286856
286924
|
setMode
|
|
286857
286925
|
} = useTheme();
|
|
286858
|
-
const [selectedIndex, setSelectedIndex] =
|
|
286859
|
-
const originalThemeRef =
|
|
286860
|
-
const originalModeRef =
|
|
286861
|
-
const handleClose =
|
|
286926
|
+
const [selectedIndex, setSelectedIndex] = import_react80.useState(() => Math.max(0, availableThemes.indexOf(theme.name)));
|
|
286927
|
+
const originalThemeRef = import_react80.useRef(theme.name);
|
|
286928
|
+
const originalModeRef = import_react80.useRef(mode);
|
|
286929
|
+
const handleClose = import_react80.useCallback(() => {
|
|
286862
286930
|
setTheme(originalThemeRef.current);
|
|
286863
286931
|
setMode(originalModeRef.current);
|
|
286864
286932
|
onClose();
|
|
286865
286933
|
}, [setTheme, setMode, onClose]);
|
|
286866
|
-
const handleConfirm =
|
|
286934
|
+
const handleConfirm = import_react80.useCallback(async () => {
|
|
286867
286935
|
const currentThemeName = availableThemes[selectedIndex];
|
|
286868
286936
|
if (currentThemeName) {
|
|
286869
286937
|
await config2.update({ theme: currentThemeName });
|
|
@@ -286992,16 +287060,16 @@ function ThemePicker({ onClose }) {
|
|
|
286992
287060
|
}
|
|
286993
287061
|
|
|
286994
287062
|
// src/tui/components/commands/create-skill-wizard.tsx
|
|
286995
|
-
var
|
|
287063
|
+
var import_react82 = __toESM(require_react(), 1);
|
|
286996
287064
|
function CreateSkillWizard() {
|
|
286997
287065
|
const { colors: colors2 } = useTheme();
|
|
286998
287066
|
const route = useRoute();
|
|
286999
|
-
const [step, setStep] =
|
|
287000
|
-
const [name26, setName] =
|
|
287001
|
-
const [description, setDescription] =
|
|
287002
|
-
const [content, setContent] =
|
|
287003
|
-
const [error40, setError] =
|
|
287004
|
-
const [confirmFocused, setConfirmFocused] =
|
|
287067
|
+
const [step, setStep] = import_react82.useState("name");
|
|
287068
|
+
const [name26, setName] = import_react82.useState("");
|
|
287069
|
+
const [description, setDescription] = import_react82.useState("");
|
|
287070
|
+
const [content, setContent] = import_react82.useState("");
|
|
287071
|
+
const [error40, setError] = import_react82.useState(null);
|
|
287072
|
+
const [confirmFocused, setConfirmFocused] = import_react82.useState(0);
|
|
287005
287073
|
const slug = slugify(name26);
|
|
287006
287074
|
async function handleSave() {
|
|
287007
287075
|
if (!name26.trim() || !content.trim())
|
|
@@ -289877,7 +289945,7 @@ async function detectTerminalMode(timeoutMs = 1000) {
|
|
|
289877
289945
|
}
|
|
289878
289946
|
|
|
289879
289947
|
// src/tui/console-theme.ts
|
|
289880
|
-
var
|
|
289948
|
+
var import_react84 = __toESM(require_react(), 1);
|
|
289881
289949
|
var withAlpha = (rgba, a) => RGBA.fromValues(rgba.r, rgba.g, rgba.b, a);
|
|
289882
289950
|
var overlayThemeRef = {
|
|
289883
289951
|
current: null
|
|
@@ -289900,7 +289968,7 @@ function buildConsoleOptions(themeColors) {
|
|
|
289900
289968
|
function ConsoleThemeSync() {
|
|
289901
289969
|
const { colors: colors2 } = useTheme();
|
|
289902
289970
|
const renderer = useRenderer();
|
|
289903
|
-
|
|
289971
|
+
import_react84.useEffect(() => {
|
|
289904
289972
|
overlayThemeRef.current = colors2;
|
|
289905
289973
|
const c = renderer.console;
|
|
289906
289974
|
c.backgroundColor = withAlpha(colors2.backgroundPanel, 0.85);
|
|
@@ -289988,17 +290056,17 @@ function setupAutoCopy(renderer, copyToClipboard) {
|
|
|
289988
290056
|
|
|
289989
290057
|
// src/tui/index.tsx
|
|
289990
290058
|
function App({ appConfig }) {
|
|
289991
|
-
const [focusIndex, setFocusIndex] =
|
|
289992
|
-
const [cwd, setCwd] =
|
|
289993
|
-
const [ctrlCPressTime, setCtrlCPressTime] =
|
|
289994
|
-
const [showExitWarning, setShowExitWarning] =
|
|
289995
|
-
const [inputKey, setInputKey] =
|
|
289996
|
-
const [showSessionsDialog, setShowSessionsDialog] =
|
|
289997
|
-
const [showShortcutsDialog, setShowShortcutsDialog] =
|
|
289998
|
-
const [showThemeDialog, setShowThemeDialog] =
|
|
289999
|
-
const [showAuthDialog, setShowAuthDialog] =
|
|
290000
|
-
const [showPentestDialog, setShowPentestDialog] =
|
|
290001
|
-
const [pendingPentestFlags, setPendingPentestFlags] =
|
|
290059
|
+
const [focusIndex, setFocusIndex] = import_react87.useState(0);
|
|
290060
|
+
const [cwd, setCwd] = import_react87.useState(process.cwd());
|
|
290061
|
+
const [ctrlCPressTime, setCtrlCPressTime] = import_react87.useState(null);
|
|
290062
|
+
const [showExitWarning, setShowExitWarning] = import_react87.useState(false);
|
|
290063
|
+
const [inputKey, setInputKey] = import_react87.useState(0);
|
|
290064
|
+
const [showSessionsDialog, setShowSessionsDialog] = import_react87.useState(false);
|
|
290065
|
+
const [showShortcutsDialog, setShowShortcutsDialog] = import_react87.useState(false);
|
|
290066
|
+
const [showThemeDialog, setShowThemeDialog] = import_react87.useState(false);
|
|
290067
|
+
const [showAuthDialog, setShowAuthDialog] = import_react87.useState(false);
|
|
290068
|
+
const [showPentestDialog, setShowPentestDialog] = import_react87.useState(false);
|
|
290069
|
+
const [pendingPentestFlags, setPendingPentestFlags] = import_react87.useState(undefined);
|
|
290002
290070
|
const navigableItems = ["command-input"];
|
|
290003
290071
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ConfigProvider, {
|
|
290004
290072
|
config: appConfig,
|
|
@@ -290085,14 +290153,14 @@ function AppContent({
|
|
|
290085
290153
|
const { toast } = useToast();
|
|
290086
290154
|
const { refocusPrompt } = useFocus();
|
|
290087
290155
|
const { setExternalDialogOpen } = useDialog();
|
|
290088
|
-
|
|
290156
|
+
import_react87.useEffect(() => {
|
|
290089
290157
|
checkForUpdate().then(({ updateAvailable, currentVersion, latestVersion }) => {
|
|
290090
290158
|
if (!updateAvailable)
|
|
290091
290159
|
return;
|
|
290092
290160
|
toast(`Update available: v${currentVersion} → v${latestVersion}. Run: pensar upgrade`, "warn", 8000);
|
|
290093
290161
|
});
|
|
290094
290162
|
}, []);
|
|
290095
|
-
|
|
290163
|
+
import_react87.useEffect(() => {
|
|
290096
290164
|
if (route.data.type !== "base")
|
|
290097
290165
|
return;
|
|
290098
290166
|
if (!config3.data.responsibleUseAccepted && route.data.path !== "disclosure") {
|
|
@@ -290101,12 +290169,12 @@ function AppContent({
|
|
|
290101
290169
|
route.navigate({ type: "base", path: "providers" });
|
|
290102
290170
|
}
|
|
290103
290171
|
}, [config3.data.responsibleUseAccepted, route.data]);
|
|
290104
|
-
|
|
290172
|
+
import_react87.useEffect(() => {
|
|
290105
290173
|
if (showThemeDialog || showAuthDialog || showPentestDialog) {
|
|
290106
290174
|
setExternalDialogOpen(true);
|
|
290107
290175
|
}
|
|
290108
290176
|
}, [showThemeDialog, showAuthDialog, showPentestDialog]);
|
|
290109
|
-
|
|
290177
|
+
import_react87.useEffect(() => {
|
|
290110
290178
|
if (showExitWarning) {
|
|
290111
290179
|
const timer = setTimeout(() => {
|
|
290112
290180
|
setShowExitWarning(false);
|
|
@@ -290360,16 +290428,18 @@ async function main2() {
|
|
|
290360
290428
|
initialMode: mode,
|
|
290361
290429
|
children: [
|
|
290362
290430
|
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ConsoleThemeSync, {}, undefined, false, undefined, this),
|
|
290363
|
-
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(
|
|
290364
|
-
children:
|
|
290365
|
-
|
|
290366
|
-
|
|
290367
|
-
|
|
290368
|
-
|
|
290369
|
-
|
|
290370
|
-
|
|
290371
|
-
|
|
290372
|
-
|
|
290431
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(TerminalDimensionsProvider, {
|
|
290432
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ToastProvider, {
|
|
290433
|
+
children: [
|
|
290434
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ErrorBoundary2, {
|
|
290435
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(App, {
|
|
290436
|
+
appConfig
|
|
290437
|
+
}, undefined, false, undefined, this)
|
|
290438
|
+
}, undefined, false, undefined, this),
|
|
290439
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ToastContainer, {}, undefined, false, undefined, this)
|
|
290440
|
+
]
|
|
290441
|
+
}, undefined, true, undefined, this)
|
|
290442
|
+
}, undefined, false, undefined, this)
|
|
290373
290443
|
]
|
|
290374
290444
|
}, undefined, true, undefined, this));
|
|
290375
290445
|
}
|