@pensar/apex 0.0.91 → 0.0.92-canary.139adb8c

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.
Files changed (2) hide show
  1. package/build/index.js +582 -508
  2. 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.91",
31974
+ version: "0.0.92-canary.139adb8c",
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",
@@ -89526,44 +89526,22 @@ import {
89526
89526
  readdirSync as readdirSync2
89527
89527
  } from "fs";
89528
89528
  import { join as join4 } from "path";
89529
- function mapToSavedMessage(msg) {
89530
- const m2 = msg;
89531
- if (typeof m2.content === "string") {
89532
- return { role: m2.role, content: m2.content };
89533
- }
89534
- if (Array.isArray(m2.content)) {
89535
- const mapped = m2.content.map((part) => {
89536
- if (part.type === "tool-call") {
89537
- return {
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 };
89529
+ function loadSubagentMessages(session, agentName) {
89530
+ const filePath = join4(session.rootPath, SUBAGENTS_DIR, `${agentName}.json`);
89531
+ if (!existsSync8(filePath))
89532
+ return [];
89533
+ try {
89534
+ const data = JSON.parse(readFileSync3(filePath, "utf-8"));
89535
+ return data.messages;
89536
+ } catch {
89537
+ return [];
89558
89538
  }
89559
- return { role: m2.role, content: String(m2.content) };
89560
89539
  }
89561
89540
  function saveSubagentData(session, data) {
89562
89541
  const subagentsDir = join4(session.rootPath, SUBAGENTS_DIR);
89563
89542
  mkdirSync2(subagentsDir, { recursive: true });
89564
89543
  let toolCallCount = 0;
89565
89544
  let stepCount = 0;
89566
- const savedMessages = [];
89567
89545
  for (const msg of data.messages) {
89568
89546
  if (msg.role === "assistant") {
89569
89547
  stepCount++;
@@ -89574,12 +89552,10 @@ function saveSubagentData(session, data) {
89574
89552
  }
89575
89553
  }
89576
89554
  }
89577
- savedMessages.push(mapToSavedMessage(msg));
89578
89555
  }
89579
- const now2 = new Date;
89580
89556
  const savedData = {
89581
89557
  agentName: data.agentName,
89582
- timestamp: now2.toISOString(),
89558
+ timestamp: new Date().toISOString(),
89583
89559
  target: data.target,
89584
89560
  objective: data.objective,
89585
89561
  vulnerabilityClass: data.vulnerabilityClass,
@@ -89588,16 +89564,24 @@ function saveSubagentData(session, data) {
89588
89564
  findingsCount: data.findingsCount ?? 0,
89589
89565
  status: data.status,
89590
89566
  error: data.error,
89591
- messages: savedMessages
89567
+ messages: data.messages
89592
89568
  };
89593
- const ts = now2.toISOString().replace(/[:.]/g, "-");
89594
- const filename = `${data.agentName}-${ts}.json`;
89595
- writeFileSync2(join4(subagentsDir, filename), JSON.stringify(savedData, null, 2));
89569
+ writeFileSync2(join4(subagentsDir, `${data.agentName}.json`), JSON.stringify(savedData, null, 2));
89596
89570
  }
89597
89571
  function writeAgentManifest(session, entries2) {
89598
89572
  const manifestPath = join4(session.rootPath, MANIFEST_FILE);
89599
89573
  writeFileSync2(manifestPath, JSON.stringify(entries2, null, 2));
89600
89574
  }
89575
+ function readAgentManifest(session) {
89576
+ const manifestPath = join4(session.rootPath, MANIFEST_FILE);
89577
+ if (!existsSync8(manifestPath))
89578
+ return [];
89579
+ try {
89580
+ return JSON.parse(readFileSync3(manifestPath, "utf-8"));
89581
+ } catch {
89582
+ return [];
89583
+ }
89584
+ }
89601
89585
  function buildManifestEntries(targets) {
89602
89586
  return targets.map((t2, i) => ({
89603
89587
  id: `pentest-agent-${i + 1}`,
@@ -89610,18 +89594,31 @@ function buildManifestEntries(targets) {
89610
89594
  }));
89611
89595
  }
89612
89596
  function finalizeManifest(session, entries2, results) {
89613
- const finalManifest = entries2.map((entry, i) => ({
89614
- ...entry,
89615
- status: results[i] != null ? "completed" : "failed",
89616
- completedAt: new Date().toISOString()
89617
- }));
89597
+ const finalManifest = entries2.map((entry, i) => {
89598
+ if (entry.status === "completed")
89599
+ return entry;
89600
+ return {
89601
+ ...entry,
89602
+ status: results[i] != null ? "completed" : "failed",
89603
+ completedAt: new Date().toISOString()
89604
+ };
89605
+ });
89618
89606
  writeAgentManifest(session, finalManifest);
89619
89607
  }
89608
+ function updateManifestEntryStatus(session, agentId, status) {
89609
+ const manifest = readAgentManifest(session);
89610
+ const updated = manifest.map((e) => e.id === agentId ? { ...e, status, completedAt: new Date().toISOString() } : e);
89611
+ writeAgentManifest(session, updated);
89612
+ }
89613
+ function getCompletedAgentIds(session) {
89614
+ const manifest = readAgentManifest(session);
89615
+ return new Set(manifest.filter((e) => e.id.startsWith("pentest-agent-") && e.status === "completed").map((e) => e.id));
89616
+ }
89620
89617
  function parseSubagentFilename(filename) {
89621
89618
  if (filename.startsWith("attack-surface-agent")) {
89622
89619
  return { agentType: "attack-surface", name: "Attack Surface Discovery" };
89623
89620
  }
89624
- const pentestMatch = filename.match(/^pentest-agent-(\d+)-/);
89621
+ const pentestMatch = filename.match(/^pentest-agent-(\d+)/);
89625
89622
  if (pentestMatch) {
89626
89623
  return {
89627
89624
  agentType: "pentest",
@@ -89673,7 +89670,8 @@ function convertMessagesToUI(messages, baseTime) {
89673
89670
  createdAt
89674
89671
  });
89675
89672
  } else if (part.type === "tool-call") {
89676
- const toolDescription = typeof part.input?.toolCallDescription === "string" ? part.input.toolCallDescription : part.toolName || "tool";
89673
+ const input = part.input;
89674
+ const toolDescription = typeof input?.toolCallDescription === "string" ? input.toolCallDescription : part.toolName || "tool";
89677
89675
  const result = part.toolCallId ? toolResults.get(part.toolCallId) : undefined;
89678
89676
  uiMessages.push({
89679
89677
  role: "tool",
@@ -89681,7 +89679,7 @@ function convertMessagesToUI(messages, baseTime) {
89681
89679
  createdAt,
89682
89680
  toolCallId: part.toolCallId,
89683
89681
  toolName: part.toolName,
89684
- args: part.input,
89682
+ args: input,
89685
89683
  result,
89686
89684
  status: "completed"
89687
89685
  });
@@ -89692,8 +89690,7 @@ function convertMessagesToUI(messages, baseTime) {
89692
89690
  return uiMessages;
89693
89691
  }
89694
89692
  function convertModelMessagesToUI(messages) {
89695
- const saved = messages.map((m2) => mapToSavedMessage(m2));
89696
- return convertMessagesToUI(saved, new Date);
89693
+ return convertMessagesToUI(messages, new Date);
89697
89694
  }
89698
89695
  function loadSubagents(rootPath) {
89699
89696
  const subagentsPath = join4(rootPath, SUBAGENTS_DIR);
@@ -89701,11 +89698,7 @@ function loadSubagents(rootPath) {
89701
89698
  const agentNameIndex = new Map;
89702
89699
  if (existsSync8(subagentsPath)) {
89703
89700
  const files = readdirSync2(subagentsPath).filter((f) => f.endsWith(".json"));
89704
- files.sort((a, b2) => {
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
- });
89701
+ files.sort();
89709
89702
  for (const file2 of files) {
89710
89703
  if (file2.startsWith("orchestrator-"))
89711
89704
  continue;
@@ -89729,9 +89722,9 @@ function loadSubagents(rootPath) {
89729
89722
  }
89730
89723
  break;
89731
89724
  }
89732
- const idx = subagents.length;
89725
+ agentNameIndex.set(data.agentName, subagents.length);
89733
89726
  subagents.push({
89734
- id: `loaded-${file2.replace(".json", "")}`,
89727
+ id: data.agentName,
89735
89728
  name: data.agentName === "attack-surface-agent" ? "Attack Surface Discovery" : name26,
89736
89729
  type: agentType,
89737
89730
  target: data.target || "Unknown",
@@ -89739,7 +89732,6 @@ function loadSubagents(rootPath) {
89739
89732
  createdAt: timestamp,
89740
89733
  status
89741
89734
  });
89742
- agentNameIndex.set(data.agentName, idx);
89743
89735
  } catch (e) {
89744
89736
  console.error(`Failed to load subagent file ${file2}:`, e);
89745
89737
  }
@@ -89787,6 +89779,116 @@ function loadSubagents(rootPath) {
89787
89779
  var SUBAGENTS_DIR = "subagents", MANIFEST_FILE = "agent-manifest.json";
89788
89780
  var init_persistence = () => {};
89789
89781
 
89782
+ // src/core/session/loader.ts
89783
+ import { join as join5 } from "path";
89784
+ import { existsSync as existsSync9, readFileSync as readFileSync4 } from "fs";
89785
+ function loadAttackSurfaceResults(rootPath) {
89786
+ const resultsPath = join5(rootPath, "attack-surface-results.json");
89787
+ if (!existsSync9(resultsPath)) {
89788
+ return null;
89789
+ }
89790
+ try {
89791
+ return JSON.parse(readFileSync4(resultsPath, "utf-8"));
89792
+ } catch (e) {
89793
+ console.error("Failed to load attack surface results:", e);
89794
+ return null;
89795
+ }
89796
+ }
89797
+ function hasReport(rootPath) {
89798
+ const reportPath = join5(rootPath, REPORT_FILENAME_MD);
89799
+ return existsSync9(reportPath);
89800
+ }
89801
+ function createDiscoveryFromLogs(rootPath, session) {
89802
+ const logPath = join5(rootPath, "logs", "streamlined-pentest.log");
89803
+ if (!existsSync9(logPath)) {
89804
+ return null;
89805
+ }
89806
+ try {
89807
+ const logContent = readFileSync4(logPath, "utf-8");
89808
+ const lines = logContent.split(`
89809
+ `).filter(Boolean);
89810
+ const messages = [];
89811
+ for (const line of lines) {
89812
+ const match = line.match(/^(\d{4}-\d{2}-\d{2}T[\d:.]+Z) - \[(\w+)\] (.+)$/);
89813
+ if (!match)
89814
+ continue;
89815
+ const [, timestamp, _level, content] = match;
89816
+ const createdAt = new Date(timestamp);
89817
+ if (content.startsWith("[Tool]")) {
89818
+ const toolMatch = content.match(/\[Tool\] (\w+): (.+)/);
89819
+ if (toolMatch) {
89820
+ messages.push({
89821
+ role: "tool",
89822
+ content: `✓ ${toolMatch[2]}`,
89823
+ createdAt,
89824
+ toolName: toolMatch[1],
89825
+ status: "completed"
89826
+ });
89827
+ }
89828
+ } else if (content.startsWith("[Step")) {
89829
+ const stepMatch = content.match(/\[Step \d+\] (.+)/);
89830
+ if (stepMatch) {
89831
+ messages.push({
89832
+ role: "assistant",
89833
+ content: stepMatch[1],
89834
+ createdAt
89835
+ });
89836
+ }
89837
+ }
89838
+ }
89839
+ if (messages.length === 0) {
89840
+ return null;
89841
+ }
89842
+ return {
89843
+ id: "discovery-from-logs",
89844
+ name: "Attack Surface Discovery",
89845
+ type: "attack-surface",
89846
+ target: session.targets[0] || "Unknown",
89847
+ messages,
89848
+ createdAt: new Date(session.time.created),
89849
+ status: "completed"
89850
+ };
89851
+ } catch (e) {
89852
+ console.error("Failed to parse logs:", e);
89853
+ return null;
89854
+ }
89855
+ }
89856
+ async function loadSessionState(session) {
89857
+ const rootPath = session.rootPath;
89858
+ let subagents = loadSubagents(rootPath);
89859
+ const hasAttackSurfaceAgent = subagents.some((s) => s.type === "attack-surface");
89860
+ if (!hasAttackSurfaceAgent) {
89861
+ const discoveryAgent = createDiscoveryFromLogs(rootPath, session);
89862
+ if (discoveryAgent) {
89863
+ subagents = [discoveryAgent, ...subagents];
89864
+ }
89865
+ }
89866
+ const attackSurfaceResults = loadAttackSurfaceResults(rootPath);
89867
+ const hasReportFile = hasReport(rootPath);
89868
+ const hasDiscoverySubagent = subagents.some((s) => s.type === "attack-surface");
89869
+ const interruptedDuringDiscovery = !attackSurfaceResults && !hasReportFile && hasDiscoverySubagent;
89870
+ if (interruptedDuringDiscovery) {
89871
+ for (let i = 0;i < subagents.length; i++) {
89872
+ if (subagents[i].type === "attack-surface" && subagents[i].status === "completed") {
89873
+ subagents[i] = { ...subagents[i], status: "paused" };
89874
+ }
89875
+ }
89876
+ }
89877
+ const isComplete = hasReportFile;
89878
+ return {
89879
+ session,
89880
+ subagents,
89881
+ attackSurfaceResults,
89882
+ isComplete,
89883
+ hasReport: hasReportFile,
89884
+ interruptedDuringDiscovery
89885
+ };
89886
+ }
89887
+ var init_loader = __esm(() => {
89888
+ init_persistence();
89889
+ init_report();
89890
+ });
89891
+
89790
89892
  // src/core/agents/specialized/attackSurface/prompts.ts
89791
89893
  var SYSTEM = `You are an autonomous attack surface analysis agent. Your mission is to comprehensively map the attack surface of a target and produce a structured report of all discovered assets and pentest objectives.
89792
89894
 
@@ -105652,9 +105754,10 @@ class PlaywrightMcpSession {
105652
105754
  }
105653
105755
  function createBrowserTools(targetUrl, evidenceDir, mode = "pentest", logger, abortSignal, headless) {
105654
105756
  const session = new PlaywrightMcpSession(headless ?? defaultHeadless);
105655
- abortSignal?.addEventListener("abort", () => {
105656
- session.disconnect().catch(() => {});
105657
- });
105757
+ if (abortSignal) {
105758
+ const onAbort = () => session.disconnect().catch(() => {});
105759
+ abortSignal.addEventListener("abort", onAbort, { once: true });
105760
+ }
105658
105761
  if (!existsSync11(evidenceDir)) {
105659
105762
  mkdirSync3(evidenceDir, { recursive: true });
105660
105763
  }
@@ -108517,9 +108620,17 @@ function runScript(runner, scriptPath, timeout, abortSignal) {
108517
108620
  let stderr = "";
108518
108621
  let killed = false;
108519
108622
  let resolved = false;
108623
+ let abortCleanup;
108624
+ if (abortSignal) {
108625
+ const handler = () => killProcess();
108626
+ abortSignal.addEventListener("abort", handler, { once: true });
108627
+ abortCleanup = () => abortSignal.removeEventListener("abort", handler);
108628
+ }
108520
108629
  const safeResolve = (result) => {
108521
108630
  if (!resolved) {
108522
108631
  resolved = true;
108632
+ clearTimeout(timeoutTimer);
108633
+ abortCleanup?.();
108523
108634
  resolve4(result);
108524
108635
  }
108525
108636
  };
@@ -108553,18 +108664,11 @@ function runScript(runner, scriptPath, timeout, abortSignal) {
108553
108664
  stderr += data.toString();
108554
108665
  });
108555
108666
  child.on("close", (code) => {
108556
- clearTimeout(timeoutTimer);
108557
108667
  safeResolve({ stdout, stderr, exitCode: code ?? 1 });
108558
108668
  });
108559
108669
  child.on("error", (err) => {
108560
- clearTimeout(timeoutTimer);
108561
108670
  safeResolve({ stdout, stderr, exitCode: 1 });
108562
108671
  });
108563
- if (abortSignal) {
108564
- const handler = () => killProcess();
108565
- abortSignal.addEventListener("abort", handler, { once: true });
108566
- child.on("close", () => abortSignal.removeEventListener("abort", handler));
108567
- }
108568
108672
  });
108569
108673
  }
108570
108674
  var MAX_POC_ATTEMPTS = 3, createPocInputSchema;
@@ -108799,6 +108903,23 @@ search with flags or a more specific directory if results are truncated.`,
108799
108903
  });
108800
108904
  let stdout = "";
108801
108905
  let stderr = "";
108906
+ let resolved = false;
108907
+ let abortCleanup;
108908
+ if (ctx4.abortSignal) {
108909
+ const abortHandler = () => child.kill("SIGTERM");
108910
+ ctx4.abortSignal.addEventListener("abort", abortHandler, {
108911
+ once: true
108912
+ });
108913
+ abortCleanup = () => ctx4.abortSignal.removeEventListener("abort", abortHandler);
108914
+ }
108915
+ const safeResolve = (result) => {
108916
+ if (resolved)
108917
+ return;
108918
+ resolved = true;
108919
+ clearTimeout(timeout);
108920
+ abortCleanup?.();
108921
+ resolve4(result);
108922
+ };
108802
108923
  const timeout = setTimeout(() => {
108803
108924
  child.kill("SIGTERM");
108804
108925
  }, 30000);
@@ -108809,7 +108930,6 @@ search with flags or a more specific directory if results are truncated.`,
108809
108930
  stderr += data.toString();
108810
108931
  });
108811
108932
  child.on("close", (code) => {
108812
- clearTimeout(timeout);
108813
108933
  const noMatch = code === 1 && stderr === "";
108814
108934
  const matchCount = stdout ? stdout.trimEnd().split(`
108815
108935
  `).length : 0;
@@ -108817,7 +108937,7 @@ search with flags or a more specific directory if results are truncated.`,
108817
108937
  const output = truncated ? `${stdout.substring(0, 50000)}
108818
108938
 
108819
108939
  (truncated — narrow your search)` : stdout || "(no matches)";
108820
- resolve4({
108940
+ safeResolve({
108821
108941
  success: code === 0 || noMatch,
108822
108942
  error: noMatch || code === 0 ? "" : stderr || `Exit code: ${code}`,
108823
108943
  output,
@@ -108826,8 +108946,7 @@ search with flags or a more specific directory if results are truncated.`,
108826
108946
  });
108827
108947
  });
108828
108948
  child.on("error", (err) => {
108829
- clearTimeout(timeout);
108830
- resolve4({
108949
+ safeResolve({
108831
108950
  success: false,
108832
108951
  error: err.message,
108833
108952
  output: "",
@@ -108835,15 +108954,6 @@ search with flags or a more specific directory if results are truncated.`,
108835
108954
  command
108836
108955
  });
108837
108956
  });
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
108957
  });
108848
108958
  }
108849
108959
  });
@@ -194191,6 +194301,7 @@ var init_offensiveSecurityAgent = __esm(() => {
194191
194301
  resolveResult;
194192
194302
  subagentId;
194193
194303
  persistentShell;
194304
+ abortSignal;
194194
194305
  _session;
194195
194306
  static async create(input) {
194196
194307
  let session = input.session;
@@ -194212,6 +194323,7 @@ var init_offensiveSecurityAgent = __esm(() => {
194212
194323
  constructor(input) {
194213
194324
  this._session = input.session;
194214
194325
  this.subagentId = input.subagentId;
194326
+ this.abortSignal = input.abortSignal;
194215
194327
  if (!input.sandbox) {
194216
194328
  this.persistentShell = new PersistentShell({
194217
194329
  cwd: input.session.rootPath
@@ -194375,6 +194487,9 @@ var init_offensiveSecurityAgent = __esm(() => {
194375
194487
  }
194376
194488
  }
194377
194489
  this.persistentShell?.dispose();
194490
+ if (this.abortSignal?.aborted) {
194491
+ throw new DOMException("Agent aborted by user", "AbortError");
194492
+ }
194378
194493
  if (this.resolveResult) {
194379
194494
  return this.resolveResult(this.streamResult);
194380
194495
  }
@@ -194483,6 +194598,7 @@ var init_blackboxAgent = __esm(() => {
194483
194598
  onStepFinish,
194484
194599
  abortSignal,
194485
194600
  attackSurfaceRegistry,
194601
+ messages: opts.messages,
194486
194602
  activeTools: [
194487
194603
  "execute_command",
194488
194604
  "document_asset",
@@ -194758,7 +194874,8 @@ var init_agent4 = __esm(() => {
194758
194874
  onStepFinish,
194759
194875
  abortSignal,
194760
194876
  sandbox,
194761
- findingsRegistry
194877
+ findingsRegistry,
194878
+ messages
194762
194879
  } = opts;
194763
194880
  super({
194764
194881
  system: buildSystemPrompt(session),
@@ -194771,6 +194888,7 @@ var init_agent4 = __esm(() => {
194771
194888
  abortSignal,
194772
194889
  sandbox,
194773
194890
  findingsRegistry,
194891
+ messages,
194774
194892
  activeTools: [
194775
194893
  "execute_command",
194776
194894
  "http_request",
@@ -194880,7 +194998,7 @@ var EXECUTION_METRICS_FILENAME = "execution-metrics.json";
194880
194998
  var init_execution_metrics = () => {};
194881
194999
 
194882
195000
  // src/core/utils/concurrency.ts
194883
- async function runWithBoundedConcurrency(items, concurrency, fn) {
195001
+ async function runWithBoundedConcurrency(items, concurrency, fn, abortSignal) {
194884
195002
  const results = new Array(items.length).fill(null);
194885
195003
  let nextIdx = 0;
194886
195004
  let completed = 0;
@@ -194891,11 +195009,11 @@ async function runWithBoundedConcurrency(items, concurrency, fn) {
194891
195009
  }
194892
195010
  let active = 0;
194893
195011
  function next() {
194894
- if (completed === items.length) {
195012
+ if (completed >= nextIdx && (nextIdx === items.length || abortSignal?.aborted)) {
194895
195013
  resolve4();
194896
195014
  return;
194897
195015
  }
194898
- while (active < concurrency && nextIdx < items.length) {
195016
+ while (active < concurrency && nextIdx < items.length && !abortSignal?.aborted) {
194899
195017
  const idx = nextIdx++;
194900
195018
  active++;
194901
195019
  fn(items[idx], idx).then((r2) => {
@@ -195485,10 +195603,21 @@ async function runPentestSwarm(input) {
195485
195603
  concurrency = DEFAULT_CONCURRENCY4,
195486
195604
  onStepFinish
195487
195605
  } = input;
195488
- const manifestEntries = buildManifestEntries(targets);
195606
+ const completedIds = getCompletedAgentIds(session);
195607
+ const existingManifest = readAgentManifest(session);
195608
+ const freshEntries = buildManifestEntries(targets);
195609
+ const manifestEntries = freshEntries.map((fresh) => {
195610
+ const existing = existingManifest.find((e2) => e2.id === fresh.id);
195611
+ if (existing && existing.status === "completed")
195612
+ return existing;
195613
+ return fresh;
195614
+ });
195489
195615
  writeAgentManifest(session, manifestEntries);
195490
195616
  const results = await runWithBoundedConcurrency(targets, concurrency, async (target, index) => {
195491
195617
  const subagentId = `pentest-agent-${index + 1}`;
195618
+ if (completedIds.has(subagentId))
195619
+ return null;
195620
+ const previousMessages = loadSubagentMessages(session, subagentId);
195492
195621
  let lastMessages = [];
195493
195622
  const handleStepFinish = (e2) => {
195494
195623
  if (e2.response.messages) {
@@ -195522,7 +195651,8 @@ async function runPentestSwarm(input) {
195522
195651
  authConfig,
195523
195652
  abortSignal,
195524
195653
  findingsRegistry,
195525
- onStepFinish: handleStepFinish
195654
+ onStepFinish: handleStepFinish,
195655
+ messages: previousMessages.length > 0 ? previousMessages : undefined
195526
195656
  });
195527
195657
  const result = await agent.consume({
195528
195658
  onError: (e2) => onError?.(e2),
@@ -195534,8 +195664,9 @@ async function runPentestSwarm(input) {
195534
195664
  objective: target.objectives.join("; "),
195535
195665
  status: "completed",
195536
195666
  findingsCount: result.findings.length,
195537
- messages: lastMessages
195667
+ messages: [...previousMessages, ...lastMessages]
195538
195668
  });
195669
+ updateManifestEntryStatus(session, subagentId, "completed");
195539
195670
  subagentCallbacks?.onSubagentComplete?.({
195540
195671
  subagentId,
195541
195672
  input: { target: target.target, objectives: target.objectives },
@@ -195549,8 +195680,9 @@ async function runPentestSwarm(input) {
195549
195680
  objective: target.objectives.join("; "),
195550
195681
  status: "failed",
195551
195682
  error: error40 instanceof Error ? error40.message : String(error40),
195552
- messages: lastMessages
195683
+ messages: [...previousMessages, ...lastMessages]
195553
195684
  });
195685
+ updateManifestEntryStatus(session, subagentId, "failed");
195554
195686
  subagentCallbacks?.onSubagentComplete?.({
195555
195687
  subagentId,
195556
195688
  input: { target: target.target, objectives: target.objectives },
@@ -195558,7 +195690,7 @@ async function runPentestSwarm(input) {
195558
195690
  });
195559
195691
  throw error40;
195560
195692
  }
195561
- });
195693
+ }, abortSignal);
195562
195694
  finalizeManifest(session, manifestEntries, results);
195563
195695
  return results;
195564
195696
  }
@@ -195576,7 +195708,13 @@ async function runPentestWorkflow(input) {
195576
195708
  try {
195577
195709
  const mode = cwd ? "whitebox" : "blackbox";
195578
195710
  let swarmTargets;
195579
- if (mode === "whitebox") {
195711
+ const existingResults = loadAttackSurfaceResults(session.rootPath);
195712
+ if (existingResults?.targets && existingResults.targets.length > 0) {
195713
+ swarmTargets = existingResults.targets.map((t3) => ({
195714
+ target: t3.target,
195715
+ objectives: [t3.objective]
195716
+ }));
195717
+ } else if (mode === "whitebox") {
195580
195718
  swarmTargets = await runWhiteboxPhase({
195581
195719
  codebasePath: cwd,
195582
195720
  baseTarget: target,
@@ -195598,6 +195736,9 @@ async function runPentestWorkflow(input) {
195598
195736
  onStepFinish
195599
195737
  });
195600
195738
  }
195739
+ if (abortSignal?.aborted) {
195740
+ throw new DOMException("Pentest aborted by user", "AbortError");
195741
+ }
195601
195742
  if (swarmTargets.length === 0) {
195602
195743
  const report2 = buildPentestReport([], {
195603
195744
  target,
@@ -195621,17 +195762,23 @@ async function runPentestWorkflow(input) {
195621
195762
  authConfig,
195622
195763
  abortSignal
195623
195764
  });
195624
- await runPentestSwarm({
195625
- targets: swarmTargets,
195626
- model,
195627
- session,
195628
- authConfig,
195629
- abortSignal,
195630
- findingsRegistry,
195631
- subagentCallbacks: callbacks?.subagentCallbacks,
195632
- onError: (e2) => callbacks?.onError?.(e2),
195633
- onStepFinish
195634
- });
195765
+ const completedCount = getCompletedAgentIds(session).size;
195766
+ if (completedCount < swarmTargets.length) {
195767
+ await runPentestSwarm({
195768
+ targets: swarmTargets,
195769
+ model,
195770
+ session,
195771
+ authConfig,
195772
+ abortSignal,
195773
+ findingsRegistry,
195774
+ subagentCallbacks: callbacks?.subagentCallbacks,
195775
+ onError: (e2) => callbacks?.onError?.(e2),
195776
+ onStepFinish
195777
+ });
195778
+ }
195779
+ if (abortSignal?.aborted) {
195780
+ throw new DOMException("Pentest aborted by user", "AbortError");
195781
+ }
195635
195782
  const findings = loadFindings2(session.findingsPath);
195636
195783
  const report = buildPentestReport(findings, {
195637
195784
  target,
@@ -195743,6 +195890,7 @@ var init_pentest = __esm(() => {
195743
195890
  init_report();
195744
195891
  init_persistence();
195745
195892
  init_execution_metrics();
195893
+ init_loader();
195746
195894
  init_whiteboxAttackSurface();
195747
195895
  });
195748
195896
 
@@ -272350,7 +272498,7 @@ var useTerminalDimensions = () => {
272350
272498
  };
272351
272499
 
272352
272500
  // src/tui/index.tsx
272353
- var import_react89 = __toESM(require_react(), 1);
272501
+ var import_react87 = __toESM(require_react(), 1);
272354
272502
 
272355
272503
  // src/tui/components/footer.tsx
272356
272504
  import os6 from "os";
@@ -273821,7 +273969,7 @@ function CommandProvider({
273821
273969
  }
273822
273970
 
273823
273971
  // src/tui/components/commands/sessions-display.tsx
273824
- var import_react22 = __toESM(require_react(), 1);
273972
+ var import_react24 = __toESM(require_react(), 1);
273825
273973
 
273826
273974
  // src/tui/context/focus.tsx
273827
273975
  var import_react18 = __toESM(require_react(), 1);
@@ -273890,10 +274038,29 @@ function openSessionReport(sessionRootPath) {
273890
274038
  }
273891
274039
  }
273892
274040
 
274041
+ // src/tui/context/dimensions.tsx
274042
+ var import_react19 = __toESM(require_react(), 1);
274043
+ var DimensionsContext = import_react19.createContext(null);
274044
+ function TerminalDimensionsProvider({
274045
+ children
274046
+ }) {
274047
+ const dimensions = useTerminalDimensions();
274048
+ return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(DimensionsContext.Provider, {
274049
+ value: dimensions,
274050
+ children
274051
+ }, undefined, false, undefined, this);
274052
+ }
274053
+ function useDimensions() {
274054
+ const ctx3 = import_react19.useContext(DimensionsContext);
274055
+ if (!ctx3)
274056
+ throw new Error("useDimensions() must be used within <TerminalDimensionsProvider>");
274057
+ return ctx3;
274058
+ }
274059
+
273893
274060
  // src/tui/context/dialog.tsx
273894
- var import_react20 = __toESM(require_react(), 1);
274061
+ var import_react22 = __toESM(require_react(), 1);
273895
274062
  function Dialog({ size = "medium", onClose, children }) {
273896
- const dimensions = useTerminalDimensions();
274063
+ const dimensions = useDimensions();
273897
274064
  const renderer = useRenderer();
273898
274065
  const { colors: themeColors } = useTheme();
273899
274066
  return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
@@ -273928,14 +274095,14 @@ function Dialog({ size = "medium", onClose, children }) {
273928
274095
  }, undefined, false, undefined, this)
273929
274096
  }, undefined, false, undefined, this);
273930
274097
  }
273931
- var DialogContext = import_react20.createContext(null);
274098
+ var DialogContext = import_react22.createContext(null);
273932
274099
  function DialogProvider({ children }) {
273933
- const [stack, setStack] = import_react20.useState([]);
273934
- const [size, setSize] = import_react20.useState("medium");
273935
- const [externalDialogOpen, setExternalDialogOpen] = import_react20.useState(false);
274100
+ const [stack, setStack] = import_react22.useState([]);
274101
+ const [size, setSize] = import_react22.useState("medium");
274102
+ const [externalDialogOpen, setExternalDialogOpen] = import_react22.useState(false);
273936
274103
  const renderer = useRenderer();
273937
- const focusRef = import_react20.useRef(null);
273938
- const refocus = import_react20.useCallback(() => {
274104
+ const focusRef = import_react22.useRef(null);
274105
+ const refocus = import_react22.useCallback(() => {
273939
274106
  setTimeout(() => {
273940
274107
  const focus = focusRef.current;
273941
274108
  if (!focus)
@@ -273957,7 +274124,7 @@ function DialogProvider({ children }) {
273957
274124
  focus.focus();
273958
274125
  }, 1);
273959
274126
  }, [renderer]);
273960
- const clear = import_react20.useCallback(() => {
274127
+ const clear = import_react22.useCallback(() => {
273961
274128
  for (const item of stack) {
273962
274129
  if (item.onClose)
273963
274130
  item.onClose();
@@ -273966,7 +274133,7 @@ function DialogProvider({ children }) {
273966
274133
  setStack([]);
273967
274134
  refocus();
273968
274135
  }, [stack, refocus]);
273969
- const replace = import_react20.useCallback((element, onClose) => {
274136
+ const replace = import_react22.useCallback((element, onClose) => {
273970
274137
  if (stack.length === 0) {
273971
274138
  focusRef.current = renderer.currentFocusedRenderable;
273972
274139
  }
@@ -274011,7 +274178,7 @@ function DialogProvider({ children }) {
274011
274178
  }, undefined, true, undefined, this);
274012
274179
  }
274013
274180
  function useDialog() {
274014
- const value = import_react20.useContext(DialogContext);
274181
+ const value = import_react22.useContext(DialogContext);
274015
274182
  if (!value) {
274016
274183
  throw new Error("useDialog must be used within a DialogProvider");
274017
274184
  }
@@ -274076,7 +274243,7 @@ function findChildById(scrollBox, id) {
274076
274243
  // src/tui/hooks/use-sessions-list.ts
274077
274244
  init_session();
274078
274245
  init_report();
274079
- var import_react21 = __toESM(require_react(), 1);
274246
+ var import_react23 = __toESM(require_react(), 1);
274080
274247
  import { existsSync as existsSync7, readdirSync } from "fs";
274081
274248
  import { join as join3 } from "path";
274082
274249
  function countFindings(findingsPath) {
@@ -274092,10 +274259,10 @@ function checkHasReport(rootPath) {
274092
274259
  return existsSync7(join3(rootPath, REPORT_FILENAME_MD));
274093
274260
  }
274094
274261
  function useSessionsList() {
274095
- const [allSessions, setAllSessions] = import_react21.useState([]);
274096
- const [loading, setLoading] = import_react21.useState(true);
274097
- const [searchTerm, setSearchTerm] = import_react21.useState("");
274098
- const loadSessions = import_react21.useCallback(async () => {
274262
+ const [allSessions, setAllSessions] = import_react23.useState([]);
274263
+ const [loading, setLoading] = import_react23.useState(true);
274264
+ const [searchTerm, setSearchTerm] = import_react23.useState("");
274265
+ const loadSessions = import_react23.useCallback(async () => {
274099
274266
  setLoading(true);
274100
274267
  try {
274101
274268
  const enriched = [];
@@ -274118,10 +274285,10 @@ function useSessionsList() {
274118
274285
  setLoading(false);
274119
274286
  }
274120
274287
  }, []);
274121
- import_react21.useEffect(() => {
274288
+ import_react23.useEffect(() => {
274122
274289
  loadSessions();
274123
274290
  }, [loadSessions]);
274124
- const deleteSession = import_react21.useCallback(async (id) => {
274291
+ const deleteSession = import_react23.useCallback(async (id) => {
274125
274292
  await sessions.remove({ sessionId: id });
274126
274293
  await loadSessions();
274127
274294
  }, [loadSessions]);
@@ -274180,10 +274347,10 @@ function useSessionsList() {
274180
274347
  function SessionsDisplay({ onClose }) {
274181
274348
  const { colors: colors2 } = useTheme();
274182
274349
  const { refocusPrompt } = useFocus();
274183
- const [selectedIndex, setSelectedIndex] = import_react22.useState(0);
274184
- const [statusMessage, setStatusMessage] = import_react22.useState("");
274350
+ const [selectedIndex, setSelectedIndex] = import_react24.useState(0);
274351
+ const [statusMessage, setStatusMessage] = import_react24.useState("");
274185
274352
  const route = useRoute();
274186
- const scroll = import_react22.useRef(null);
274353
+ const scroll = import_react24.useRef(null);
274187
274354
  const {
274188
274355
  groupedSessions,
274189
274356
  visualOrderSessions,
@@ -274199,7 +274366,7 @@ function SessionsDisplay({ onClose }) {
274199
274366
  setTimeout(() => setStatusMessage(""), 2000);
274200
274367
  }
274201
274368
  }
274202
- import_react22.useEffect(() => {
274369
+ import_react24.useEffect(() => {
274203
274370
  if (visualOrderSessions.length > 0 && selectedIndex >= visualOrderSessions.length) {
274204
274371
  setSelectedIndex(visualOrderSessions.length - 1);
274205
274372
  } else if (visualOrderSessions.length === 0) {
@@ -274235,7 +274402,7 @@ function SessionsDisplay({ onClose }) {
274235
274402
  setTimeout(() => setStatusMessage(""), 2000);
274236
274403
  return;
274237
274404
  }
274238
- const isOperator = currentSelection.config?.mode === "operator" || currentSelection.hasOperatorState;
274405
+ const isOperator = currentSelection.config?.mode === "operator" || !currentSelection.config?.mode && currentSelection.hasOperatorState;
274239
274406
  refocusPrompt();
274240
274407
  onClose();
274241
274408
  route.navigate({
@@ -274281,6 +274448,11 @@ function SessionsDisplay({ onClose }) {
274281
274448
  const currentSelection = visualOrderSessions[selectedIndex];
274282
274449
  if (!currentSelection)
274283
274450
  return;
274451
+ if (!currentSelection.hasReport) {
274452
+ setStatusMessage("No report available");
274453
+ setTimeout(() => setStatusMessage(""), 2000);
274454
+ return;
274455
+ }
274284
274456
  openReport(currentSelection.id);
274285
274457
  return;
274286
274458
  }
@@ -274384,6 +274556,7 @@ function SessionsDisplay({ onClose }) {
274384
274556
  });
274385
274557
  const mode = session.config?.mode || "auto";
274386
274558
  const modeBadge = mode === "operator" ? "[operator]" : "[auto]";
274559
+ const statusBadge = session.hasReport ? "✓" : "…";
274387
274560
  const findingsText = session.findingsCount > 0 ? `${session.findingsCount} finding${session.findingsCount > 1 ? "s" : ""}` : "";
274388
274561
  return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
274389
274562
  id: session.id,
@@ -274408,6 +274581,10 @@ function SessionsDisplay({ onClose }) {
274408
274581
  fg: isSelected ? colors2.text : colors2.textMuted,
274409
274582
  children: session.name
274410
274583
  }, undefined, false, undefined, this),
274584
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
274585
+ fg: session.hasReport ? colors2.primary : colors2.textMuted,
274586
+ children: statusBadge
274587
+ }, undefined, false, undefined, this),
274411
274588
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
274412
274589
  fg: mode === "operator" ? colors2.primary : colors2.textMuted,
274413
274590
  children: modeBadge
@@ -274471,7 +274648,7 @@ function SessionsDisplay({ onClose }) {
274471
274648
  }
274472
274649
 
274473
274650
  // src/tui/components/commands/config-dialog.tsx
274474
- var import_react25 = __toESM(require_react(), 1);
274651
+ var import_react27 = __toESM(require_react(), 1);
274475
274652
 
274476
274653
  // src/tui/components/alert-dialog.tsx
274477
274654
  function AlertDialog({
@@ -274484,7 +274661,7 @@ function AlertDialog({
274484
274661
  size = "medium"
274485
274662
  }) {
274486
274663
  const { colors: colors2 } = useTheme();
274487
- const dimensions = useTerminalDimensions();
274664
+ const dimensions = useDimensions();
274488
274665
  const renderer = useRenderer();
274489
274666
  useKeyboard((key) => {
274490
274667
  if (!open)
@@ -274558,8 +274735,8 @@ function AlertDialog({
274558
274735
  init_config2();
274559
274736
  function ConfigDialog() {
274560
274737
  const route = useRoute();
274561
- const [open, setOpen] = import_react25.useState(false);
274562
- import_react25.useEffect(() => {
274738
+ const [open, setOpen] = import_react27.useState(false);
274739
+ import_react27.useEffect(() => {
274563
274740
  if (route.data.type === "base" && route.data.path === "config") {
274564
274741
  setOpen(true);
274565
274742
  } else {
@@ -274573,8 +274750,8 @@ function ConfigDialog() {
274573
274750
  path: "home"
274574
274751
  });
274575
274752
  };
274576
- const [appConfig, setAppConfig] = import_react25.useState(null);
274577
- import_react25.useEffect(() => {
274753
+ const [appConfig, setAppConfig] = import_react27.useState(null);
274754
+ import_react27.useEffect(() => {
274578
274755
  async function getConfig() {
274579
274756
  const _appConfig = await config2.get();
274580
274757
  setAppConfig(_appConfig);
@@ -274649,11 +274826,11 @@ var import_react38 = __toESM(require_react(), 1);
274649
274826
 
274650
274827
  // src/tui/context/config.tsx
274651
274828
  init_config2();
274652
- var import_react26 = __toESM(require_react(), 1);
274653
- var ctx3 = import_react26.createContext(null);
274829
+ var import_react28 = __toESM(require_react(), 1);
274830
+ var ctx3 = import_react28.createContext(null);
274654
274831
  function ConfigProvider({ children, config: config3 }) {
274655
- const [appConfig, setAppConfig] = import_react26.useState(config3);
274656
- const value = import_react26.useMemo(() => ({
274832
+ const [appConfig, setAppConfig] = import_react28.useState(config3);
274833
+ const value = import_react28.useMemo(() => ({
274657
274834
  data: appConfig,
274658
274835
  update: async (newConfig) => {
274659
274836
  await config2.update(newConfig);
@@ -274673,7 +274850,7 @@ function ConfigProvider({ children, config: config3 }) {
274673
274850
  }, undefined, false, undefined, this);
274674
274851
  }
274675
274852
  var useConfig = () => {
274676
- const config3 = import_react26.useContext(ctx3);
274853
+ const config3 = import_react28.useContext(ctx3);
274677
274854
  if (!config3) {
274678
274855
  throw new Error("useConfig must be called within a ConfigProvider");
274679
274856
  }
@@ -274681,10 +274858,10 @@ var useConfig = () => {
274681
274858
  };
274682
274859
 
274683
274860
  // src/tui/components/chat/home-view.tsx
274684
- var import_react32 = __toESM(require_react(), 1);
274861
+ var import_react33 = __toESM(require_react(), 1);
274685
274862
 
274686
274863
  // src/tui/components/chat/petri-animation.tsx
274687
- var import_react27 = __toESM(require_react(), 1);
274864
+ var import_react29 = __toESM(require_react(), 1);
274688
274865
 
274689
274866
  // src/tui/components/chat/lib/play-core/num.ts
274690
274867
  function clamp(x2, min, max) {
@@ -274780,8 +274957,8 @@ function stopGlobalTick2() {
274780
274957
  }
274781
274958
  }
274782
274959
  function useGlobalTick2() {
274783
- const [, setTick] = import_react27.useState(0);
274784
- import_react27.useEffect(() => {
274960
+ const [, setTick] = import_react29.useState(0);
274961
+ import_react29.useEffect(() => {
274785
274962
  const listener = () => setTick((t2) => t2 + 1);
274786
274963
  globalListeners2.add(listener);
274787
274964
  startGlobalTick2();
@@ -274806,19 +274983,19 @@ function PetriAnimation({
274806
274983
  height = 0.4,
274807
274984
  width = "100%"
274808
274985
  }) {
274809
- const dimensions = useTerminalDimensions();
274986
+ const dimensions = useDimensions();
274810
274987
  const tick = useGlobalTick2();
274811
274988
  const { colors: colors2 } = useTheme();
274812
- const simulationRef = import_react27.useRef(null);
274813
- const [frame, setFrame] = import_react27.useState([]);
274814
- const gradientColors = import_react27.useMemo(() => generateGradient(colors2.primary, 9), [colors2.primary]);
274815
- const actualHeight = import_react27.useMemo(() => {
274989
+ const simulationRef = import_react29.useRef(null);
274990
+ const [frame, setFrame] = import_react29.useState([]);
274991
+ const gradientColors = import_react29.useMemo(() => generateGradient(colors2.primary, 9), [colors2.primary]);
274992
+ const actualHeight = import_react29.useMemo(() => {
274816
274993
  if (typeof height === "number" && height <= 1) {
274817
274994
  return Math.floor(dimensions.height * height);
274818
274995
  }
274819
274996
  return typeof height === "number" ? height : Math.floor(dimensions.height * 0.4);
274820
274997
  }, [height, dimensions.height]);
274821
- const actualWidth = import_react27.useMemo(() => {
274998
+ const actualWidth = import_react29.useMemo(() => {
274822
274999
  if (typeof width === "number" && width <= 1) {
274823
275000
  return Math.floor(dimensions.width * width);
274824
275001
  }
@@ -274827,7 +275004,7 @@ function PetriAnimation({
274827
275004
  }
274828
275005
  return typeof width === "number" ? width : dimensions.width;
274829
275006
  }, [width, dimensions.width]);
274830
- import_react27.useEffect(() => {
275007
+ import_react29.useEffect(() => {
274831
275008
  if (actualWidth <= 0 || actualHeight <= 0)
274832
275009
  return;
274833
275010
  if (!simulationRef.current) {
@@ -274836,7 +275013,7 @@ function PetriAnimation({
274836
275013
  simulationRef.current.resize(actualWidth, actualHeight);
274837
275014
  }
274838
275015
  }, [actualWidth, actualHeight]);
274839
- import_react27.useEffect(() => {
275016
+ import_react29.useEffect(() => {
274840
275017
  if (simulationRef.current) {
274841
275018
  simulationRef.current.step();
274842
275019
  setFrame(simulationRef.current.render());
@@ -274862,7 +275039,7 @@ function getRowColor(rowIdx, totalRows, gradient) {
274862
275039
  }
274863
275040
 
274864
275041
  // src/tui/components/shared/prompt-input.tsx
274865
- var import_react30 = __toESM(require_react(), 1);
275042
+ var import_react31 = __toESM(require_react(), 1);
274866
275043
 
274867
275044
  // src/tui/components/shared/prompt-input-logic.ts
274868
275045
  function filterSuggestions(inputValue, options, maxSuggestions) {
@@ -274983,13 +275160,13 @@ function shouldResetHistory(historyIndex, isNavigatingHistory) {
274983
275160
  }
274984
275161
 
274985
275162
  // src/tui/components/shared/use-paste-extmarks.ts
274986
- var import_react29 = __toESM(require_react(), 1);
275163
+ var import_react30 = __toESM(require_react(), 1);
274987
275164
  var LARGE_PASTE_MIN_LINES = 5;
274988
275165
  var LARGE_PASTE_MIN_CHARS = 500;
274989
275166
  function usePasteExtmarks(textareaRef) {
274990
- const countRef = import_react29.useRef(0);
274991
- const typeIdRef = import_react29.useRef(-1);
274992
- const dataRef = import_react29.useRef(new Map);
275167
+ const countRef = import_react30.useRef(0);
275168
+ const typeIdRef = import_react30.useRef(-1);
275169
+ const dataRef = import_react30.useRef(new Map);
274993
275170
  const clearPaste = () => {
274994
275171
  textareaRef.current?.extmarks.clear();
274995
275172
  countRef.current = 0;
@@ -275059,7 +275236,7 @@ var chatKeyBindings = [
275059
275236
  { name: "return", shift: true, action: "newline" },
275060
275237
  { name: "linefeed", shift: true, action: "newline" }
275061
275238
  ];
275062
- var PromptInput = import_react30.forwardRef(function PromptInput2({
275239
+ var PromptInput = import_react31.forwardRef(function PromptInput2({
275063
275240
  width,
275064
275241
  minHeight = 1,
275065
275242
  maxHeight = 6,
@@ -275084,31 +275261,31 @@ var PromptInput = import_react30.forwardRef(function PromptInput2({
275084
275261
  const { colors: colors2 } = useTheme();
275085
275262
  const { inputValue, setInputValue } = useInput();
275086
275263
  const { registerPromptRef } = useFocus();
275087
- const textareaRef = import_react30.useRef(null);
275088
- const [selectedSuggestionIndex, setSelectedSuggestionIndex] = import_react30.useState(-1);
275089
- const [historyIndex, setHistoryIndex] = import_react30.useState(-1);
275090
- const savedInputRef = import_react30.useRef("");
275091
- const historyRef = import_react30.useRef(commandHistory);
275264
+ const textareaRef = import_react31.useRef(null);
275265
+ const [selectedSuggestionIndex, setSelectedSuggestionIndex] = import_react31.useState(-1);
275266
+ const [historyIndex, setHistoryIndex] = import_react31.useState(-1);
275267
+ const savedInputRef = import_react31.useRef("");
275268
+ const historyRef = import_react31.useRef(commandHistory);
275092
275269
  historyRef.current = commandHistory;
275093
- const isNavigatingHistoryRef = import_react30.useRef(false);
275094
- const selectedIndexRef = import_react30.useRef(selectedSuggestionIndex);
275095
- const suggestionsRef = import_react30.useRef([]);
275096
- const onCommandExecuteRef = import_react30.useRef(onCommandExecute);
275270
+ const isNavigatingHistoryRef = import_react31.useRef(false);
275271
+ const selectedIndexRef = import_react31.useRef(selectedSuggestionIndex);
275272
+ const suggestionsRef = import_react31.useRef([]);
275273
+ const onCommandExecuteRef = import_react31.useRef(onCommandExecute);
275097
275274
  onCommandExecuteRef.current = onCommandExecute;
275098
- const onSubmitRef = import_react30.useRef(onSubmit);
275275
+ const onSubmitRef = import_react31.useRef(onSubmit);
275099
275276
  onSubmitRef.current = onSubmit;
275100
275277
  const { handlePaste, resolveText, clearPaste } = usePasteExtmarks(textareaRef);
275101
- const suggestions = import_react30.useMemo(() => enableAutocomplete ? filterSuggestions(inputValue, autocompleteOptions, maxSuggestions) : [], [enableAutocomplete, autocompleteOptions, inputValue, maxSuggestions]);
275102
- import_react30.useEffect(() => {
275278
+ const suggestions = import_react31.useMemo(() => enableAutocomplete ? filterSuggestions(inputValue, autocompleteOptions, maxSuggestions) : [], [enableAutocomplete, autocompleteOptions, inputValue, maxSuggestions]);
275279
+ import_react31.useEffect(() => {
275103
275280
  suggestionsRef.current = suggestions;
275104
275281
  }, [suggestions]);
275105
- import_react30.useEffect(() => {
275282
+ import_react31.useEffect(() => {
275106
275283
  selectedIndexRef.current = selectedSuggestionIndex;
275107
275284
  }, [selectedSuggestionIndex]);
275108
- import_react30.useEffect(() => {
275285
+ import_react31.useEffect(() => {
275109
275286
  setSelectedSuggestionIndex(suggestions.length > 0 ? 0 : -1);
275110
275287
  }, [suggestions.length]);
275111
- const imperativeRef = import_react30.useRef({
275288
+ const imperativeRef = import_react31.useRef({
275112
275289
  focus: () => textareaRef.current?.focus(),
275113
275290
  blur: () => textareaRef.current?.blur(),
275114
275291
  reset: () => {
@@ -275125,11 +275302,11 @@ var PromptInput = import_react30.forwardRef(function PromptInput2({
275125
275302
  getValue: () => inputValue,
275126
275303
  getTextareaRef: () => textareaRef.current
275127
275304
  });
275128
- import_react30.useEffect(() => {
275305
+ import_react31.useEffect(() => {
275129
275306
  imperativeRef.current.getValue = () => inputValue;
275130
275307
  }, [inputValue]);
275131
- import_react30.useImperativeHandle(ref, () => imperativeRef.current, []);
275132
- import_react30.useEffect(() => {
275308
+ import_react31.useImperativeHandle(ref, () => imperativeRef.current, []);
275309
+ import_react31.useEffect(() => {
275133
275310
  registerPromptRef(imperativeRef.current);
275134
275311
  return () => registerPromptRef(null);
275135
275312
  }, [registerPromptRef]);
@@ -275345,41 +275522,41 @@ function getEntries() {
275345
275522
  // src/tui/components/chat/home-view.tsx
275346
275523
  function HomeView({ onNavigate, onStartSession }) {
275347
275524
  const { colors: colors2 } = useTheme();
275348
- const dimensions = useTerminalDimensions();
275525
+ const dimensions = useDimensions();
275349
275526
  const config3 = useConfig();
275350
275527
  const route = useRoute();
275351
275528
  const { executeCommand, autocompleteOptions, resolveSkillContent, skills } = useCommand();
275352
275529
  const { setInputValue } = useInput();
275353
275530
  const { promptRef } = useFocus();
275354
275531
  const { externalDialogOpen, stack } = useDialog();
275355
- const [hintMessage, setHintMessage] = import_react32.useState(null);
275356
- const [commandHistory, setCommandHistory] = import_react32.useState(getEntries);
275357
- import_react32.useEffect(() => {
275532
+ const [hintMessage, setHintMessage] = import_react33.useState(null);
275533
+ const [commandHistory, setCommandHistory] = import_react33.useState(getEntries);
275534
+ import_react33.useEffect(() => {
275358
275535
  load().then(setCommandHistory);
275359
275536
  }, []);
275360
- const launchOperator = import_react32.useCallback((message, options) => {
275537
+ const launchOperator = import_react33.useCallback((message, options) => {
275361
275538
  route.navigate({
275362
275539
  type: "operator",
275363
275540
  initialMessage: message,
275364
275541
  initialConfig: { requireApproval: options?.requireApproval ?? true }
275365
275542
  });
275366
275543
  }, [route]);
275367
- const pushHistory = import_react32.useCallback((entry) => {
275544
+ const pushHistory = import_react33.useCallback((entry) => {
275368
275545
  push(entry).then(() => setCommandHistory([...getEntries()]));
275369
275546
  }, []);
275370
- const handleSubmit = import_react32.useCallback((value) => {
275547
+ const handleSubmit = import_react33.useCallback((value) => {
275371
275548
  if (!value.trim())
275372
275549
  return;
275373
275550
  pushHistory(value.trim());
275374
275551
  launchOperator(value.trim());
275375
275552
  }, [launchOperator, pushHistory]);
275376
- import_react32.useEffect(() => {
275553
+ import_react33.useEffect(() => {
275377
275554
  if (!hintMessage)
275378
275555
  return;
275379
275556
  const timer = setTimeout(() => setHintMessage(null), 3000);
275380
275557
  return () => clearTimeout(timer);
275381
275558
  }, [hintMessage]);
275382
- const handleCommandExecute = import_react32.useCallback(async (command) => {
275559
+ const handleCommandExecute = import_react33.useCallback(async (command) => {
275383
275560
  const trimmed = command.trim();
275384
275561
  pushHistory(trimmed);
275385
275562
  const parts = trimmed.replace(/^\/+/, "").split(/\s+/);
@@ -278243,7 +278420,7 @@ function ToastItem({
278243
278420
  }
278244
278421
  function ToastContainer() {
278245
278422
  const { toasts, dismiss } = useToast();
278246
- const dims = useTerminalDimensions();
278423
+ const dims = useDimensions();
278247
278424
  if (toasts.length === 0)
278248
278425
  return null;
278249
278426
  return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
@@ -278264,11 +278441,11 @@ function ToastContainer() {
278264
278441
  }
278265
278442
 
278266
278443
  // src/tui/components/error-boundary.tsx
278267
- var import_react53 = __toESM(require_react(), 1);
278444
+ var import_react52 = __toESM(require_react(), 1);
278268
278445
  var MAX_ERRORS = 3;
278269
278446
  var ERROR_WINDOW_MS = 5000;
278270
278447
 
278271
- class ErrorBoundaryInner extends import_react53.default.Component {
278448
+ class ErrorBoundaryInner extends import_react52.default.Component {
278272
278449
  state = {
278273
278450
  hasError: false,
278274
278451
  errorTimestamps: [],
@@ -278299,10 +278476,10 @@ class ErrorBoundaryInner extends import_react53.default.Component {
278299
278476
  }
278300
278477
  function ErrorBoundary2({ children }) {
278301
278478
  const { toast } = useToast();
278302
- const handleError = import_react53.useCallback((message) => {
278479
+ const handleError = import_react52.useCallback((message) => {
278303
278480
  toast(message, "error");
278304
278481
  }, [toast]);
278305
- return import_react53.default.createElement(ErrorBoundaryInner, { onError: handleError }, children);
278482
+ return import_react52.default.createElement(ErrorBoundaryInner, { onError: handleError }, children);
278306
278483
  }
278307
278484
 
278308
278485
  // src/tui/index.tsx
@@ -278413,16 +278590,16 @@ function ShortcutsDialog({
278413
278590
  }
278414
278591
 
278415
278592
  // src/tui/components/commands/help-dialog.tsx
278416
- var import_react55 = __toESM(require_react(), 1);
278593
+ var import_react54 = __toESM(require_react(), 1);
278417
278594
  function HelpDialog() {
278418
278595
  const { colors: colors2 } = useTheme();
278419
278596
  const { commands: commands2 } = useCommand();
278420
278597
  const route = useRoute();
278421
- const dimensions = useTerminalDimensions();
278422
- const [selectedIndex, setSelectedIndex] = import_react55.useState(0);
278423
- const [showDetail, setShowDetail] = import_react55.useState(false);
278424
- const scrollboxRef = import_react55.useRef(null);
278425
- const commandsByCategory = import_react55.useMemo(() => {
278598
+ const dimensions = useDimensions();
278599
+ const [selectedIndex, setSelectedIndex] = import_react54.useState(0);
278600
+ const [showDetail, setShowDetail] = import_react54.useState(false);
278601
+ const scrollboxRef = import_react54.useRef(null);
278602
+ const commandsByCategory = import_react54.useMemo(() => {
278426
278603
  const grouped = {};
278427
278604
  for (const cmd of commands2) {
278428
278605
  const category = cmd.category || "Other";
@@ -278433,15 +278610,15 @@ function HelpDialog() {
278433
278610
  }
278434
278611
  return grouped;
278435
278612
  }, [commands2]);
278436
- const flatCommands = import_react55.useMemo(() => {
278613
+ const flatCommands = import_react54.useMemo(() => {
278437
278614
  return commands2;
278438
278615
  }, [commands2]);
278439
- import_react55.useEffect(() => {
278616
+ import_react54.useEffect(() => {
278440
278617
  if (selectedIndex >= flatCommands.length) {
278441
278618
  setSelectedIndex(Math.max(0, flatCommands.length - 1));
278442
278619
  }
278443
278620
  }, [flatCommands.length, selectedIndex]);
278444
- import_react55.useEffect(() => {
278621
+ import_react54.useEffect(() => {
278445
278622
  scrollToIndex(scrollboxRef.current, selectedIndex, flatCommands, (cmd) => cmd.name);
278446
278623
  }, [selectedIndex, flatCommands]);
278447
278624
  const handleClose = () => {
@@ -278876,24 +279053,24 @@ function ModelsDisplay() {
278876
279053
  }
278877
279054
 
278878
279055
  // src/tui/components/commands/auth-flow.tsx
278879
- var import_react58 = __toESM(require_react(), 1);
279056
+ var import_react57 = __toESM(require_react(), 1);
278880
279057
  init_config2();
278881
279058
  function AuthFlow({ onClose }) {
278882
279059
  const { colors: colors2 } = useTheme();
278883
279060
  const appConfig = useConfig();
278884
279061
  const isConnected = !!(appConfig.data.accessToken || appConfig.data.pensarAPIKey);
278885
- const [step, setStep] = import_react58.useState(isConnected ? "success" : "start");
278886
- const [error40, setError] = import_react58.useState(null);
278887
- const [authMode, setAuthMode] = import_react58.useState(null);
278888
- const [deviceInfo, setDeviceInfo] = import_react58.useState(null);
278889
- const [legacyDeviceInfo, setLegacyDeviceInfo] = import_react58.useState(null);
278890
- const [workspaces, setWorkspaces] = import_react58.useState([]);
278891
- const [selectedWorkspace, setSelectedWorkspace] = import_react58.useState(null);
278892
- const [selectedIndex, setSelectedIndex] = import_react58.useState(0);
278893
- const [billingUrl, setBillingUrl] = import_react58.useState(null);
278894
- const [balance, setBalance] = import_react58.useState(null);
278895
- const pollingRef = import_react58.useRef(null);
278896
- const cancelledRef = import_react58.useRef(false);
279062
+ const [step, setStep] = import_react57.useState(isConnected ? "success" : "start");
279063
+ const [error40, setError] = import_react57.useState(null);
279064
+ const [authMode, setAuthMode] = import_react57.useState(null);
279065
+ const [deviceInfo, setDeviceInfo] = import_react57.useState(null);
279066
+ const [legacyDeviceInfo, setLegacyDeviceInfo] = import_react57.useState(null);
279067
+ const [workspaces, setWorkspaces] = import_react57.useState([]);
279068
+ const [selectedWorkspace, setSelectedWorkspace] = import_react57.useState(null);
279069
+ const [selectedIndex, setSelectedIndex] = import_react57.useState(0);
279070
+ const [billingUrl, setBillingUrl] = import_react57.useState(null);
279071
+ const [balance, setBalance] = import_react57.useState(null);
279072
+ const pollingRef = import_react57.useRef(null);
279073
+ const cancelledRef = import_react57.useRef(false);
278897
279074
  const connectedWorkspace = appConfig.data.workspaceSlug ? { name: appConfig.data.workspaceSlug, slug: appConfig.data.workspaceSlug } : null;
278898
279075
  const goHome = () => {
278899
279076
  onClose();
@@ -278905,7 +279082,7 @@ function AuthFlow({ onClose }) {
278905
279082
  pollingRef.current = null;
278906
279083
  }
278907
279084
  };
278908
- import_react58.useEffect(() => {
279085
+ import_react57.useEffect(() => {
278909
279086
  return cleanup;
278910
279087
  }, []);
278911
279088
  const openUrl = (url2) => {
@@ -279538,14 +279715,14 @@ function AuthFlow({ onClose }) {
279538
279715
  }
279539
279716
 
279540
279717
  // src/tui/components/commands/credits-flow.tsx
279541
- var import_react60 = __toESM(require_react(), 1);
279718
+ var import_react59 = __toESM(require_react(), 1);
279542
279719
  init_tokenRefresh();
279543
279720
  function CreditsFlow({ onOpenAuthDialog }) {
279544
279721
  const route = useRoute();
279545
279722
  const appConfig = useConfig();
279546
- const [step, setStep] = import_react60.useState("loading");
279547
- const [credits, setCredits] = import_react60.useState(null);
279548
- const [error40, setError] = import_react60.useState(null);
279723
+ const [step, setStep] = import_react59.useState("loading");
279724
+ const [credits, setCredits] = import_react59.useState(null);
279725
+ const [error40, setError] = import_react59.useState(null);
279549
279726
  const creditsUrl = `${getPensarConsoleUrl()}/credits`;
279550
279727
  const goHome = () => {
279551
279728
  route.navigate({ type: "base", path: "home" });
@@ -279603,7 +279780,7 @@ function CreditsFlow({ onOpenAuthDialog }) {
279603
279780
  setStep("display");
279604
279781
  }
279605
279782
  };
279606
- import_react60.useEffect(() => {
279783
+ import_react59.useEffect(() => {
279607
279784
  fetchBalance();
279608
279785
  }, []);
279609
279786
  useKeyboard((key) => {
@@ -279842,10 +280019,10 @@ function CreditsFlow({ onOpenAuthDialog }) {
279842
280019
  }
279843
280020
 
279844
280021
  // src/tui/context/keybinding.tsx
279845
- var import_react66 = __toESM(require_react(), 1);
280022
+ var import_react65 = __toESM(require_react(), 1);
279846
280023
 
279847
280024
  // src/tui/keybindings/keybind.tsx
279848
- var import_react62 = __toESM(require_react(), 1);
280025
+ var import_react61 = __toESM(require_react(), 1);
279849
280026
 
279850
280027
  // src/tui/keybindings/actions.ts
279851
280028
  var movementActions = [
@@ -280097,7 +280274,7 @@ var allActions = [
280097
280274
  var actionsByKey = new Map(allActions.map((action) => [action.key, action]));
280098
280275
  var actionsById = new Map(allActions.map((action) => [action.id, action]));
280099
280276
  // src/tui/keybindings/keybind.tsx
280100
- var LeaderKeyContext = import_react62.createContext(null);
280277
+ var LeaderKeyContext = import_react61.createContext(null);
280101
280278
  // src/tui/keybindings/registry.ts
280102
280279
  function createKeybindings(deps) {
280103
280280
  const {
@@ -280278,7 +280455,7 @@ function matchesKeybind(pressed, combo) {
280278
280455
  }
280279
280456
 
280280
280457
  // src/tui/context/keybinding.tsx
280281
- var KeybindingContext = import_react66.createContext(undefined);
280458
+ var KeybindingContext = import_react65.createContext(undefined);
280282
280459
  function KeybindingProvider({
280283
280460
  children,
280284
280461
  deps
@@ -280318,121 +280495,12 @@ function KeybindingProvider({
280318
280495
  }
280319
280496
 
280320
280497
  // src/tui/components/pentest/pentest.tsx
280321
- var import_react75 = __toESM(require_react(), 1);
280498
+ var import_react73 = __toESM(require_react(), 1);
280322
280499
  init_report();
280323
280500
  import { existsSync as existsSync26, readdirSync as readdirSync6, readFileSync as readFileSync12 } from "fs";
280324
280501
  import { join as join27 } from "path";
280325
280502
  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
- }
280503
+ init_loader();
280436
280504
 
280437
280505
  // src/core/api/blackboxPentest.ts
280438
280506
  init_pentest();
@@ -280459,7 +280527,7 @@ Found ${findings.length} vulnerabilities`);
280459
280527
  init_utils();
280460
280528
 
280461
280529
  // src/tui/components/agent-display.tsx
280462
- var import_react73 = __toESM(require_react(), 1);
280530
+ var import_react72 = __toESM(require_react(), 1);
280463
280531
 
280464
280532
  // node_modules/marked/lib/marked.esm.js
280465
280533
  function L2() {
@@ -282791,14 +282859,14 @@ ${preview}${suffix}` : preview + suffix || "POC passed",
282791
282859
  return null;
282792
282860
  }
282793
282861
  // src/tui/components/shared/ascii-spinner.tsx
282794
- var import_react67 = __toESM(require_react(), 1);
282862
+ var import_react66 = __toESM(require_react(), 1);
282795
282863
  var SPINNER_FRAMES = ["/", "-", "\\", "|"];
282796
282864
  var SPINNER_INTERVAL = 100;
282797
282865
  function AsciiSpinner({ label, fg: fg2 }) {
282798
282866
  const { colors: colors2 } = useTheme();
282799
282867
  const spinnerColor = fg2 ?? colors2.info;
282800
- const [frame, setFrame] = import_react67.useState(0);
282801
- import_react67.useEffect(() => {
282868
+ const [frame, setFrame] = import_react66.useState(0);
282869
+ import_react66.useEffect(() => {
282802
282870
  const interval = setInterval(() => {
282803
282871
  setFrame((f3) => (f3 + 1) % SPINNER_FRAMES.length);
282804
282872
  }, SPINNER_INTERVAL);
@@ -282810,7 +282878,7 @@ function AsciiSpinner({ label, fg: fg2 }) {
282810
282878
  }, undefined, false, undefined, this);
282811
282879
  }
282812
282880
  // src/tui/components/shared/tool-renderer.tsx
282813
- var import_react68 = __toESM(require_react(), 1);
282881
+ var import_react67 = __toESM(require_react(), 1);
282814
282882
  var TOOLS_WITH_LOG_WINDOW = new Set([
282815
282883
  "execute_command",
282816
282884
  "run_attack_surface",
@@ -282823,13 +282891,13 @@ var TOOLS_WITH_LOG_WINDOW = new Set([
282823
282891
  "document_vulnerability"
282824
282892
  ]);
282825
282893
  var DEFAULT_SUBAGENT_LOG_LINES = 5;
282826
- var ToolRenderer = import_react68.memo(function ToolRenderer2({
282894
+ var ToolRenderer = import_react67.memo(function ToolRenderer2({
282827
282895
  message,
282828
282896
  verbose = false,
282829
282897
  expandedLogs = false
282830
282898
  }) {
282831
282899
  const { colors: colors2 } = useTheme();
282832
- const [showOutput, setShowOutput] = import_react68.useState(false);
282900
+ const [showOutput, setShowOutput] = import_react67.useState(false);
282833
282901
  if (!isToolMessage(message)) {
282834
282902
  return null;
282835
282903
  }
@@ -282969,7 +283037,7 @@ var ToolRenderer = import_react68.memo(function ToolRenderer2({
282969
283037
  ]
282970
283038
  }, undefined, true, undefined, this);
282971
283039
  });
282972
- var SubagentLogWindow = import_react68.memo(function SubagentLogWindow2({
283040
+ var SubagentLogWindow = import_react67.memo(function SubagentLogWindow2({
282973
283041
  subagentId,
282974
283042
  entry,
282975
283043
  expandedLogs
@@ -283026,8 +283094,8 @@ var SubagentLogWindow = import_react68.memo(function SubagentLogWindow2({
283026
283094
  }, undefined, true, undefined, this);
283027
283095
  });
283028
283096
  // src/tui/components/shared/message-renderer.tsx
283029
- var import_react69 = __toESM(require_react(), 1);
283030
- var MessageRenderer = import_react69.memo(function MessageRenderer2({
283097
+ var import_react68 = __toESM(require_react(), 1);
283098
+ var MessageRenderer = import_react68.memo(function MessageRenderer2({
283031
283099
  message,
283032
283100
  isStreaming = false,
283033
283101
  verbose = false,
@@ -283037,7 +283105,7 @@ var MessageRenderer = import_react69.memo(function MessageRenderer2({
283037
283105
  }) {
283038
283106
  const { colors: colors2 } = useTheme();
283039
283107
  const content = typeof message.content === "string" ? message.content : JSON.stringify(message.content);
283040
- const displayContent = import_react69.useMemo(() => message.role === "assistant" ? markdownToStyledText(content, colors2) : content, [content, message.role, colors2]);
283108
+ const displayContent = import_react68.useMemo(() => message.role === "assistant" ? markdownToStyledText(content, colors2) : content, [content, message.role, colors2]);
283041
283109
  if (isToolMessage(message)) {
283042
283110
  return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ToolRenderer, {
283043
283111
  message,
@@ -283149,9 +283217,9 @@ var MessageRenderer = import_react69.memo(function MessageRenderer2({
283149
283217
  }, undefined, false, undefined, this);
283150
283218
  });
283151
283219
  // src/tui/components/shared/approval-prompt.tsx
283152
- var import_react70 = __toESM(require_react(), 1);
283220
+ var import_react69 = __toESM(require_react(), 1);
283153
283221
  // src/tui/components/shared/message-reducer.ts
283154
- var import_react72 = __toESM(require_react(), 1);
283222
+ var import_react71 = __toESM(require_react(), 1);
283155
283223
  // src/tui/components/agent-display.tsx
283156
283224
  function getStableKey(item, contextId = "root") {
283157
283225
  if ("messages" in item) {
@@ -283227,11 +283295,11 @@ function AgentDisplay({
283227
283295
  ]
283228
283296
  }, undefined, true, undefined, this);
283229
283297
  }
283230
- var SubAgentDisplay = import_react73.memo(function SubAgentDisplay2({
283298
+ var SubAgentDisplay = import_react72.memo(function SubAgentDisplay2({
283231
283299
  subagent
283232
283300
  }) {
283233
283301
  const { colors: colors2 } = useTheme();
283234
- const [open, setOpen] = import_react73.useState(false);
283302
+ const [open, setOpen] = import_react72.useState(false);
283235
283303
  return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
283236
283304
  height: open ? 40 : "auto",
283237
283305
  onMouseDown: () => setOpen(!open),
@@ -283286,11 +283354,11 @@ var SubAgentDisplay = import_react73.memo(function SubAgentDisplay2({
283286
283354
  ]
283287
283355
  }, undefined, true, undefined, this);
283288
283356
  });
283289
- var AgentMessage = import_react73.memo(function AgentMessage2({
283357
+ var AgentMessage = import_react72.memo(function AgentMessage2({
283290
283358
  message
283291
283359
  }) {
283292
283360
  const { colors: colors2 } = useTheme();
283293
- const dimensions = useTerminalDimensions();
283361
+ const dimensions = useDimensions();
283294
283362
  let content = "";
283295
283363
  if (typeof message.content === "string") {
283296
283364
  content = message.content;
@@ -283395,8 +283463,8 @@ var AgentMessage = import_react73.memo(function AgentMessage2({
283395
283463
  });
283396
283464
  function ToolDetails({ message }) {
283397
283465
  const { colors: colors2 } = useTheme();
283398
- const [showArgs, setShowArgs] = import_react73.useState(false);
283399
- const [showResult, setShowResult] = import_react73.useState(false);
283466
+ const [showArgs, setShowArgs] = import_react72.useState(false);
283467
+ const [showResult, setShowResult] = import_react72.useState(false);
283400
283468
  if (message.role !== "tool") {
283401
283469
  return null;
283402
283470
  }
@@ -283502,27 +283570,27 @@ function Pentest({
283502
283570
  const config3 = useConfig();
283503
283571
  const { model, setThinking, setIsExecuting, isExecuting } = useAgent();
283504
283572
  const { stack, externalDialogOpen } = useDialog();
283505
- const [session, setSession] = import_react75.useState(null);
283506
- const [error40, setError] = import_react75.useState(null);
283507
- const [phase, setPhase] = import_react75.useState("loading");
283508
- const [abortController, setAbortController] = import_react75.useState(null);
283509
- const [panelMessages, setPanelMessages] = import_react75.useState([]);
283510
- const panelTextRef = import_react75.useRef("");
283511
- const panelSourceRef = import_react75.useRef(null);
283512
- const [pentestAgents, setPentestAgents] = import_react75.useState({});
283513
- const pentestTextRefs = import_react75.useRef({});
283514
- const [assets, setAssets] = import_react75.useState([]);
283515
- const [viewMode, setViewMode] = import_react75.useState("overview");
283516
- const [selectedAgentId, setSelectedAgentId] = import_react75.useState(null);
283517
- const [focusedIndex, setFocusedIndex] = import_react75.useState(0);
283518
- const [showOrchestratorPanel, setShowOrchestratorPanel] = import_react75.useState(false);
283519
- const [startTime, setStartTime] = import_react75.useState(null);
283520
- const pentestAgentList = import_react75.useMemo(() => Object.values(pentestAgents).sort((a, b3) => a.createdAt.getTime() - b3.createdAt.getTime()), [pentestAgents]);
283521
- const selectedAgent = import_react75.useMemo(() => selectedAgentId ? pentestAgents[selectedAgentId] ?? null : null, [pentestAgents, selectedAgentId]);
283522
- const { width: termWidth } = useTerminalDimensions();
283573
+ const [session, setSession] = import_react73.useState(null);
283574
+ const [error40, setError] = import_react73.useState(null);
283575
+ const [phase, setPhase] = import_react73.useState("loading");
283576
+ const [abortController, setAbortController] = import_react73.useState(null);
283577
+ const [panelMessages, setPanelMessages] = import_react73.useState([]);
283578
+ const panelTextRef = import_react73.useRef("");
283579
+ const panelSourceRef = import_react73.useRef(null);
283580
+ const [pentestAgents, setPentestAgents] = import_react73.useState({});
283581
+ const pentestTextRefs = import_react73.useRef({});
283582
+ const [assets, setAssets] = import_react73.useState([]);
283583
+ const [viewMode, setViewMode] = import_react73.useState("overview");
283584
+ const [selectedAgentId, setSelectedAgentId] = import_react73.useState(null);
283585
+ const [focusedIndex, setFocusedIndex] = import_react73.useState(0);
283586
+ const [showOrchestratorPanel, setShowOrchestratorPanel] = import_react73.useState(false);
283587
+ const [startTime, setStartTime] = import_react73.useState(null);
283588
+ const pentestAgentList = import_react73.useMemo(() => Object.values(pentestAgents).sort((a, b3) => a.createdAt.getTime() - b3.createdAt.getTime()), [pentestAgents]);
283589
+ const selectedAgent = import_react73.useMemo(() => selectedAgentId ? pentestAgents[selectedAgentId] ?? null : null, [pentestAgents, selectedAgentId]);
283590
+ const { width: termWidth } = useDimensions();
283523
283591
  const gridAvailableWidth = showOrchestratorPanel ? Math.floor((termWidth - 4) / 2) - 2 : termWidth - ORCHESTRATOR_PANEL_WIDTH - GRID_OUTER_PADDING;
283524
283592
  const gridColumns = Math.max(1, Math.floor((gridAvailableWidth + GRID_GAP) / (CARD_MIN_WIDTH + GRID_GAP)));
283525
- import_react75.useEffect(() => {
283593
+ import_react73.useEffect(() => {
283526
283594
  async function load2() {
283527
283595
  try {
283528
283596
  let s2;
@@ -283568,6 +283636,9 @@ function Pentest({
283568
283636
  if (attackSurfaceAgents.some((sa) => sa.messages.length > 0)) {
283569
283637
  setShowOrchestratorPanel(true);
283570
283638
  }
283639
+ if (state.attackSurfaceResults?.summary?.analysisComplete) {
283640
+ setPhase("pentesting");
283641
+ }
283571
283642
  startPentest(s2);
283572
283643
  }
283573
283644
  } else {
@@ -283580,7 +283651,7 @@ function Pentest({
283580
283651
  }
283581
283652
  load2();
283582
283653
  }, [sessionId]);
283583
- import_react75.useEffect(() => {
283654
+ import_react73.useEffect(() => {
283584
283655
  if (!session)
283585
283656
  return;
283586
283657
  const assetsPath = join27(session.rootPath, "assets");
@@ -283603,12 +283674,12 @@ function Pentest({
283603
283674
  const interval = setInterval(readAssets, 2000);
283604
283675
  return () => clearInterval(interval);
283605
283676
  }, [session]);
283606
- import_react75.useEffect(() => {
283677
+ import_react73.useEffect(() => {
283607
283678
  return () => {
283608
283679
  abortController?.abort();
283609
283680
  };
283610
283681
  }, [abortController]);
283611
- const ensurePentestAgent = import_react75.useCallback((subagentId) => {
283682
+ const ensurePentestAgent = import_react73.useCallback((subagentId) => {
283612
283683
  setPentestAgents((prev) => {
283613
283684
  if (prev[subagentId])
283614
283685
  return prev;
@@ -283625,7 +283696,7 @@ function Pentest({
283625
283696
  };
283626
283697
  });
283627
283698
  }, []);
283628
- const handleSubagentSpawn = import_react75.useCallback(({
283699
+ const handleSubagentSpawn = import_react73.useCallback(({
283629
283700
  subagentId,
283630
283701
  input
283631
283702
  }) => {
@@ -283645,7 +283716,7 @@ function Pentest({
283645
283716
  }
283646
283717
  }));
283647
283718
  }, []);
283648
- const handleSubagentComplete = import_react75.useCallback(({ subagentId, status }) => {
283719
+ const handleSubagentComplete = import_react73.useCallback(({ subagentId, status }) => {
283649
283720
  if (!subagentId.startsWith("pentest-agent-"))
283650
283721
  return;
283651
283722
  setPentestAgents((prev) => {
@@ -283658,7 +283729,7 @@ function Pentest({
283658
283729
  };
283659
283730
  });
283660
283731
  }, []);
283661
- const appendPanelText = import_react75.useCallback((source, text2) => {
283732
+ const appendPanelText = import_react73.useCallback((source, text2) => {
283662
283733
  if (panelSourceRef.current !== source) {
283663
283734
  panelTextRef.current = "";
283664
283735
  panelSourceRef.current = source;
@@ -283683,7 +283754,7 @@ function Pentest({
283683
283754
  ];
283684
283755
  });
283685
283756
  }, []);
283686
- const appendPentestText = import_react75.useCallback((subagentId, text2) => {
283757
+ const appendPentestText = import_react73.useCallback((subagentId, text2) => {
283687
283758
  ensurePentestAgent(subagentId);
283688
283759
  if (!pentestTextRefs.current[subagentId]) {
283689
283760
  pentestTextRefs.current[subagentId] = "";
@@ -283716,8 +283787,8 @@ function Pentest({
283716
283787
  };
283717
283788
  });
283718
283789
  }, [ensurePentestAgent]);
283719
- const toolArgsDeltaRef = import_react75.useRef(new Map);
283720
- const addPanelStreamingToolCall = import_react75.useCallback((toolCallId, toolName) => {
283790
+ const toolArgsDeltaRef = import_react73.useRef(new Map);
283791
+ const addPanelStreamingToolCall = import_react73.useCallback((toolCallId, toolName) => {
283721
283792
  panelTextRef.current = "";
283722
283793
  panelSourceRef.current = null;
283723
283794
  toolArgsDeltaRef.current.set(toolCallId, "");
@@ -283736,7 +283807,7 @@ function Pentest({
283736
283807
  return [...prev, msg];
283737
283808
  });
283738
283809
  }, []);
283739
- const appendPanelToolCallDelta = import_react75.useCallback((toolCallId, argsTextDelta) => {
283810
+ const appendPanelToolCallDelta = import_react73.useCallback((toolCallId, argsTextDelta) => {
283740
283811
  const prev = toolArgsDeltaRef.current.get(toolCallId) ?? "";
283741
283812
  const accumulated = prev + argsTextDelta;
283742
283813
  toolArgsDeltaRef.current.set(toolCallId, accumulated);
@@ -283759,7 +283830,7 @@ function Pentest({
283759
283830
  return updated;
283760
283831
  });
283761
283832
  }, []);
283762
- const addPanelToolCall = import_react75.useCallback((toolCallId, toolName, args) => {
283833
+ const addPanelToolCall = import_react73.useCallback((toolCallId, toolName, args) => {
283763
283834
  panelTextRef.current = "";
283764
283835
  panelSourceRef.current = null;
283765
283836
  toolArgsDeltaRef.current.delete(toolCallId);
@@ -283791,7 +283862,7 @@ function Pentest({
283791
283862
  ];
283792
283863
  });
283793
283864
  }, []);
283794
- const addPentestStreamingToolCall = import_react75.useCallback((subagentId, toolCallId, toolName) => {
283865
+ const addPentestStreamingToolCall = import_react73.useCallback((subagentId, toolCallId, toolName) => {
283795
283866
  pentestTextRefs.current[subagentId] = "";
283796
283867
  ensurePentestAgent(subagentId);
283797
283868
  toolArgsDeltaRef.current.set(toolCallId, "");
@@ -283816,7 +283887,7 @@ function Pentest({
283816
283887
  };
283817
283888
  });
283818
283889
  }, [ensurePentestAgent]);
283819
- const appendPentestToolCallDelta = import_react75.useCallback((subagentId, toolCallId, argsTextDelta) => {
283890
+ const appendPentestToolCallDelta = import_react73.useCallback((subagentId, toolCallId, argsTextDelta) => {
283820
283891
  const prev = toolArgsDeltaRef.current.get(toolCallId) ?? "";
283821
283892
  const accumulated = prev + argsTextDelta;
283822
283893
  toolArgsDeltaRef.current.set(toolCallId, accumulated);
@@ -283842,7 +283913,7 @@ function Pentest({
283842
283913
  return { ...agents, [subagentId]: { ...agent, messages: updatedMsgs } };
283843
283914
  });
283844
283915
  }, []);
283845
- const addPentestToolCall = import_react75.useCallback((subagentId, toolCallId, toolName, args) => {
283916
+ const addPentestToolCall = import_react73.useCallback((subagentId, toolCallId, toolName, args) => {
283846
283917
  pentestTextRefs.current[subagentId] = "";
283847
283918
  ensurePentestAgent(subagentId);
283848
283919
  toolArgsDeltaRef.current.delete(toolCallId);
@@ -283903,12 +283974,12 @@ function Pentest({
283903
283974
  }
283904
283975
  ];
283905
283976
  };
283906
- const updatePanelToolResult = import_react75.useCallback((toolCallId, toolName, result) => {
283977
+ const updatePanelToolResult = import_react73.useCallback((toolCallId, toolName, result) => {
283907
283978
  panelTextRef.current = "";
283908
283979
  panelSourceRef.current = null;
283909
283980
  setPanelMessages((prev) => toolResultUpdater(prev, toolCallId, toolName, result));
283910
283981
  }, []);
283911
- const updatePentestToolResult = import_react75.useCallback((subagentId, toolCallId, toolName, result) => {
283982
+ const updatePentestToolResult = import_react73.useCallback((subagentId, toolCallId, toolName, result) => {
283912
283983
  pentestTextRefs.current[subagentId] = "";
283913
283984
  setPentestAgents((prev) => {
283914
283985
  const agent = prev[subagentId];
@@ -283923,11 +283994,12 @@ function Pentest({
283923
283994
  };
283924
283995
  });
283925
283996
  }, []);
283926
- const startPentest = import_react75.useCallback(async (s2) => {
283927
- setPhase("discovery");
283997
+ const startPentest = import_react73.useCallback(async (s2) => {
283998
+ setPhase((prev) => prev === "pentesting" || prev === "reporting" ? prev : "discovery");
283928
283999
  setStartTime(new Date);
283929
284000
  setIsExecuting(true);
283930
- setThinking(true);
284001
+ const discoveryDone = existsSync26(join27(s2.rootPath, "attack-surface-results.json"));
284002
+ setThinking(!discoveryDone);
283931
284003
  const controller = new AbortController;
283932
284004
  setAbortController(controller);
283933
284005
  try {
@@ -284050,7 +284122,7 @@ function Pentest({
284050
284122
  handleSubagentSpawn,
284051
284123
  handleSubagentComplete
284052
284124
  ]);
284053
- import_react75.useEffect(() => {
284125
+ import_react73.useEffect(() => {
284054
284126
  if (phase === "completed") {
284055
284127
  setFocusedIndex(pentestAgentList.length);
284056
284128
  }
@@ -284113,7 +284185,7 @@ function Pentest({
284113
284185
  }
284114
284186
  }
284115
284187
  });
284116
- const openReport = import_react75.useCallback(() => {
284188
+ const openReport = import_react73.useCallback(() => {
284117
284189
  if (!session)
284118
284190
  return;
284119
284191
  const err = openSessionReport(session.rootPath);
@@ -284298,7 +284370,7 @@ function OrchestratorPanel({
284298
284370
  }) {
284299
284371
  const { colors: colors2 } = useTheme();
284300
284372
  const isRunning = phase !== "loading" && phase !== "completed" && phase !== "error";
284301
- const assetSummary = import_react75.useMemo(() => {
284373
+ const assetSummary = import_react73.useMemo(() => {
284302
284374
  const byType = {};
284303
284375
  for (const a of assets) {
284304
284376
  const key = a.assetType;
@@ -284541,13 +284613,13 @@ function AgentCardGrid({
284541
284613
  onSelectAgent
284542
284614
  }) {
284543
284615
  const { colors: colors2 } = useTheme();
284544
- const scrollRef = import_react75.useRef(null);
284545
- import_react75.useEffect(() => {
284616
+ const scrollRef = import_react73.useRef(null);
284617
+ import_react73.useEffect(() => {
284546
284618
  const agent = agents[focusedIndex];
284547
284619
  if (agent)
284548
284620
  scrollToChild(scrollRef.current, agent.id);
284549
284621
  }, [focusedIndex, agents]);
284550
- const rows = import_react75.useMemo(() => {
284622
+ const rows = import_react73.useMemo(() => {
284551
284623
  const result = [];
284552
284624
  for (let i2 = 0;i2 < agents.length; i2 += gridColumns) {
284553
284625
  result.push(agents.slice(i2, i2 + gridColumns));
@@ -284604,14 +284676,14 @@ function AgentCard({
284604
284676
  completed: colors2.primary,
284605
284677
  failed: colors2.error
284606
284678
  }[agent.status];
284607
- const lastActivity = import_react75.useMemo(() => {
284679
+ const lastActivity = import_react73.useMemo(() => {
284608
284680
  const last = agent.messages[agent.messages.length - 1];
284609
284681
  if (!last)
284610
284682
  return "Starting...";
284611
284683
  const text2 = typeof last.content === "string" ? last.content.replace(/\n/g, " ").trim() : "Working...";
284612
284684
  return text2.length > 50 ? text2.substring(0, 47) + "..." : text2;
284613
284685
  }, [agent.messages]);
284614
- const toolCalls = import_react75.useMemo(() => agent.messages.filter((m4) => m4.role === "tool").length, [agent.messages]);
284686
+ const toolCalls = import_react73.useMemo(() => agent.messages.filter((m4) => m4.role === "tool").length, [agent.messages]);
284615
284687
  return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
284616
284688
  id: agent.id,
284617
284689
  flexGrow: 1,
@@ -284799,8 +284871,8 @@ function MetricsBar({
284799
284871
  isExecuting
284800
284872
  }) {
284801
284873
  const { colors: colors2 } = useTheme();
284802
- const [now2, setNow] = import_react75.useState(Date.now());
284803
- import_react75.useEffect(() => {
284874
+ const [now2, setNow] = import_react73.useState(Date.now());
284875
+ import_react73.useEffect(() => {
284804
284876
  if (!isExecuting)
284805
284877
  return;
284806
284878
  const interval = setInterval(() => setNow(Date.now()), 1000);
@@ -284943,7 +285015,7 @@ function MetricsBar({
284943
285015
  }
284944
285016
 
284945
285017
  // src/tui/components/operator-dashboard/index.tsx
284946
- var import_react80 = __toESM(require_react(), 1);
285018
+ var import_react78 = __toESM(require_react(), 1);
284947
285019
  init_session();
284948
285020
 
284949
285021
  // src/core/api/offesecAgent.ts
@@ -285046,7 +285118,7 @@ function InlineApprovalPrompt2({ approval }) {
285046
285118
  }
285047
285119
 
285048
285120
  // src/tui/components/chat/loading-indicator.tsx
285049
- var import_react77 = __toESM(require_react(), 1);
285121
+ var import_react75 = __toESM(require_react(), 1);
285050
285122
  var SPINNER_FRAMES2 = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
285051
285123
  var SPINNER_INTERVAL2 = 80;
285052
285124
  var DOTS_FRAMES = ["", ".", "..", "..."];
@@ -285057,15 +285129,15 @@ function LoadingIndicator({
285057
285129
  toolName
285058
285130
  }) {
285059
285131
  const { colors: colors2 } = useTheme();
285060
- const [spinnerFrame, setSpinnerFrame] = import_react77.useState(0);
285061
- const [dotsFrame, setDotsFrame] = import_react77.useState(0);
285062
- import_react77.useEffect(() => {
285132
+ const [spinnerFrame, setSpinnerFrame] = import_react75.useState(0);
285133
+ const [dotsFrame, setDotsFrame] = import_react75.useState(0);
285134
+ import_react75.useEffect(() => {
285063
285135
  const interval = setInterval(() => {
285064
285136
  setSpinnerFrame((f3) => (f3 + 1) % SPINNER_FRAMES2.length);
285065
285137
  }, SPINNER_INTERVAL2);
285066
285138
  return () => clearInterval(interval);
285067
285139
  }, []);
285068
- import_react77.useEffect(() => {
285140
+ import_react75.useEffect(() => {
285069
285141
  const interval = setInterval(() => {
285070
285142
  setDotsFrame((f3) => (f3 + 1) % DOTS_FRAMES.length);
285071
285143
  }, DOTS_INTERVAL);
@@ -285319,7 +285391,7 @@ function MessageList({
285319
285391
  }
285320
285392
 
285321
285393
  // src/tui/components/chat/input-area.tsx
285322
- var import_react78 = __toESM(require_react(), 1);
285394
+ var import_react76 = __toESM(require_react(), 1);
285323
285395
  function NormalInputAreaInner({
285324
285396
  value,
285325
285397
  onChange,
@@ -285341,10 +285413,10 @@ function NormalInputAreaInner({
285341
285413
  }) {
285342
285414
  const { colors: colors2, theme, mode: colorMode } = useTheme();
285343
285415
  const { inputValue, setInputValue } = useInput();
285344
- const promptRef = import_react78.useRef(null);
285345
- const isExternalUpdate = import_react78.useRef(false);
285346
- const prevValueRef = import_react78.useRef(value);
285347
- import_react78.useEffect(() => {
285416
+ const promptRef = import_react76.useRef(null);
285417
+ const isExternalUpdate = import_react76.useRef(false);
285418
+ const prevValueRef = import_react76.useRef(value);
285419
+ import_react76.useEffect(() => {
285348
285420
  const prevValue = prevValueRef.current;
285349
285421
  prevValueRef.current = value;
285350
285422
  if (value !== prevValue && value !== inputValue) {
@@ -285353,7 +285425,7 @@ function NormalInputAreaInner({
285353
285425
  promptRef.current?.setValue(value);
285354
285426
  }
285355
285427
  }, [value, inputValue, setInputValue]);
285356
- import_react78.useEffect(() => {
285428
+ import_react76.useEffect(() => {
285357
285429
  if (isExternalUpdate.current) {
285358
285430
  isExternalUpdate.current = false;
285359
285431
  return;
@@ -285528,7 +285600,7 @@ function ApprovalInputArea2({
285528
285600
  lastDeclineNote
285529
285601
  }) {
285530
285602
  const { colors: colors2 } = useTheme();
285531
- const [focusedElement, setFocusedElement] = import_react78.useState(0);
285603
+ const [focusedElement, setFocusedElement] = import_react76.useState(0);
285532
285604
  useKeyboard((key) => {
285533
285605
  if (key.name === "up") {
285534
285606
  setFocusedElement((prev) => Math.max(0, prev - 1));
@@ -285855,29 +285927,29 @@ function OperatorDashboard({
285855
285927
  clear: clearDialog,
285856
285928
  setSize: setDialogSize
285857
285929
  } = useDialog();
285858
- const autocompleteOptions = import_react80.useMemo(() => {
285930
+ const autocompleteOptions = import_react78.useMemo(() => {
285859
285931
  const skillSlugs = new Set(skills.map((s2) => `/${slugify(s2.name)}`));
285860
285932
  return filterOperatorAutocomplete(allAutocompleteOptions, skillSlugs);
285861
285933
  }, [allAutocompleteOptions, skills]);
285862
- const [session, setSession] = import_react80.useState(null);
285863
- const [loading, setLoading] = import_react80.useState(true);
285864
- const [error40, setError] = import_react80.useState(null);
285865
- const pendingNameRef = import_react80.useRef(null);
285866
- const [status, setStatus] = import_react80.useState("idle");
285867
- const abortControllerRef = import_react80.useRef(null);
285868
- const generationRef = import_react80.useRef(0);
285869
- const cancelHandleRef = import_react80.useRef({
285934
+ const [session, setSession] = import_react78.useState(null);
285935
+ const [loading, setLoading] = import_react78.useState(true);
285936
+ const [error40, setError] = import_react78.useState(null);
285937
+ const pendingNameRef = import_react78.useRef(null);
285938
+ const [status, setStatus] = import_react78.useState("idle");
285939
+ const abortControllerRef = import_react78.useRef(null);
285940
+ const generationRef = import_react78.useRef(0);
285941
+ const cancelHandleRef = import_react78.useRef({
285870
285942
  cancel: () => false
285871
285943
  });
285872
- const commandCancelledRef = import_react80.useRef(false);
285873
- const [messages, setMessages] = import_react80.useState([]);
285874
- const textRef = import_react80.useRef("");
285875
- const conversationRef = import_react80.useRef([]);
285876
- const [inputValue, setInputValue] = import_react80.useState("");
285877
- const [queuedMessages, setQueuedMessages] = import_react80.useState([]);
285878
- const [selectedQueueIndex, setSelectedQueueIndex] = import_react80.useState(-1);
285879
- const queuedMessagesRef = import_react80.useRef([]);
285880
- import_react80.useEffect(() => {
285944
+ const commandCancelledRef = import_react78.useRef(false);
285945
+ const [messages, setMessages] = import_react78.useState([]);
285946
+ const textRef = import_react78.useRef("");
285947
+ const conversationRef = import_react78.useRef([]);
285948
+ const [inputValue, setInputValue] = import_react78.useState("");
285949
+ const [queuedMessages, setQueuedMessages] = import_react78.useState([]);
285950
+ const [selectedQueueIndex, setSelectedQueueIndex] = import_react78.useState(-1);
285951
+ const queuedMessagesRef = import_react78.useRef([]);
285952
+ import_react78.useEffect(() => {
285881
285953
  queuedMessagesRef.current = queuedMessages;
285882
285954
  if (queuedMessages.length === 0) {
285883
285955
  setSelectedQueueIndex(-1);
@@ -285885,17 +285957,17 @@ function OperatorDashboard({
285885
285957
  setSelectedQueueIndex(queuedMessages.length - 1);
285886
285958
  }
285887
285959
  }, [queuedMessages, selectedQueueIndex]);
285888
- const [operatorState, setOperatorState] = import_react80.useState(() => createInitialOperatorState("manual", true));
285889
- const approvalGateRef = import_react80.useRef(new ApprovalGate({ requireApproval: true }));
285890
- const [pendingApprovals, setPendingApprovals] = import_react80.useState([]);
285891
- const [lastApprovedAction, setLastApprovedAction] = import_react80.useState(null);
285892
- const [verboseMode, setVerboseMode] = import_react80.useState(false);
285893
- const [expandedLogs, setExpandedLogs] = import_react80.useState(false);
285894
- const tokenUsageRef = import_react80.useRef(tokenUsage);
285895
- import_react80.useEffect(() => {
285960
+ const [operatorState, setOperatorState] = import_react78.useState(() => createInitialOperatorState("manual", true));
285961
+ const approvalGateRef = import_react78.useRef(new ApprovalGate({ requireApproval: true }));
285962
+ const [pendingApprovals, setPendingApprovals] = import_react78.useState([]);
285963
+ const [lastApprovedAction, setLastApprovedAction] = import_react78.useState(null);
285964
+ const [verboseMode, setVerboseMode] = import_react78.useState(false);
285965
+ const [expandedLogs, setExpandedLogs] = import_react78.useState(false);
285966
+ const tokenUsageRef = import_react78.useRef(tokenUsage);
285967
+ import_react78.useEffect(() => {
285896
285968
  tokenUsageRef.current = tokenUsage;
285897
285969
  }, [tokenUsage]);
285898
- import_react80.useEffect(() => {
285970
+ import_react78.useEffect(() => {
285899
285971
  const gate = approvalGateRef.current;
285900
285972
  const onApprovalNeeded = () => {
285901
285973
  setPendingApprovals(gate.getPendingApprovals());
@@ -285917,7 +285989,7 @@ function OperatorDashboard({
285917
285989
  gate.off("approval-resolved", onApprovalResolved);
285918
285990
  };
285919
285991
  }, []);
285920
- import_react80.useEffect(() => {
285992
+ import_react78.useEffect(() => {
285921
285993
  async function loadSession() {
285922
285994
  try {
285923
285995
  if (sessionId) {
@@ -285974,10 +286046,10 @@ function OperatorDashboard({
285974
286046
  }
285975
286047
  loadSession();
285976
286048
  }, [sessionId]);
285977
- import_react80.useEffect(() => {
286049
+ import_react78.useEffect(() => {
285978
286050
  return () => setSessionCwd(null);
285979
286051
  }, [setSessionCwd]);
285980
- import_react80.useEffect(() => {
286052
+ import_react78.useEffect(() => {
285981
286053
  if (!session)
285982
286054
  return;
285983
286055
  resetTokenUsage();
@@ -285995,7 +286067,7 @@ function OperatorDashboard({
285995
286067
  });
285996
286068
  } catch {}
285997
286069
  }, [session, addTokenUsage, resetTokenUsage]);
285998
- const appendText = import_react80.useCallback((text2) => {
286070
+ const appendText = import_react78.useCallback((text2) => {
285999
286071
  textRef.current += text2;
286000
286072
  const accumulated = textRef.current;
286001
286073
  setMessages((prev) => {
@@ -286011,8 +286083,8 @@ function OperatorDashboard({
286011
286083
  ];
286012
286084
  });
286013
286085
  }, []);
286014
- const toolArgsDeltaRef = import_react80.useRef(new Map);
286015
- const addStreamingToolCall = import_react80.useCallback((toolCallId, toolName) => {
286086
+ const toolArgsDeltaRef = import_react78.useRef(new Map);
286087
+ const addStreamingToolCall = import_react78.useCallback((toolCallId, toolName) => {
286016
286088
  textRef.current = "";
286017
286089
  toolArgsDeltaRef.current.set(toolCallId, {
286018
286090
  toolName,
@@ -286031,7 +286103,7 @@ function OperatorDashboard({
286031
286103
  }
286032
286104
  ]);
286033
286105
  }, []);
286034
- const appendToolCallDelta = import_react80.useCallback((toolCallId, argsTextDelta) => {
286106
+ const appendToolCallDelta = import_react78.useCallback((toolCallId, argsTextDelta) => {
286035
286107
  const entry = toolArgsDeltaRef.current.get(toolCallId);
286036
286108
  const accumulated = (entry?.accumulated ?? "") + argsTextDelta;
286037
286109
  toolArgsDeltaRef.current.set(toolCallId, {
@@ -286053,7 +286125,7 @@ function OperatorDashboard({
286053
286125
  return updated;
286054
286126
  });
286055
286127
  }, []);
286056
- const addToolCall = import_react80.useCallback((toolCallId, toolName, args) => {
286128
+ const addToolCall = import_react78.useCallback((toolCallId, toolName, args) => {
286057
286129
  textRef.current = "";
286058
286130
  toolArgsDeltaRef.current.delete(toolCallId);
286059
286131
  setMessages((prev) => {
@@ -286082,7 +286154,7 @@ function OperatorDashboard({
286082
286154
  ];
286083
286155
  });
286084
286156
  }, []);
286085
- const updateToolResult = import_react80.useCallback((toolCallId, _toolName, result) => {
286157
+ const updateToolResult = import_react78.useCallback((toolCallId, _toolName, result) => {
286086
286158
  textRef.current = "";
286087
286159
  setMessages((prev) => {
286088
286160
  const idx = prev.findIndex((m4) => isToolMessage(m4) && m4.toolCallId === toolCallId);
@@ -286093,10 +286165,10 @@ function OperatorDashboard({
286093
286165
  return updated;
286094
286166
  });
286095
286167
  }, []);
286096
- const cmdOutputBufRef = import_react80.useRef("");
286097
- const cmdFlushTimerRef = import_react80.useRef(null);
286168
+ const cmdOutputBufRef = import_react78.useRef("");
286169
+ const cmdFlushTimerRef = import_react78.useRef(null);
286098
286170
  const MAX_LOG_LINES = 200;
286099
- const flushCommandOutput = import_react80.useCallback(() => {
286171
+ const flushCommandOutput = import_react78.useCallback(() => {
286100
286172
  const buf = cmdOutputBufRef.current;
286101
286173
  if (!buf)
286102
286174
  return;
@@ -286126,7 +286198,7 @@ function OperatorDashboard({
286126
286198
  return updated;
286127
286199
  });
286128
286200
  }, []);
286129
- const onCommandOutput = import_react80.useCallback((data) => {
286201
+ const onCommandOutput = import_react78.useCallback((data) => {
286130
286202
  cmdOutputBufRef.current += data;
286131
286203
  if (!cmdFlushTimerRef.current) {
286132
286204
  cmdFlushTimerRef.current = setInterval(() => {
@@ -286134,7 +286206,7 @@ function OperatorDashboard({
286134
286206
  }, 150);
286135
286207
  }
286136
286208
  }, [flushCommandOutput]);
286137
- import_react80.useEffect(() => {
286209
+ import_react78.useEffect(() => {
286138
286210
  return () => {
286139
286211
  if (cmdFlushTimerRef.current) {
286140
286212
  clearInterval(cmdFlushTimerRef.current);
@@ -286142,7 +286214,7 @@ function OperatorDashboard({
286142
286214
  }
286143
286215
  };
286144
286216
  }, []);
286145
- const appendLogToActiveTool = import_react80.useCallback((line) => {
286217
+ const appendLogToActiveTool = import_react78.useCallback((line) => {
286146
286218
  setMessages((prev) => {
286147
286219
  const idx = prev.findLastIndex((m4) => isToolMessage(m4) && (m4.status === "pending" || m4.status === "streaming"));
286148
286220
  if (idx === -1)
@@ -286157,7 +286229,7 @@ function OperatorDashboard({
286157
286229
  return updated;
286158
286230
  });
286159
286231
  }, []);
286160
- const initSubagent = import_react80.useCallback((subagentId, name26) => {
286232
+ const initSubagent = import_react78.useCallback((subagentId, name26) => {
286161
286233
  setMessages((prev) => {
286162
286234
  const idx = prev.findLastIndex((m4) => isToolMessage(m4) && (m4.status === "pending" || m4.status === "streaming"));
286163
286235
  if (idx === -1)
@@ -286172,7 +286244,7 @@ function OperatorDashboard({
286172
286244
  return updated;
286173
286245
  });
286174
286246
  }, []);
286175
- const completeSubagent = import_react80.useCallback((subagentId, status2) => {
286247
+ const completeSubagent = import_react78.useCallback((subagentId, status2) => {
286176
286248
  setMessages((prev) => {
286177
286249
  const idx = prev.findLastIndex((m4) => isToolMessage(m4) && (m4.status === "pending" || m4.status === "streaming"));
286178
286250
  if (idx === -1)
@@ -286190,7 +286262,7 @@ function OperatorDashboard({
286190
286262
  return updated;
286191
286263
  });
286192
286264
  }, []);
286193
- const appendLogToSubagent = import_react80.useCallback((subagentId, line) => {
286265
+ const appendLogToSubagent = import_react78.useCallback((subagentId, line) => {
286194
286266
  setMessages((prev) => {
286195
286267
  const idx = prev.findLastIndex((m4) => isToolMessage(m4) && (m4.status === "pending" || m4.status === "streaming"));
286196
286268
  if (idx === -1)
@@ -286212,13 +286284,13 @@ function OperatorDashboard({
286212
286284
  return updated;
286213
286285
  });
286214
286286
  }, []);
286215
- const handleApprove = import_react80.useCallback(() => {
286287
+ const handleApprove = import_react78.useCallback(() => {
286216
286288
  const pending = approvalGateRef.current.getPendingApprovals();
286217
286289
  if (pending.length > 0) {
286218
286290
  approvalGateRef.current.approve(pending[0].id);
286219
286291
  }
286220
286292
  }, []);
286221
- const handleAutoApprove = import_react80.useCallback(() => {
286293
+ const handleAutoApprove = import_react78.useCallback(() => {
286222
286294
  approvalGateRef.current.updateConfig({ requireApproval: false });
286223
286295
  setOperatorState((prev) => ({ ...prev, requireApproval: false }));
286224
286296
  const pending = approvalGateRef.current.getPendingApprovals();
@@ -286226,7 +286298,7 @@ function OperatorDashboard({
286226
286298
  approvalGateRef.current.approve(p.id);
286227
286299
  }
286228
286300
  }, []);
286229
- const runAgent = import_react80.useCallback(async (prompt) => {
286301
+ const runAgent = import_react78.useCallback(async (prompt) => {
286230
286302
  if (abortControllerRef.current) {
286231
286303
  abortControllerRef.current.abort();
286232
286304
  abortControllerRef.current = null;
@@ -286440,7 +286512,7 @@ function OperatorDashboard({
286440
286512
  setThinking,
286441
286513
  setIsExecuting
286442
286514
  ]);
286443
- const handleSubmit = import_react80.useCallback((value) => {
286515
+ const handleSubmit = import_react78.useCallback((value) => {
286444
286516
  const pending = approvalGateRef.current.getPendingApprovals();
286445
286517
  const result = resolveSubmit(value, status, pending.length > 0);
286446
286518
  if (result.denyPending) {
@@ -286458,16 +286530,16 @@ function OperatorDashboard({
286458
286530
  setInputValue("");
286459
286531
  runAgent(result.prompt);
286460
286532
  }, [status, runAgent]);
286461
- const initialMessageSentRef = import_react80.useRef(false);
286462
- const runAgentRef = import_react80.useRef(runAgent);
286533
+ const initialMessageSentRef = import_react78.useRef(false);
286534
+ const runAgentRef = import_react78.useRef(runAgent);
286463
286535
  runAgentRef.current = runAgent;
286464
- import_react80.useEffect(() => {
286536
+ import_react78.useEffect(() => {
286465
286537
  if (!loading && initialMessage && !initialMessageSentRef.current) {
286466
286538
  initialMessageSentRef.current = true;
286467
286539
  runAgentRef.current(initialMessage);
286468
286540
  }
286469
286541
  }, [loading, initialMessage]);
286470
- import_react80.useEffect(() => {
286542
+ import_react78.useEffect(() => {
286471
286543
  if (status !== "idle")
286472
286544
  return;
286473
286545
  const queue = queuedMessagesRef.current;
@@ -286478,7 +286550,7 @@ function OperatorDashboard({
286478
286550
  setSelectedQueueIndex(-1);
286479
286551
  runAgentRef.current(next);
286480
286552
  }, [status]);
286481
- const showModelPicker = import_react80.useCallback(() => {
286553
+ const showModelPicker = import_react78.useCallback(() => {
286482
286554
  setDialogSize("large");
286483
286555
  showDialog(/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
286484
286556
  flexDirection: "column",
@@ -286540,7 +286612,7 @@ function OperatorDashboard({
286540
286612
  clearDialog,
286541
286613
  setDialogSize
286542
286614
  ]);
286543
- const handleCommandExecute = import_react80.useCallback(async (command) => {
286615
+ const handleCommandExecute = import_react78.useCallback(async (command) => {
286544
286616
  const action = routeCommand(command, resolveSkillContent);
286545
286617
  switch (action.type) {
286546
286618
  case "show-models":
@@ -286558,7 +286630,7 @@ function OperatorDashboard({
286558
286630
  return;
286559
286631
  }
286560
286632
  }, [resolveSkillContent, handleSubmit, executeCommand2, showModelPicker]);
286561
- const handleAbort = import_react80.useCallback(() => {
286633
+ const handleAbort = import_react78.useCallback(() => {
286562
286634
  if (!abortControllerRef.current)
286563
286635
  return;
286564
286636
  const action = resolveAbortAction(commandCancelledRef.current, () => cancelHandleRef.current.cancel());
@@ -286608,7 +286680,7 @@ function OperatorDashboard({
286608
286680
  ];
286609
286681
  });
286610
286682
  }, [session, setThinking, setIsExecuting]);
286611
- const toggleApproval = import_react80.useCallback(() => {
286683
+ const toggleApproval = import_react78.useCallback(() => {
286612
286684
  setOperatorState((prev) => {
286613
286685
  const newVal = !prev.requireApproval;
286614
286686
  approvalGateRef.current.updateConfig({ requireApproval: newVal });
@@ -286842,10 +286914,10 @@ function OperatorDashboard({
286842
286914
  }
286843
286915
 
286844
286916
  // src/tui/components/commands/theme-picker.tsx
286845
- var import_react82 = __toESM(require_react(), 1);
286917
+ var import_react80 = __toESM(require_react(), 1);
286846
286918
  init_config2();
286847
286919
  function ThemePicker({ onClose }) {
286848
- const dimensions = useTerminalDimensions();
286920
+ const dimensions = useDimensions();
286849
286921
  const {
286850
286922
  colors: colors2,
286851
286923
  theme,
@@ -286855,15 +286927,15 @@ function ThemePicker({ onClose }) {
286855
286927
  toggleMode,
286856
286928
  setMode
286857
286929
  } = useTheme();
286858
- const [selectedIndex, setSelectedIndex] = import_react82.useState(() => Math.max(0, availableThemes.indexOf(theme.name)));
286859
- const originalThemeRef = import_react82.useRef(theme.name);
286860
- const originalModeRef = import_react82.useRef(mode);
286861
- const handleClose = import_react82.useCallback(() => {
286930
+ const [selectedIndex, setSelectedIndex] = import_react80.useState(() => Math.max(0, availableThemes.indexOf(theme.name)));
286931
+ const originalThemeRef = import_react80.useRef(theme.name);
286932
+ const originalModeRef = import_react80.useRef(mode);
286933
+ const handleClose = import_react80.useCallback(() => {
286862
286934
  setTheme(originalThemeRef.current);
286863
286935
  setMode(originalModeRef.current);
286864
286936
  onClose();
286865
286937
  }, [setTheme, setMode, onClose]);
286866
- const handleConfirm = import_react82.useCallback(async () => {
286938
+ const handleConfirm = import_react80.useCallback(async () => {
286867
286939
  const currentThemeName = availableThemes[selectedIndex];
286868
286940
  if (currentThemeName) {
286869
286941
  await config2.update({ theme: currentThemeName });
@@ -286992,16 +287064,16 @@ function ThemePicker({ onClose }) {
286992
287064
  }
286993
287065
 
286994
287066
  // src/tui/components/commands/create-skill-wizard.tsx
286995
- var import_react84 = __toESM(require_react(), 1);
287067
+ var import_react82 = __toESM(require_react(), 1);
286996
287068
  function CreateSkillWizard() {
286997
287069
  const { colors: colors2 } = useTheme();
286998
287070
  const route = useRoute();
286999
- const [step, setStep] = import_react84.useState("name");
287000
- const [name26, setName] = import_react84.useState("");
287001
- const [description, setDescription] = import_react84.useState("");
287002
- const [content, setContent] = import_react84.useState("");
287003
- const [error40, setError] = import_react84.useState(null);
287004
- const [confirmFocused, setConfirmFocused] = import_react84.useState(0);
287071
+ const [step, setStep] = import_react82.useState("name");
287072
+ const [name26, setName] = import_react82.useState("");
287073
+ const [description, setDescription] = import_react82.useState("");
287074
+ const [content, setContent] = import_react82.useState("");
287075
+ const [error40, setError] = import_react82.useState(null);
287076
+ const [confirmFocused, setConfirmFocused] = import_react82.useState(0);
287005
287077
  const slug = slugify(name26);
287006
287078
  async function handleSave() {
287007
287079
  if (!name26.trim() || !content.trim())
@@ -289877,7 +289949,7 @@ async function detectTerminalMode(timeoutMs = 1000) {
289877
289949
  }
289878
289950
 
289879
289951
  // src/tui/console-theme.ts
289880
- var import_react86 = __toESM(require_react(), 1);
289952
+ var import_react84 = __toESM(require_react(), 1);
289881
289953
  var withAlpha = (rgba, a) => RGBA.fromValues(rgba.r, rgba.g, rgba.b, a);
289882
289954
  var overlayThemeRef = {
289883
289955
  current: null
@@ -289900,7 +289972,7 @@ function buildConsoleOptions(themeColors) {
289900
289972
  function ConsoleThemeSync() {
289901
289973
  const { colors: colors2 } = useTheme();
289902
289974
  const renderer = useRenderer();
289903
- import_react86.useEffect(() => {
289975
+ import_react84.useEffect(() => {
289904
289976
  overlayThemeRef.current = colors2;
289905
289977
  const c = renderer.console;
289906
289978
  c.backgroundColor = withAlpha(colors2.backgroundPanel, 0.85);
@@ -289988,17 +290060,17 @@ function setupAutoCopy(renderer, copyToClipboard) {
289988
290060
 
289989
290061
  // src/tui/index.tsx
289990
290062
  function App({ appConfig }) {
289991
- const [focusIndex, setFocusIndex] = import_react89.useState(0);
289992
- const [cwd, setCwd] = import_react89.useState(process.cwd());
289993
- const [ctrlCPressTime, setCtrlCPressTime] = import_react89.useState(null);
289994
- const [showExitWarning, setShowExitWarning] = import_react89.useState(false);
289995
- const [inputKey, setInputKey] = import_react89.useState(0);
289996
- const [showSessionsDialog, setShowSessionsDialog] = import_react89.useState(false);
289997
- const [showShortcutsDialog, setShowShortcutsDialog] = import_react89.useState(false);
289998
- const [showThemeDialog, setShowThemeDialog] = import_react89.useState(false);
289999
- const [showAuthDialog, setShowAuthDialog] = import_react89.useState(false);
290000
- const [showPentestDialog, setShowPentestDialog] = import_react89.useState(false);
290001
- const [pendingPentestFlags, setPendingPentestFlags] = import_react89.useState(undefined);
290063
+ const [focusIndex, setFocusIndex] = import_react87.useState(0);
290064
+ const [cwd, setCwd] = import_react87.useState(process.cwd());
290065
+ const [ctrlCPressTime, setCtrlCPressTime] = import_react87.useState(null);
290066
+ const [showExitWarning, setShowExitWarning] = import_react87.useState(false);
290067
+ const [inputKey, setInputKey] = import_react87.useState(0);
290068
+ const [showSessionsDialog, setShowSessionsDialog] = import_react87.useState(false);
290069
+ const [showShortcutsDialog, setShowShortcutsDialog] = import_react87.useState(false);
290070
+ const [showThemeDialog, setShowThemeDialog] = import_react87.useState(false);
290071
+ const [showAuthDialog, setShowAuthDialog] = import_react87.useState(false);
290072
+ const [showPentestDialog, setShowPentestDialog] = import_react87.useState(false);
290073
+ const [pendingPentestFlags, setPendingPentestFlags] = import_react87.useState(undefined);
290002
290074
  const navigableItems = ["command-input"];
290003
290075
  return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ConfigProvider, {
290004
290076
  config: appConfig,
@@ -290085,14 +290157,14 @@ function AppContent({
290085
290157
  const { toast } = useToast();
290086
290158
  const { refocusPrompt } = useFocus();
290087
290159
  const { setExternalDialogOpen } = useDialog();
290088
- import_react89.useEffect(() => {
290160
+ import_react87.useEffect(() => {
290089
290161
  checkForUpdate().then(({ updateAvailable, currentVersion, latestVersion }) => {
290090
290162
  if (!updateAvailable)
290091
290163
  return;
290092
290164
  toast(`Update available: v${currentVersion} → v${latestVersion}. Run: pensar upgrade`, "warn", 8000);
290093
290165
  });
290094
290166
  }, []);
290095
- import_react89.useEffect(() => {
290167
+ import_react87.useEffect(() => {
290096
290168
  if (route.data.type !== "base")
290097
290169
  return;
290098
290170
  if (!config3.data.responsibleUseAccepted && route.data.path !== "disclosure") {
@@ -290101,12 +290173,12 @@ function AppContent({
290101
290173
  route.navigate({ type: "base", path: "providers" });
290102
290174
  }
290103
290175
  }, [config3.data.responsibleUseAccepted, route.data]);
290104
- import_react89.useEffect(() => {
290176
+ import_react87.useEffect(() => {
290105
290177
  if (showThemeDialog || showAuthDialog || showPentestDialog) {
290106
290178
  setExternalDialogOpen(true);
290107
290179
  }
290108
290180
  }, [showThemeDialog, showAuthDialog, showPentestDialog]);
290109
- import_react89.useEffect(() => {
290181
+ import_react87.useEffect(() => {
290110
290182
  if (showExitWarning) {
290111
290183
  const timer = setTimeout(() => {
290112
290184
  setShowExitWarning(false);
@@ -290360,16 +290432,18 @@ async function main2() {
290360
290432
  initialMode: mode,
290361
290433
  children: [
290362
290434
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ConsoleThemeSync, {}, undefined, false, undefined, this),
290363
- /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ToastProvider, {
290364
- children: [
290365
- /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ErrorBoundary2, {
290366
- children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(App, {
290367
- appConfig
290368
- }, undefined, false, undefined, this)
290369
- }, undefined, false, undefined, this),
290370
- /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ToastContainer, {}, undefined, false, undefined, this)
290371
- ]
290372
- }, undefined, true, undefined, this)
290435
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(TerminalDimensionsProvider, {
290436
+ children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ToastProvider, {
290437
+ children: [
290438
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ErrorBoundary2, {
290439
+ children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(App, {
290440
+ appConfig
290441
+ }, undefined, false, undefined, this)
290442
+ }, undefined, false, undefined, this),
290443
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ToastContainer, {}, undefined, false, undefined, this)
290444
+ ]
290445
+ }, undefined, true, undefined, this)
290446
+ }, undefined, false, undefined, this)
290373
290447
  ]
290374
290448
  }, undefined, true, undefined, this));
290375
290449
  }