@pensar/apex 0.0.54 → 0.0.55-canary.02c66dc2

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 +358 -70
  2. package/package.json +1 -1
package/build/index.js CHANGED
@@ -69284,7 +69284,7 @@ function createRoot(renderer) {
69284
69284
  }
69285
69285
 
69286
69286
  // src/tui/index.tsx
69287
- var import_react84 = __toESM(require_react(), 1);
69287
+ var import_react86 = __toESM(require_react(), 1);
69288
69288
 
69289
69289
  // src/tui/components/footer.tsx
69290
69290
  import os5 from "os";
@@ -70407,6 +70407,7 @@ init_zod();
70407
70407
  import os3 from "os";
70408
70408
  import path3 from "path";
70409
70409
  import fs3 from "fs/promises";
70410
+ import { readdir } from "fs/promises";
70410
70411
 
70411
70412
  // src/util/errors.ts
70412
70413
  init_zod();
@@ -70532,7 +70533,6 @@ var Lock;
70532
70533
  })(Lock ||= {});
70533
70534
 
70534
70535
  // src/core/storage/index.ts
70535
- import { mkdir } from "fs/promises";
70536
70536
  var Storage;
70537
70537
  ((Storage) => {
70538
70538
  Storage.NotFoundError = NamedError.create("NotFoundError", zod_default.object({
@@ -70559,7 +70559,8 @@ var Storage;
70559
70559
  let __stack = [];
70560
70560
  try {
70561
70561
  const _ = __using(__stack, await Lock.write(target), 0);
70562
- await Bun.write(target, JSON.stringify(content, null, 2));
70562
+ await fs3.mkdir(path3.dirname(target), { recursive: true });
70563
+ await fs3.writeFile(target, JSON.stringify(content, null, 2), "utf-8");
70563
70564
  } catch (_catch) {
70564
70565
  var _err = _catch, _hasErr = 1;
70565
70566
  } finally {
@@ -70575,7 +70576,7 @@ var Storage;
70575
70576
  let __stack = [];
70576
70577
  try {
70577
70578
  const _ = __using(__stack, await Lock.write(target), 0);
70578
- await mkdir(target, { recursive: true });
70579
+ await fs3.mkdir(target, { recursive: true });
70579
70580
  } catch (_catch) {
70580
70581
  var _err = _catch, _hasErr = 1;
70581
70582
  } finally {
@@ -70592,8 +70593,8 @@ var Storage;
70592
70593
  try {
70593
70594
  const _ = __using(__stack, await Lock.write(target), 0);
70594
70595
  const parentDir = path3.dirname(target);
70595
- await mkdir(parentDir, { recursive: true });
70596
- await Bun.write(target, content);
70596
+ await fs3.mkdir(parentDir, { recursive: true });
70597
+ await fs3.writeFile(target, content, "utf-8");
70597
70598
  } catch (_catch) {
70598
70599
  var _err = _catch, _hasErr = 1;
70599
70600
  } finally {
@@ -70610,7 +70611,7 @@ var Storage;
70610
70611
  try {
70611
70612
  const _ = __using(__stack, await Lock.write(target), 0);
70612
70613
  const parentDir = path3.dirname(target);
70613
- await mkdir(parentDir, { recursive: true });
70614
+ await fs3.mkdir(parentDir, { recursive: true });
70614
70615
  await fs3.appendFile(target, content);
70615
70616
  } catch (_catch) {
70616
70617
  var _err = _catch, _hasErr = 1;
@@ -70627,7 +70628,8 @@ var Storage;
70627
70628
  let __stack = [];
70628
70629
  try {
70629
70630
  const _ = __using(__stack, await Lock.read(target), 0);
70630
- const result = ext ? await Bun.file(target).text() : await Bun.file(target).json();
70631
+ const text = await fs3.readFile(target, "utf-8");
70632
+ const result = ext ? text : JSON.parse(text);
70631
70633
  return result;
70632
70634
  } catch (_catch) {
70633
70635
  var _err = _catch, _hasErr = 1;
@@ -70644,9 +70646,10 @@ var Storage;
70644
70646
  let __stack = [];
70645
70647
  try {
70646
70648
  const _ = __using(__stack, await Lock.write(target), 0);
70647
- const content = ext ? await Bun.file(target).text() : await Bun.file(target).json();
70649
+ const text = await fs3.readFile(target, "utf-8");
70650
+ const content = ext ? text : JSON.parse(text);
70648
70651
  fn(content);
70649
- await Bun.write(target, JSON.stringify(content, null, 2));
70652
+ await fs3.writeFile(target, JSON.stringify(content, null, 2), "utf-8");
70650
70653
  return content;
70651
70654
  } catch (_catch) {
70652
70655
  var _err = _catch, _hasErr = 1;
@@ -70667,14 +70670,28 @@ var Storage;
70667
70670
  throw e;
70668
70671
  });
70669
70672
  }
70670
- const glob = new Bun.Glob("**/*");
70673
+ async function listFilesRecursively(dir) {
70674
+ const entries = await readdir(dir, { withFileTypes: true });
70675
+ const files = [];
70676
+ for (const entry of entries) {
70677
+ const fullPath = path3.join(dir, entry.name);
70678
+ if (entry.isDirectory()) {
70679
+ files.push(...await listFilesRecursively(fullPath));
70680
+ } else {
70681
+ files.push(fullPath);
70682
+ }
70683
+ }
70684
+ return files;
70685
+ }
70671
70686
  async function list(prefix) {
70672
70687
  const dir = path3.join(os3.homedir(), ".pensar");
70688
+ const targetDir = path3.join(dir, ...prefix);
70673
70689
  try {
70674
- const result = await Array.fromAsync(glob.scan({
70675
- cwd: path3.join(dir, ...prefix),
70676
- onlyFiles: true
70677
- })).then((results) => results.map((x) => [...prefix, ...x.slice(0, -5).split(path3.sep)]));
70690
+ const files = await listFilesRecursively(targetDir);
70691
+ const result = files.map((filePath) => {
70692
+ const relativePath = path3.relative(targetDir, filePath);
70693
+ return [...prefix, ...relativePath.slice(0, -5).split(path3.sep)];
70694
+ });
70678
70695
  result.sort();
70679
70696
  return result;
70680
70697
  } catch {
@@ -71907,7 +71924,7 @@ var commands = [
71907
71924
  handler: async (args, ctx3) => {
71908
71925
  ctx3.navigate({
71909
71926
  type: "base",
71910
- path: "chat"
71927
+ path: "home"
71911
71928
  });
71912
71929
  }
71913
71930
  },
@@ -136231,6 +136248,7 @@ async function runAuthenticationSubagent(opts) {
136231
136248
  const {
136232
136249
  input,
136233
136250
  model,
136251
+ authConfig,
136234
136252
  onStepFinish,
136235
136253
  abortSignal,
136236
136254
  httpRequestOverride,
@@ -136334,6 +136352,7 @@ Provide a clear summary of the authentication outcome.`,
136334
136352
  system: systemPrompt,
136335
136353
  model,
136336
136354
  tools,
136355
+ authConfig,
136337
136356
  onStepFinish: (step) => {
136338
136357
  if (step.toolCalls?.length > 0 || step.text) {
136339
136358
  messagesRef.current.push({
@@ -136486,7 +136505,8 @@ async function runAgent(opts) {
136486
136505
  onToolTokenUsage,
136487
136506
  toolOverride,
136488
136507
  persistence,
136489
- existingState
136508
+ existingState,
136509
+ authConfig
136490
136510
  } = opts;
136491
136511
  const session = opts.session || await Session.create({
136492
136512
  targets: [target],
@@ -137259,7 +137279,8 @@ You MUST provide the final report using create_attack_surface_report tool.
137259
137279
  stopWhen: stepCountIs(1e4),
137260
137280
  toolChoice: "auto",
137261
137281
  onStepFinish,
137262
- abortSignal
137282
+ abortSignal,
137283
+ authConfig
137263
137284
  });
137264
137285
  streamResult.session = session;
137265
137286
  return { streamResult, session };
@@ -141737,7 +141758,7 @@ function saveAgentMessages2(sessionRootPath, agentName, messages, metadata) {
141737
141758
  return filepath;
141738
141759
  }
141739
141760
  async function runAuthBypassAgent(opts) {
141740
- const { input, model, toolOverride, abortSignal } = opts;
141761
+ const { input, model, authConfig, toolOverride, abortSignal } = opts;
141741
141762
  const { session } = input;
141742
141763
  const logger = new Logger({
141743
141764
  id: session.id,
@@ -141850,6 +141871,7 @@ async function runAuthBypassAgent(opts) {
141850
141871
  system: AUTH_BYPASS_SYSTEM_PROMPT,
141851
141872
  model,
141852
141873
  tools: tools2,
141874
+ authConfig,
141853
141875
  stopWhen: hasToolCall("complete_testing"),
141854
141876
  abortSignal,
141855
141877
  silent: true
@@ -141890,7 +141912,7 @@ async function runAuthBypassAgent(opts) {
141890
141912
  };
141891
141913
  }
141892
141914
  }
141893
- function createAuthBypassTool(sessionInfo, logger, model, toolOverride) {
141915
+ function createAuthBypassTool(sessionInfo, logger, model, toolOverride, authConfig) {
141894
141916
  return tool2({
141895
141917
  description: `Spawn a specialized Authorization Bypass Testing Agent.
141896
141918
 
@@ -141929,6 +141951,7 @@ Provide the authentication context you've discovered (endpoints, parameters, cre
141929
141951
  session: sessionInfo
141930
141952
  },
141931
141953
  model,
141954
+ authConfig,
141932
141955
  toolOverride
141933
141956
  });
141934
141957
  return {
@@ -142078,6 +142101,7 @@ async function runMetaVulnerabilityTestAgent(opts) {
142078
142101
  const {
142079
142102
  input,
142080
142103
  model,
142104
+ authConfig,
142081
142105
  remoteSandboxUrl,
142082
142106
  onStepFinish,
142083
142107
  onChunk,
@@ -142133,7 +142157,7 @@ async function runMetaVulnerabilityTestAgent(opts) {
142133
142157
  });
142134
142158
  const { store_plan, get_plan, store_adaptation } = createPlanMemoryTools(sessionInfo, logger);
142135
142159
  const { optimize_prompt } = createPromptOptimizerTool(sessionInfo, logger);
142136
- const auth_bypass_test = createAuthBypassTool(sessionInfo, logger, model, toolOverride);
142160
+ const auth_bypass_test = createAuthBypassTool(sessionInfo, logger, model, toolOverride, authConfig);
142137
142161
  const spawn_vulnerability_test = tool2({
142138
142162
  description: `Spawn a NEW vulnerability test agent for a DIFFERENT vulnerability class than your current assignment.
142139
142163
 
@@ -142251,6 +142275,7 @@ Call when:
142251
142275
  system: systemPrompt,
142252
142276
  model,
142253
142277
  tools: tools2,
142278
+ authConfig,
142254
142279
  onStepFinish: (step) => {
142255
142280
  if (step.toolCalls?.length > 0 || step.text) {
142256
142281
  messagesRef.current.push({
@@ -142452,6 +142477,7 @@ Objective: ${target.objective}`,
142452
142477
  const result = await runMetaVulnerabilityTestAgent({
142453
142478
  input,
142454
142479
  model: this.config.model,
142480
+ authConfig: this.config.authConfig,
142455
142481
  abortSignal: this.abortController.signal,
142456
142482
  onStepFinish: async (step) => {
142457
142483
  if (this.pausePromise) {
@@ -144842,6 +144868,7 @@ This tool requires user approval (T3 tier - Probing).`,
144842
144868
  tools: wrappedTools,
144843
144869
  stopWhen: stepCountIs(100),
144844
144870
  abortSignal: this.abortController?.signal,
144871
+ authConfig: this.config.authConfig,
144845
144872
  onStepFinish: (step) => {
144846
144873
  console.log(step.usage);
144847
144874
  console.log(this.config.onTokenUsage);
@@ -148128,6 +148155,7 @@ async function runPentestOrchestrator(input) {
148128
148155
  const {
148129
148156
  targets,
148130
148157
  model,
148158
+ authConfig,
148131
148159
  sessionConfig,
148132
148160
  onProgress,
148133
148161
  onAgentSpawn,
@@ -148232,6 +148260,7 @@ async function runPentestOrchestrator(input) {
148232
148260
  }
148233
148261
  },
148234
148262
  model,
148263
+ authConfig,
148235
148264
  remoteSandboxUrl: sessionConfig?.remoteSandboxUrl,
148236
148265
  toolOverride,
148237
148266
  abortSignal,
@@ -148878,6 +148907,7 @@ async function runStreamlinedPentest(input) {
148878
148907
  const {
148879
148908
  target,
148880
148909
  model,
148910
+ authConfig,
148881
148911
  sessionConfig,
148882
148912
  onProgress,
148883
148913
  onDiscoveryStepFinish,
@@ -148908,6 +148938,7 @@ async function runStreamlinedPentest(input) {
148908
148938
  target,
148909
148939
  model,
148910
148940
  session,
148941
+ authConfig,
148911
148942
  abortSignal,
148912
148943
  toolOverride,
148913
148944
  logger,
@@ -148951,6 +148982,7 @@ async function runStreamlinedPentest(input) {
148951
148982
  targets,
148952
148983
  model,
148953
148984
  session,
148985
+ authConfig,
148954
148986
  sessionConfig,
148955
148987
  abortSignal,
148956
148988
  toolOverride,
@@ -149026,7 +149058,7 @@ function sleep4(ms) {
149026
149058
  return new Promise((resolve4) => setTimeout(resolve4, ms));
149027
149059
  }
149028
149060
  async function runDiscoveryPhase(params) {
149029
- const { target, model, session, abortSignal, toolOverride, logger, onProgress, onStepFinish, onStream } = params;
149061
+ const { target, model, session, authConfig, abortSignal, toolOverride, logger, onProgress, onStepFinish, onStream } = params;
149030
149062
  let attempt = 0;
149031
149063
  let lastError = null;
149032
149064
  while (attempt < RETRY_CONFIG3.maxRetries) {
@@ -149046,6 +149078,7 @@ async function runDiscoveryPhase(params) {
149046
149078
  objective: "Comprehensive attack surface discovery and target identification",
149047
149079
  model,
149048
149080
  session,
149081
+ authConfig,
149049
149082
  abortSignal,
149050
149083
  toolOverride,
149051
149084
  onStepFinish: (step) => {
@@ -152671,17 +152704,268 @@ function WebWizard({
152671
152704
  }, undefined, true, undefined, this);
152672
152705
  }
152673
152706
 
152707
+ // src/tui/components/commands/resume-wizard.tsx
152708
+ var import_react68 = __toESM(require_react(), 1);
152709
+ import { existsSync as existsSync26, readdirSync as readdirSync7 } from "fs";
152710
+ import { join as join19 } from "path";
152711
+ var greenAccent5 = RGBA.fromInts(76, 175, 80, 255);
152712
+ var creamText12 = RGBA.fromInts(255, 248, 220, 255);
152713
+ var dimText13 = RGBA.fromInts(120, 120, 120, 255);
152714
+ function formatRelativeTime(timestamp) {
152715
+ const now2 = Date.now();
152716
+ const diff = now2 - timestamp;
152717
+ const minutes = Math.floor(diff / 60000);
152718
+ const hours = Math.floor(diff / 3600000);
152719
+ const days = Math.floor(diff / 86400000);
152720
+ if (minutes < 1)
152721
+ return "just now";
152722
+ if (minutes < 60)
152723
+ return `${minutes}m ago`;
152724
+ if (hours < 24)
152725
+ return `${hours}h ago`;
152726
+ if (days === 1)
152727
+ return "yesterday";
152728
+ if (days < 7)
152729
+ return `${days}d ago`;
152730
+ return new Date(timestamp).toLocaleDateString();
152731
+ }
152732
+ function countFindings(findingsPath) {
152733
+ try {
152734
+ if (!existsSync26(findingsPath))
152735
+ return 0;
152736
+ return readdirSync7(findingsPath).filter((f) => f.endsWith(".json")).length;
152737
+ } catch {
152738
+ return 0;
152739
+ }
152740
+ }
152741
+ function ResumeWizard() {
152742
+ const [sessions, setSessions] = import_react68.useState([]);
152743
+ const [selectedIndex, setSelectedIndex] = import_react68.useState(0);
152744
+ const [loading, setLoading] = import_react68.useState(true);
152745
+ const [statusMessage, setStatusMessage] = import_react68.useState("");
152746
+ const route = useRoute();
152747
+ const { load: loadSession } = useSession();
152748
+ const { refocusPrompt } = useFocus();
152749
+ import_react68.useEffect(() => {
152750
+ async function loadOperatorSessions() {
152751
+ setLoading(true);
152752
+ try {
152753
+ const enrichedSessions = [];
152754
+ for await (const session of Session.list()) {
152755
+ const statePath = join19(session.rootPath, "operator-state.json");
152756
+ const hasOperatorState = existsSync26(statePath);
152757
+ const findingsCount = countFindings(session.findingsPath);
152758
+ enrichedSessions.push({
152759
+ ...session,
152760
+ findingsCount,
152761
+ hasOperatorState
152762
+ });
152763
+ }
152764
+ enrichedSessions.sort((a, b2) => b2.time.updated - a.time.updated);
152765
+ setSessions(enrichedSessions.slice(0, 20));
152766
+ } catch (error41) {
152767
+ console.error("Error loading sessions:", error41);
152768
+ setStatusMessage("Error loading sessions");
152769
+ } finally {
152770
+ setLoading(false);
152771
+ }
152772
+ }
152773
+ loadOperatorSessions();
152774
+ }, []);
152775
+ const resumeSession = async (session) => {
152776
+ try {
152777
+ const loaded = await loadSession(session.id);
152778
+ if (!loaded) {
152779
+ setStatusMessage("Error loading session");
152780
+ setTimeout(() => setStatusMessage(""), 2000);
152781
+ return;
152782
+ }
152783
+ route.navigate({
152784
+ type: "session",
152785
+ sessionId: session.id,
152786
+ isResume: true
152787
+ });
152788
+ } catch (error41) {
152789
+ console.error("Error resuming session:", error41);
152790
+ setStatusMessage("Error resuming session");
152791
+ setTimeout(() => setStatusMessage(""), 2000);
152792
+ }
152793
+ };
152794
+ useKeyboard((key) => {
152795
+ if (key.name === "escape") {
152796
+ refocusPrompt();
152797
+ route.navigate({ type: "base", path: "home" });
152798
+ return;
152799
+ }
152800
+ if (key.name === "up" && sessions.length > 0) {
152801
+ setSelectedIndex((i) => i > 0 ? i - 1 : sessions.length - 1);
152802
+ return;
152803
+ }
152804
+ if (key.name === "down" && sessions.length > 0) {
152805
+ setSelectedIndex((i) => i < sessions.length - 1 ? i + 1 : 0);
152806
+ return;
152807
+ }
152808
+ if (key.name === "return" && sessions.length > 0) {
152809
+ const selected = sessions[selectedIndex];
152810
+ if (selected) {
152811
+ resumeSession(selected);
152812
+ }
152813
+ return;
152814
+ }
152815
+ });
152816
+ if (loading) {
152817
+ return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
152818
+ flexDirection: "column",
152819
+ padding: 2,
152820
+ width: "100%",
152821
+ children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
152822
+ fg: creamText12,
152823
+ children: "Loading sessions..."
152824
+ }, undefined, false, undefined, this)
152825
+ }, undefined, false, undefined, this);
152826
+ }
152827
+ if (sessions.length === 0) {
152828
+ return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
152829
+ flexDirection: "column",
152830
+ padding: 2,
152831
+ gap: 1,
152832
+ width: "100%",
152833
+ children: [
152834
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
152835
+ fg: creamText12,
152836
+ children: "Resume Pentest Session"
152837
+ }, undefined, false, undefined, this),
152838
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
152839
+ fg: dimText13,
152840
+ children: "No sessions found to resume."
152841
+ }, undefined, false, undefined, this),
152842
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
152843
+ fg: dimText13,
152844
+ children: "Start a new session with /web or /operator"
152845
+ }, undefined, false, undefined, this),
152846
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
152847
+ fg: dimText13,
152848
+ children: "Press Esc to go back"
152849
+ }, undefined, false, undefined, this)
152850
+ ]
152851
+ }, undefined, true, undefined, this);
152852
+ }
152853
+ return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
152854
+ flexDirection: "column",
152855
+ padding: 2,
152856
+ gap: 1,
152857
+ width: "100%",
152858
+ children: [
152859
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
152860
+ fg: creamText12,
152861
+ children: "Resume Pentest Session"
152862
+ }, undefined, false, undefined, this),
152863
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
152864
+ fg: dimText13,
152865
+ children: "Select a session to continue where you left off"
152866
+ }, undefined, false, undefined, this),
152867
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
152868
+ flexDirection: "column",
152869
+ marginTop: 1,
152870
+ children: sessions.map((session, index) => {
152871
+ const isSelected = index === selectedIndex;
152872
+ const age = formatRelativeTime(session.time.updated);
152873
+ const target = session.targets[0] || "No target";
152874
+ const findingsText = session.findingsCount > 0 ? `${session.findingsCount} finding${session.findingsCount > 1 ? "s" : ""}` : "No findings";
152875
+ return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
152876
+ flexDirection: "row",
152877
+ justifyContent: "space-between",
152878
+ width: "100%",
152879
+ border: isSelected ? ["left"] : undefined,
152880
+ borderColor: isSelected ? greenAccent5 : undefined,
152881
+ paddingLeft: isSelected ? 1 : 2,
152882
+ children: [
152883
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
152884
+ flexDirection: "row",
152885
+ gap: 1,
152886
+ children: [
152887
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
152888
+ fg: isSelected ? greenAccent5 : creamText12,
152889
+ children: [
152890
+ isSelected ? "▸ " : " ",
152891
+ session.name
152892
+ ]
152893
+ }, undefined, true, undefined, this),
152894
+ session.hasOperatorState && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
152895
+ fg: greenAccent5,
152896
+ children: "●"
152897
+ }, undefined, false, undefined, this)
152898
+ ]
152899
+ }, undefined, true, undefined, this),
152900
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
152901
+ fg: dimText13,
152902
+ children: [
152903
+ target,
152904
+ " · ",
152905
+ findingsText,
152906
+ " · ",
152907
+ age
152908
+ ]
152909
+ }, undefined, true, undefined, this)
152910
+ ]
152911
+ }, session.id, true, undefined, this);
152912
+ })
152913
+ }, undefined, false, undefined, this),
152914
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
152915
+ marginTop: 2,
152916
+ flexDirection: "column",
152917
+ children: [
152918
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
152919
+ fg: dimText13,
152920
+ children: [
152921
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
152922
+ fg: greenAccent5,
152923
+ children: "↑↓"
152924
+ }, undefined, false, undefined, this),
152925
+ " Navigate ",
152926
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
152927
+ fg: greenAccent5,
152928
+ children: "Enter"
152929
+ }, undefined, false, undefined, this),
152930
+ " Resume ",
152931
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
152932
+ fg: greenAccent5,
152933
+ children: "Esc"
152934
+ }, undefined, false, undefined, this),
152935
+ " Cancel"
152936
+ ]
152937
+ }, undefined, true, undefined, this),
152938
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
152939
+ fg: dimText13,
152940
+ children: [
152941
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("span", {
152942
+ fg: greenAccent5,
152943
+ children: "●"
152944
+ }, undefined, false, undefined, this),
152945
+ " = Has saved state (full context restore)"
152946
+ ]
152947
+ }, undefined, true, undefined, this)
152948
+ ]
152949
+ }, undefined, true, undefined, this),
152950
+ statusMessage && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
152951
+ fg: greenAccent5,
152952
+ children: statusMessage
152953
+ }, undefined, false, undefined, this)
152954
+ ]
152955
+ }, undefined, true, undefined, this);
152956
+ }
152957
+
152674
152958
  // src/tui/components/commands/provider-manager.tsx
152675
- var import_react72 = __toESM(require_react(), 1);
152959
+ var import_react74 = __toESM(require_react(), 1);
152676
152960
  // src/tui/components/commands/provider-selection.tsx
152677
- var import_react69 = __toESM(require_react(), 1);
152961
+ var import_react71 = __toESM(require_react(), 1);
152678
152962
  function ProviderSelection({
152679
152963
  onProviderSelected,
152680
152964
  onClose
152681
152965
  }) {
152682
152966
  const route = useRoute();
152683
152967
  const _config = useConfig();
152684
- const [highlightedIndex, setHighlightedIndex] = import_react69.useState(0);
152968
+ const [highlightedIndex, setHighlightedIndex] = import_react71.useState(0);
152685
152969
  const configuredProviders = getConfiguredProviders(_config.data);
152686
152970
  useKeyboard((key) => {
152687
152971
  if (key.name === "escape") {
@@ -152834,14 +153118,14 @@ function ProviderSelection({
152834
153118
  }
152835
153119
 
152836
153120
  // src/tui/components/commands/api-key-input.tsx
152837
- var import_react71 = __toESM(require_react(), 1);
153121
+ var import_react73 = __toESM(require_react(), 1);
152838
153122
  function APIKeyInput({
152839
153123
  provider,
152840
153124
  providerName,
152841
153125
  onSubmit,
152842
153126
  onCancel
152843
153127
  }) {
152844
- const [apiKey, setApiKey] = import_react71.useState("");
153128
+ const [apiKey, setApiKey] = import_react73.useState("");
152845
153129
  useKeyboard((key) => {
152846
153130
  if (key.name === "escape") {
152847
153131
  onCancel();
@@ -152953,8 +153237,8 @@ function APIKeyInput({
152953
153237
  function ProviderManager() {
152954
153238
  const route = useRoute();
152955
153239
  const _config = useConfig();
152956
- const [flowState, setFlowState] = import_react72.useState("selecting");
152957
- const [selectedProvider, setSelectedProvider] = import_react72.useState(null);
153240
+ const [flowState, setFlowState] = import_react74.useState("selecting");
153241
+ const [selectedProvider, setSelectedProvider] = import_react74.useState(null);
152958
153242
  const handleProviderSelected = (providerId) => {
152959
153243
  setSelectedProvider(providerId);
152960
153244
  setFlowState("inputting");
@@ -153012,7 +153296,7 @@ function ProviderManager() {
153012
153296
  }
153013
153297
 
153014
153298
  // src/tui/components/switch.tsx
153015
- var import_react73 = __toESM(require_react(), 1);
153299
+ var import_react75 = __toESM(require_react(), 1);
153016
153300
  var CaseSymbol = Symbol("Switch.Case");
153017
153301
  var DefaultSymbol = Symbol("Switch.Default");
153018
153302
  function CaseComponent({ children }) {
@@ -153033,8 +153317,8 @@ function SwitchComponent({
153033
153317
  }) {
153034
153318
  let matchedChild = null;
153035
153319
  let defaultChild = null;
153036
- import_react73.default.Children.forEach(children, (child) => {
153037
- if (import_react73.default.isValidElement(child)) {
153320
+ import_react75.default.Children.forEach(children, (child) => {
153321
+ if (import_react75.default.isValidElement(child)) {
153038
153322
  if (child.type[CaseSymbol]) {
153039
153323
  const caseChild = child;
153040
153324
  if (caseChild.props.when === condition) {
@@ -153246,22 +153530,22 @@ function ShortcutsDialog({ open, onClose }) {
153246
153530
  }
153247
153531
 
153248
153532
  // src/tui/components/commands/help-dialog.tsx
153249
- var import_react76 = __toESM(require_react(), 1);
153533
+ var import_react78 = __toESM(require_react(), 1);
153250
153534
  var bgOverlay2 = RGBA.fromInts(0, 0, 0, 200);
153251
153535
  var bgPanel2 = RGBA.fromInts(20, 20, 20, 255);
153252
153536
  var borderColor3 = RGBA.fromInts(60, 60, 60, 255);
153253
- var greenAccent5 = RGBA.fromInts(76, 175, 80, 255);
153254
- var dimText13 = RGBA.fromInts(120, 120, 120, 255);
153537
+ var greenAccent6 = RGBA.fromInts(76, 175, 80, 255);
153538
+ var dimText14 = RGBA.fromInts(120, 120, 120, 255);
153255
153539
  var selectedBg2 = RGBA.fromInts(40, 40, 60, 255);
153256
153540
  var white3 = RGBA.fromInts(255, 255, 255, 255);
153257
153541
  function HelpDialog() {
153258
153542
  const { commands: commands2 } = useCommand();
153259
153543
  const route = useRoute();
153260
153544
  const dimensions = useTerminalDimensions();
153261
- const [selectedIndex, setSelectedIndex] = import_react76.useState(0);
153262
- const [showDetail, setShowDetail] = import_react76.useState(false);
153263
- const scrollboxRef = import_react76.useRef(null);
153264
- const commandsByCategory = import_react76.useMemo(() => {
153545
+ const [selectedIndex, setSelectedIndex] = import_react78.useState(0);
153546
+ const [showDetail, setShowDetail] = import_react78.useState(false);
153547
+ const scrollboxRef = import_react78.useRef(null);
153548
+ const commandsByCategory = import_react78.useMemo(() => {
153265
153549
  const grouped = {};
153266
153550
  for (const cmd of commands2) {
153267
153551
  const category = cmd.category || "Other";
@@ -153272,15 +153556,15 @@ function HelpDialog() {
153272
153556
  }
153273
153557
  return grouped;
153274
153558
  }, [commands2]);
153275
- const flatCommands = import_react76.useMemo(() => {
153559
+ const flatCommands = import_react78.useMemo(() => {
153276
153560
  return commands2;
153277
153561
  }, [commands2]);
153278
- import_react76.useEffect(() => {
153562
+ import_react78.useEffect(() => {
153279
153563
  if (selectedIndex >= flatCommands.length) {
153280
153564
  setSelectedIndex(Math.max(0, flatCommands.length - 1));
153281
153565
  }
153282
153566
  }, [flatCommands.length, selectedIndex]);
153283
- import_react76.useEffect(() => {
153567
+ import_react78.useEffect(() => {
153284
153568
  if (!scrollboxRef.current || flatCommands.length === 0)
153285
153569
  return;
153286
153570
  const scroll = scrollboxRef.current;
@@ -153357,7 +153641,7 @@ function HelpDialog() {
153357
153641
  width: panelWidth,
153358
153642
  height: detailHeight,
153359
153643
  backgroundColor: bgPanel2,
153360
- borderColor: greenAccent5,
153644
+ borderColor: greenAccent6,
153361
153645
  borderStyle: "single",
153362
153646
  flexDirection: "column",
153363
153647
  children: [
@@ -153367,14 +153651,14 @@ function HelpDialog() {
153367
153651
  flexDirection: "row",
153368
153652
  children: [
153369
153653
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
153370
- fg: greenAccent5,
153654
+ fg: greenAccent6,
153371
153655
  children: [
153372
153656
  "/",
153373
153657
  selectedCommand.name
153374
153658
  ]
153375
153659
  }, undefined, true, undefined, this),
153376
153660
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
153377
- fg: dimText13,
153661
+ fg: dimText14,
153378
153662
  children: ` (${selectedCommand.category || "General"})`
153379
153663
  }, undefined, false, undefined, this)
153380
153664
  ]
@@ -153402,7 +153686,7 @@ function HelpDialog() {
153402
153686
  marginTop: 1,
153403
153687
  children: [
153404
153688
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
153405
- fg: dimText13,
153689
+ fg: dimText14,
153406
153690
  children: "Aliases: "
153407
153691
  }, undefined, false, undefined, this),
153408
153692
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
@@ -153417,7 +153701,7 @@ function HelpDialog() {
153417
153701
  height: 1
153418
153702
  }, undefined, false, undefined, this),
153419
153703
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
153420
- fg: dimText13,
153704
+ fg: dimText14,
153421
153705
  children: "Options:"
153422
153706
  }, undefined, false, undefined, this),
153423
153707
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
@@ -153428,11 +153712,11 @@ function HelpDialog() {
153428
153712
  paddingLeft: 2,
153429
153713
  children: [
153430
153714
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
153431
- fg: greenAccent5,
153715
+ fg: greenAccent6,
153432
153716
  children: opt.name
153433
153717
  }, undefined, false, undefined, this),
153434
153718
  opt.valueHint && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
153435
- fg: dimText13,
153719
+ fg: dimText14,
153436
153720
  children: ` ${opt.valueHint}`
153437
153721
  }, undefined, false, undefined, this),
153438
153722
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
@@ -153458,7 +153742,7 @@ function HelpDialog() {
153458
153742
  padding: 1,
153459
153743
  flexDirection: "row",
153460
153744
  children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
153461
- fg: dimText13,
153745
+ fg: dimText14,
153462
153746
  children: "[enter/esc] back"
153463
153747
  }, undefined, false, undefined, this)
153464
153748
  }, undefined, false, undefined, this)
@@ -153489,11 +153773,11 @@ function HelpDialog() {
153489
153773
  flexDirection: "row",
153490
153774
  children: [
153491
153775
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
153492
- fg: greenAccent5,
153776
+ fg: greenAccent6,
153493
153777
  children: "Help - Available Commands".padEnd(panelWidth - 20)
153494
153778
  }, undefined, false, undefined, this),
153495
153779
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
153496
- fg: dimText13,
153780
+ fg: dimText14,
153497
153781
  children: `${flatCommands.length} commands`
153498
153782
  }, undefined, false, undefined, this)
153499
153783
  ]
@@ -153512,7 +153796,7 @@ function HelpDialog() {
153512
153796
  paddingRight: 2,
153513
153797
  flexDirection: "row",
153514
153798
  children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
153515
- fg: dimText13,
153799
+ fg: dimText14,
153516
153800
  children: [
153517
153801
  "Command".padEnd(18),
153518
153802
  "Category".padEnd(14),
@@ -153547,19 +153831,19 @@ function HelpDialog() {
153547
153831
  paddingLeft: 1,
153548
153832
  children: [
153549
153833
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
153550
- fg: isSelected ? greenAccent5 : white3,
153834
+ fg: isSelected ? greenAccent6 : white3,
153551
153835
  children: name39
153552
153836
  }, undefined, false, undefined, this),
153553
153837
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
153554
- fg: dimText13,
153838
+ fg: dimText14,
153555
153839
  children: category
153556
153840
  }, undefined, false, undefined, this),
153557
153841
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
153558
- fg: isSelected ? white3 : dimText13,
153842
+ fg: isSelected ? white3 : dimText14,
153559
153843
  children: desc
153560
153844
  }, undefined, false, undefined, this),
153561
153845
  hasOptions && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
153562
- fg: greenAccent5,
153846
+ fg: greenAccent6,
153563
153847
  children: optionHint
153564
153848
  }, undefined, false, undefined, this)
153565
153849
  ]
@@ -153579,7 +153863,7 @@ function HelpDialog() {
153579
153863
  padding: 1,
153580
153864
  flexDirection: "row",
153581
153865
  children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
153582
- fg: dimText13,
153866
+ fg: dimText14,
153583
153867
  children: "[j/k] navigate [enter/v] details [esc] close"
153584
153868
  }, undefined, false, undefined, this)
153585
153869
  }, undefined, false, undefined, this)
@@ -153589,10 +153873,10 @@ function HelpDialog() {
153589
153873
  }
153590
153874
 
153591
153875
  // src/tui/context/keybinding.tsx
153592
- var import_react82 = __toESM(require_react(), 1);
153876
+ var import_react84 = __toESM(require_react(), 1);
153593
153877
 
153594
153878
  // src/tui/keybindings/keybind.tsx
153595
- var import_react78 = __toESM(require_react(), 1);
153879
+ var import_react80 = __toESM(require_react(), 1);
153596
153880
 
153597
153881
  // src/tui/keybindings/actions.ts
153598
153882
  var movementActions = [
@@ -153844,7 +154128,7 @@ var allActions = [
153844
154128
  var actionsByKey = new Map(allActions.map((action) => [action.key, action]));
153845
154129
  var actionsById = new Map(allActions.map((action) => [action.id, action]));
153846
154130
  // src/tui/keybindings/keybind.tsx
153847
- var LeaderKeyContext = import_react78.createContext(null);
154131
+ var LeaderKeyContext = import_react80.createContext(null);
153848
154132
  // src/tui/keybindings/registry.ts
153849
154133
  function createKeybindings(deps) {
153850
154134
  const {
@@ -154050,7 +154334,7 @@ var Keybind;
154050
154334
  })(Keybind ||= {});
154051
154335
 
154052
154336
  // src/tui/context/keybinding.tsx
154053
- var KeybindingContext = import_react82.createContext(undefined);
154337
+ var KeybindingContext = import_react84.createContext(undefined);
154054
154338
  function KeybindingProvider({
154055
154339
  children,
154056
154340
  deps
@@ -154091,13 +154375,13 @@ function KeybindingProvider({
154091
154375
  // src/tui/index.tsx
154092
154376
  function App(props) {
154093
154377
  const { appConfig } = props;
154094
- const [focusIndex, setFocusIndex] = import_react84.useState(0);
154095
- const [cwd, setCwd] = import_react84.useState(process.cwd());
154096
- const [ctrlCPressTime, setCtrlCPressTime] = import_react84.useState(null);
154097
- const [showExitWarning, setShowExitWarning] = import_react84.useState(false);
154098
- const [inputKey, setInputKey] = import_react84.useState(0);
154099
- const [showSessionsDialog, setShowSessionsDialog] = import_react84.useState(false);
154100
- const [showShortcutsDialog, setShowShortcutsDialog] = import_react84.useState(false);
154378
+ const [focusIndex, setFocusIndex] = import_react86.useState(0);
154379
+ const [cwd, setCwd] = import_react86.useState(process.cwd());
154380
+ const [ctrlCPressTime, setCtrlCPressTime] = import_react86.useState(null);
154381
+ const [showExitWarning, setShowExitWarning] = import_react86.useState(false);
154382
+ const [inputKey, setInputKey] = import_react86.useState(0);
154383
+ const [showSessionsDialog, setShowSessionsDialog] = import_react86.useState(false);
154384
+ const [showShortcutsDialog, setShowShortcutsDialog] = import_react86.useState(false);
154101
154385
  const navigableItems = ["command-input"];
154102
154386
  return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ConfigProvider, {
154103
154387
  config: appConfig,
@@ -154171,7 +154455,7 @@ function AppContent({
154171
154455
  path: "providers"
154172
154456
  });
154173
154457
  }
154174
- import_react84.useEffect(() => {
154458
+ import_react86.useEffect(() => {
154175
154459
  if (showExitWarning) {
154176
154460
  const timer = setTimeout(() => {
154177
154461
  setShowExitWarning(false);
@@ -154297,6 +154581,10 @@ function CommandDisplay({
154297
154581
  when: "providers",
154298
154582
  children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ProviderManager, {}, undefined, false, undefined, this)
154299
154583
  }, undefined, false, undefined, this),
154584
+ /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(RouteSwitch.Case, {
154585
+ when: "resume",
154586
+ children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ResumeWizard, {}, undefined, false, undefined, this)
154587
+ }, undefined, false, undefined, this),
154300
154588
  /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(RouteSwitch.Case, {
154301
154589
  when: "help",
154302
154590
  children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(HelpDialog, {}, undefined, false, undefined, this)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pensar/apex",
3
- "version": "0.0.54",
3
+ "version": "0.0.55-canary.02c66dc2",
4
4
  "description": "AI-powered penetration testing CLI tool with terminal UI",
5
5
  "module": "src/tui/index.tsx",
6
6
  "main": "build/index.js",