pentesting 0.73.12 → 0.73.13

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.
@@ -5,7 +5,7 @@ import {
5
5
  createContextExtractor,
6
6
  getLLMClient,
7
7
  getShellSupervisorLifecycleSnapshot
8
- } from "./chunk-4DUF6JX2.js";
8
+ } from "./chunk-GILD75OT.js";
9
9
  import {
10
10
  AGENT_ROLES,
11
11
  EVENT_TYPES,
@@ -13,7 +13,7 @@ import {
13
13
  TOOL_NAMES,
14
14
  getProcessOutput,
15
15
  listBackgroundProcesses
16
- } from "./chunk-5JXATHQ3.js";
16
+ } from "./chunk-4UNNRHYY.js";
17
17
  import {
18
18
  DETECTION_PATTERNS,
19
19
  PROCESS_EVENTS,
@@ -348,7 +348,7 @@ var INPUT_PROMPT_PATTERNS = [
348
348
  ];
349
349
 
350
350
  // src/shared/constants/agent.ts
351
- var APP_VERSION = "0.73.12";
351
+ var APP_VERSION = "0.73.13";
352
352
  var APP_DESCRIPTION = "Autonomous Penetration Testing AI Agent";
353
353
  var LLM_ROLES = {
354
354
  SYSTEM: "system",
@@ -2323,6 +2323,93 @@ function setupTimeout(child, timeoutMs, onTimeout) {
2323
2323
  }
2324
2324
  }, timeoutMs);
2325
2325
  }
2326
+ function emitCommandStart(safeCommand, eventEmitter) {
2327
+ const preview = safeCommand.slice(0, DISPLAY_LIMITS.COMMAND_PREVIEW);
2328
+ const suffix = safeCommand.length > DISPLAY_LIMITS.COMMAND_PREVIEW ? "..." : "";
2329
+ eventEmitter?.({
2330
+ type: COMMAND_EVENT_TYPES.COMMAND_START,
2331
+ message: `Executing: ${preview}${suffix}`
2332
+ });
2333
+ }
2334
+ function createChildProcess(execCommand, options) {
2335
+ return spawn3("sh", ["-c", execCommand], {
2336
+ detached: true,
2337
+ env: { ...process.env, ...options.env },
2338
+ cwd: options.cwd
2339
+ });
2340
+ }
2341
+ function createExecutionState() {
2342
+ return { terminated: false, timedOut: false };
2343
+ }
2344
+ function createTimeoutError(timeoutMs, ioHandler) {
2345
+ const timeoutSeconds = Math.round(timeoutMs / 1e3);
2346
+ const outputTail = (ioHandler.stdout + ioHandler.stderr).trim().slice(-500);
2347
+ return `Command timed out after ${timeoutSeconds}s. Output so far:
2348
+ ${outputTail}`;
2349
+ }
2350
+ function resolveTimeout(timeoutMs, ioHandler, eventEmitter, resolve) {
2351
+ const timeoutSeconds = Math.round(timeoutMs / 1e3);
2352
+ eventEmitter?.({
2353
+ type: COMMAND_EVENT_TYPES.COMMAND_FAILED,
2354
+ message: `Command timed out after ${timeoutSeconds}s`
2355
+ });
2356
+ resolve({
2357
+ success: false,
2358
+ output: ioHandler.stdout.trim(),
2359
+ error: createTimeoutError(timeoutMs, ioHandler)
2360
+ });
2361
+ }
2362
+ function resolveSuccess(ioHandler, eventEmitter, resolve) {
2363
+ const stdout = ioHandler.stdout.trim();
2364
+ const stderr = ioHandler.stderr.trim();
2365
+ eventEmitter?.({
2366
+ type: COMMAND_EVENT_TYPES.COMMAND_SUCCESS,
2367
+ message: "Command completed"
2368
+ });
2369
+ resolve({ success: true, output: stdout || stderr });
2370
+ }
2371
+ function resolveFailure(code, ioHandler, eventEmitter, resolve) {
2372
+ const stdout = ioHandler.stdout.trim();
2373
+ const stderr = ioHandler.stderr.trim();
2374
+ eventEmitter?.({
2375
+ type: COMMAND_EVENT_TYPES.COMMAND_FAILED,
2376
+ message: `Command failed (exit ${code})`,
2377
+ detail: stderr.slice(0, SYSTEM_LIMITS.MAX_INPUT_SLICE)
2378
+ });
2379
+ resolve({
2380
+ success: false,
2381
+ output: stdout,
2382
+ error: stderr || `Process exited with code ${code}`
2383
+ });
2384
+ }
2385
+ function attachProcessStreams(child, ioHandler) {
2386
+ child.stdout?.on("data", (data) => ioHandler.handleStdout(data));
2387
+ child.stderr?.on("data", (data) => ioHandler.handleStderr(data));
2388
+ }
2389
+ function attachProcessLifecycleHandlers(child, ioHandler, processState, killTimer, timeoutMs, eventEmitter, resolve) {
2390
+ child.on("close", (code) => {
2391
+ clearTimeout(killTimer);
2392
+ processState.terminated = true;
2393
+ if (processState.timedOut) {
2394
+ resolveTimeout(timeoutMs, ioHandler, eventEmitter, resolve);
2395
+ return;
2396
+ }
2397
+ if (code === 0) {
2398
+ resolveSuccess(ioHandler, eventEmitter, resolve);
2399
+ return;
2400
+ }
2401
+ resolveFailure(code, ioHandler, eventEmitter, resolve);
2402
+ });
2403
+ child.on("error", (err) => {
2404
+ clearTimeout(killTimer);
2405
+ processState.terminated = true;
2406
+ eventEmitter?.({
2407
+ type: COMMAND_EVENT_TYPES.COMMAND_ERROR,
2408
+ message: `Command error: ${err.message}`
2409
+ });
2410
+ resolve({ success: false, output: "", error: err.message || String(err) });
2411
+ });
2412
+ }
2326
2413
  async function executeCommandOnce(command, options = {}) {
2327
2414
  return new Promise((resolve) => {
2328
2415
  const eventEmitter = getEventEmitter();
@@ -2330,16 +2417,9 @@ async function executeCommandOnce(command, options = {}) {
2330
2417
  if (error) {
2331
2418
  return resolve({ success: false, output: "", error });
2332
2419
  }
2333
- eventEmitter?.({
2334
- type: COMMAND_EVENT_TYPES.COMMAND_START,
2335
- message: `Executing: ${safeCommand.slice(0, DISPLAY_LIMITS.COMMAND_PREVIEW)}${safeCommand.length > DISPLAY_LIMITS.COMMAND_PREVIEW ? "..." : ""}`
2336
- });
2337
- const child = spawn3("sh", ["-c", execCommand], {
2338
- detached: true,
2339
- env: { ...process.env, ...options.env },
2340
- cwd: options.cwd
2341
- });
2342
- const processState = { terminated: false, timedOut: false };
2420
+ emitCommandStart(safeCommand, eventEmitter);
2421
+ const child = createChildProcess(execCommand, options);
2422
+ const processState = createExecutionState();
2343
2423
  const timeoutMs = options.timeout ?? TOOL_TIMEOUTS.DEFAULT_COMMAND;
2344
2424
  const killTimer = setupTimeout(child, timeoutMs, () => {
2345
2425
  processState.timedOut = true;
@@ -2351,42 +2431,16 @@ async function executeCommandOnce(command, options = {}) {
2351
2431
  eventEmitter,
2352
2432
  inputHandler: getInputHandler()
2353
2433
  });
2354
- child.stdout.on("data", (d) => ioHandler.handleStdout(d));
2355
- child.stderr.on("data", (d) => ioHandler.handleStderr(d));
2356
- child.on("close", (code) => {
2357
- clearTimeout(killTimer);
2358
- processState.terminated = true;
2359
- const outTrimmed = ioHandler.stdout.trim();
2360
- const errTrimmed = ioHandler.stderr.trim();
2361
- if (processState.timedOut) {
2362
- eventEmitter?.({
2363
- type: COMMAND_EVENT_TYPES.COMMAND_FAILED,
2364
- message: `Command timed out after ${Math.round(timeoutMs / 1e3)}s`
2365
- });
2366
- return resolve({
2367
- success: false,
2368
- output: outTrimmed,
2369
- error: `Command timed out after ${Math.round(timeoutMs / 1e3)}s. Output so far:
2370
- ${(ioHandler.stdout + ioHandler.stderr).trim().slice(-500)}`
2371
- });
2372
- }
2373
- if (code === 0) {
2374
- eventEmitter?.({ type: COMMAND_EVENT_TYPES.COMMAND_SUCCESS, message: `Command completed` });
2375
- return resolve({ success: true, output: outTrimmed || errTrimmed });
2376
- }
2377
- eventEmitter?.({
2378
- type: COMMAND_EVENT_TYPES.COMMAND_FAILED,
2379
- message: `Command failed (exit ${code})`,
2380
- detail: errTrimmed.slice(0, SYSTEM_LIMITS.MAX_INPUT_SLICE)
2381
- });
2382
- return resolve({ success: false, output: outTrimmed, error: errTrimmed || `Process exited with code ${code}` });
2383
- });
2384
- child.on("error", (err) => {
2385
- clearTimeout(killTimer);
2386
- processState.terminated = true;
2387
- eventEmitter?.({ type: COMMAND_EVENT_TYPES.COMMAND_ERROR, message: `Command error: ${err.message}` });
2388
- resolve({ success: false, output: "", error: err.message || String(err) });
2389
- });
2434
+ attachProcessStreams(child, ioHandler);
2435
+ attachProcessLifecycleHandlers(
2436
+ child,
2437
+ ioHandler,
2438
+ processState,
2439
+ killTimer,
2440
+ timeoutMs,
2441
+ eventEmitter,
2442
+ resolve
2443
+ );
2390
2444
  });
2391
2445
  }
2392
2446
 
@@ -69,7 +69,7 @@ import {
69
69
  startBackgroundProcess,
70
70
  stopBackgroundProcess,
71
71
  writeFileContent
72
- } from "./chunk-5JXATHQ3.js";
72
+ } from "./chunk-4UNNRHYY.js";
73
73
  import {
74
74
  DETECTION_PATTERNS,
75
75
  HEALTH_CONFIG,
@@ -11084,7 +11084,7 @@ After completion: record key loot/findings from the sub-agent output to canonica
11084
11084
  rootTaskId: activeExecution.rootTaskId
11085
11085
  }
11086
11086
  });
11087
- const { AgentTool } = await import("./agent-tool-RTF2W3GB.js");
11087
+ const { AgentTool } = await import("./agent-tool-KHXXTHGS.js");
11088
11088
  const executor = new AgentTool(state, events, scopeGuard, approvalGate);
11089
11089
  try {
11090
11090
  const result = await executor.execute(input);
package/dist/main.js CHANGED
@@ -39,7 +39,7 @@ import {
39
39
  rotateTurnRecords,
40
40
  setCurrentTurn,
41
41
  writePolicyDocument
42
- } from "./chunk-4DUF6JX2.js";
42
+ } from "./chunk-GILD75OT.js";
43
43
  import {
44
44
  AGENT_ROLES,
45
45
  APP_DESCRIPTION,
@@ -88,7 +88,7 @@ import {
88
88
  setActiveSessionRuntime,
89
89
  setTorEnabled,
90
90
  snapshotToPrompt
91
- } from "./chunk-5JXATHQ3.js";
91
+ } from "./chunk-4UNNRHYY.js";
92
92
  import {
93
93
  EXIT_CODES,
94
94
  getOptionalRuntimeSection,
@@ -3285,7 +3285,7 @@ var makeRotateTurns = (_llm, _opts) => async (_ctx) => {
3285
3285
  };
3286
3286
  var makeSaveSession = (_llm, _opts) => async (ctx) => {
3287
3287
  try {
3288
- const { saveState: saveState2 } = await import("./persistence-DC6QI7XQ.js");
3288
+ const { saveState: saveState2 } = await import("./persistence-U2N3KWFH.js");
3289
3289
  saveState2(ctx.state);
3290
3290
  } catch {
3291
3291
  }
@@ -4273,11 +4273,11 @@ async function writeJsonReport(outputPath, result) {
4273
4273
  }
4274
4274
 
4275
4275
  // src/platform/tui/cli/interactive-runtime.tsx
4276
- import React17 from "react";
4276
+ import React18 from "react";
4277
4277
  import { render } from "ink";
4278
4278
 
4279
4279
  // src/platform/tui/app.tsx
4280
- import { Box as Box19 } from "ink";
4280
+ import { Box as Box20 } from "ink";
4281
4281
 
4282
4282
  // src/platform/tui/hooks/useAgent.ts
4283
4283
  import { useState as useState6, useEffect as useEffect2, useCallback as useCallback7, useRef as useRef7 } from "react";
@@ -4846,6 +4846,8 @@ var UI_STATUS_MESSAGES = {
4846
4846
  POLICY_BOOTSTRAP_SAVED: "Competition policy saved for this run.",
4847
4847
  /** Policy bootstrap did not produce a durable update */
4848
4848
  POLICY_BOOTSTRAP_NO_CHANGE: "Competition policy was reviewed, but no durable policy change was recorded.",
4849
+ /** No extra bootstrap policy was provided */
4850
+ POLICY_BOOTSTRAP_SKIPPED: "No additional policy provided. Starting with existing policy memory.",
4849
4851
  /** Pentest task prefix */
4850
4852
  PENTEST_TASK_PREFIX: "Perform comprehensive penetration testing",
4851
4853
  /** Against prefix */
@@ -6751,8 +6753,21 @@ var POLICY_COMPOSER_GUIDE = [
6751
6753
  "Before autonomous execution, add any competition rules or durable engagement constraints here.",
6752
6754
  "Use /policy to view the current policy memory at any time.",
6753
6755
  "You can also tell the agent to remember a rule or put something into policy memory in normal chat, and it will merge it automatically.",
6756
+ "Use Ctrl+J to insert a newline inside this policy editor.",
6754
6757
  "Tip: paste a compact summary of the most important rules if the source text is long."
6755
6758
  ].join("\n");
6759
+ var POLICY_COMPOSER_TITLE = "\u25C8 COMPETITION POLICY \u25C8";
6760
+ var POLICY_COMPOSER_FOOTER_BREAKPOINT = 72;
6761
+ function formatPolicyComposerTitle(terminalWidth) {
6762
+ if (terminalWidth <= POLICY_COMPOSER_TITLE.length + 2) {
6763
+ return POLICY_COMPOSER_TITLE;
6764
+ }
6765
+ const sideWidth = Math.floor((terminalWidth - POLICY_COMPOSER_TITLE.length - 2) / 2);
6766
+ return `${"\u2500".repeat(sideWidth)} ${POLICY_COMPOSER_TITLE} ${"\u2500".repeat(sideWidth)}`;
6767
+ }
6768
+ function shouldStackPolicyComposerFooter(terminalWidth) {
6769
+ return terminalWidth < POLICY_COMPOSER_FOOTER_BREAKPOINT;
6770
+ }
6756
6771
  function buildPolicyBootstrapInput(rawPolicy) {
6757
6772
  const trimmed = rawPolicy.trim();
6758
6773
  if (!trimmed) return "";
@@ -6848,6 +6863,8 @@ var useAppLogic = ({ autoApprove = false, target }) => {
6848
6863
  "system",
6849
6864
  policyResult.shouldWritePolicy ? policyResult.policyUpdateSummary || UI_STATUS_MESSAGES.POLICY_BOOTSTRAP_SAVED : UI_STATUS_MESSAGES.POLICY_BOOTSTRAP_NO_CHANGE
6850
6865
  );
6866
+ } else {
6867
+ addMessage("system", UI_STATUS_MESSAGES.POLICY_BOOTSTRAP_SKIPPED);
6851
6868
  }
6852
6869
  setAutoApproveMode(true);
6853
6870
  agent.setToolAutoApprove(true);
@@ -7380,7 +7397,30 @@ function computeResultDisplay(content) {
7380
7397
  return { firstLine, visibleRest, hasMore, hiddenCount, summary };
7381
7398
  }
7382
7399
 
7400
+ // src/platform/tui/components/messages/markdown-detection.ts
7401
+ var MARKDOWN_PATTERNS = [
7402
+ /^#{1,3}\s/m,
7403
+ /^[-*]\s/m,
7404
+ /^\d+\.\s/m,
7405
+ /```/,
7406
+ /`[^`]+`/,
7407
+ /(\*\*|__)[^*_]+(\*\*|__)/
7408
+ ];
7409
+ function shouldUseMarkdownRenderer(content) {
7410
+ const trimmed = content.trim();
7411
+ if (!trimmed) return false;
7412
+ return MARKDOWN_PATTERNS.some((pattern) => pattern.test(trimmed));
7413
+ }
7414
+
7383
7415
  // src/platform/tui/utils/chrome.ts
7416
+ function normalizePlaceholderText(text) {
7417
+ return text.replace(/\s+/g, " ").trim();
7418
+ }
7419
+ function resolveActiveInputPlaceholder(inputRequest) {
7420
+ const candidate = inputRequest.placeholder || inputRequest.prompt;
7421
+ const normalized = normalizePlaceholderText(candidate);
7422
+ return normalized || "Answer the active prompt";
7423
+ }
7384
7424
  function buildLeftAlignedLabelBorder({
7385
7425
  icon,
7386
7426
  label,
@@ -7399,6 +7439,18 @@ function resolveInputSeparatorColor({
7399
7439
  if (isProcessing) return THEME.dimGray;
7400
7440
  return THEME.primary;
7401
7441
  }
7442
+ function resolveInputPlaceholder({
7443
+ isProcessing,
7444
+ inputRequest
7445
+ }) {
7446
+ if (inputRequest.status === "active") {
7447
+ return resolveActiveInputPlaceholder(inputRequest);
7448
+ }
7449
+ if (isProcessing) {
7450
+ return "Send a note for the next turn, or type /help";
7451
+ }
7452
+ return "Describe the target or type /help";
7453
+ }
7402
7454
 
7403
7455
  // src/platform/tui/components/messages/MessageRow.tsx
7404
7456
  import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
@@ -7485,7 +7537,8 @@ var MessageRow = memo4(({ msg }) => {
7485
7537
  ] }), 0);
7486
7538
  }
7487
7539
  if (msg.type === "ai" || msg.type === "assistant") {
7488
- return renderBox("\u2022", "ai", THEME.messages.ai, /* @__PURE__ */ jsx6(MarkdownText, { content: msg.content }), 0);
7540
+ const useMarkdown = shouldUseMarkdownRenderer(msg.content);
7541
+ return renderBox("\u2022", "ai", THEME.messages.ai, useMarkdown ? /* @__PURE__ */ jsx6(MarkdownText, { content: msg.content }) : /* @__PURE__ */ jsx6(Text5, { color: THEME.white, wrap: "wrap", children: msg.content }), 0);
7489
7542
  }
7490
7543
  if (msg.type === "error") {
7491
7544
  const lines = msg.content.split("\n");
@@ -7607,11 +7660,11 @@ import { memo as memo7 } from "react";
7607
7660
  import { Text as Text7 } from "ink";
7608
7661
 
7609
7662
  // src/platform/tui/utils/animation-style.ts
7610
- var PRIMARY_BLUE = "#2496ED";
7611
7663
  var BLINKING_CIRCLE_PHASE_LENGTH = 8;
7612
7664
  var BLINKING_CIRCLE_SOLID_PHASE = 4;
7613
7665
  var SHIMMER_COLOR_STEPS = 64;
7614
7666
  var READY_SHIMMER_COLOR_COUNT = 12;
7667
+ var READY_SHIMMER_SWEEP_SPEED = 1.15;
7615
7668
  function getBlinkingCircleFrame(tick, activeColor = THEME.primary) {
7616
7669
  const phase = tick % BLINKING_CIRCLE_PHASE_LENGTH;
7617
7670
  const isSolid = phase < BLINKING_CIRCLE_SOLID_PHASE;
@@ -7647,18 +7700,6 @@ function buildNeutralShimmerPalette() {
7647
7700
  ]);
7648
7701
  });
7649
7702
  }
7650
- function buildAccentShimmerPalette() {
7651
- const start = hexToRgb(PRIMARY_BLUE);
7652
- const peak = hexToRgb(THEME.white);
7653
- return Array.from({ length: SHIMMER_COLOR_STEPS }, (_, i) => {
7654
- const t = i / (SHIMMER_COLOR_STEPS - 1);
7655
- return rgbToHex([
7656
- lerp(start[0], peak[0], t),
7657
- lerp(start[1], peak[1], t),
7658
- lerp(start[2], peak[2], t)
7659
- ]);
7660
- });
7661
- }
7662
7703
  var READY_SHIMMER_BASE_COLORS = [
7663
7704
  "#2496ED",
7664
7705
  "#38BDF8",
@@ -7719,11 +7760,9 @@ import { memo as memo8, useMemo as useMemo2 } from "react";
7719
7760
  import { Text as Text9 } from "ink";
7720
7761
  import { jsx as jsx11 } from "react/jsx-runtime";
7721
7762
  var SPOT_WIDTH = 6;
7722
- var SWEEP_SPEED = 1.5;
7723
7763
  var LOOP_PAD = SPOT_WIDTH * 2;
7724
7764
  var TICK_WRAP = 1e6;
7725
7765
  var NEUTRAL_PALETTE = buildNeutralShimmerPalette();
7726
- var ACCENT_PALETTE = buildAccentShimmerPalette();
7727
7766
  var READY_PALETTES = buildReadyShimmerPalettes();
7728
7767
  function gaussian(x, sigma) {
7729
7768
  return Math.exp(-(x * x) / (2 * sigma * sigma));
@@ -7736,10 +7775,11 @@ var ShimmerText = memo8(({
7736
7775
  }) => {
7737
7776
  const tick = useAnimationTick() % TICK_WRAP;
7738
7777
  const len = children.length;
7739
- const palette = variant === "accent" ? ACCENT_PALETTE : variant === "ready" ? READY_PALETTES[tick % READY_SHIMMER_COLOR_COUNT] : NEUTRAL_PALETTE;
7778
+ const palette = variant === "ready" ? READY_PALETTES[tick % READY_SHIMMER_COLOR_COUNT] : NEUTRAL_PALETTE;
7740
7779
  const chars = useMemo2(() => Array.from(children), [children]);
7780
+ const sweepSpeed = READY_SHIMMER_SWEEP_SPEED;
7741
7781
  const loopLen = len + LOOP_PAD;
7742
- const rawPos = (tick * SWEEP_SPEED + phase * loopLen) % loopLen;
7782
+ const rawPos = (tick * sweepSpeed + phase * loopLen) % loopLen;
7743
7783
  const spotPos = rawPos - SPOT_WIDTH;
7744
7784
  const sigma = SPOT_WIDTH / 2.5;
7745
7785
  return /* @__PURE__ */ jsx11(Text9, { bold, children: chars.map((char, i) => {
@@ -7765,6 +7805,20 @@ function fmtElapsed(secs) {
7765
7805
  const s = secs % 60;
7766
7806
  return `${h}h ${String(m).padStart(2, "0")}m ${String(s).padStart(2, "0")}s`;
7767
7807
  }
7808
+ var STATUS_META_STACK_BREAKPOINT = 76;
7809
+ function shouldStackProcessingMeta(columns) {
7810
+ return columns < STATUS_META_STACK_BREAKPOINT;
7811
+ }
7812
+ function buildProcessingMetaSuffix(isActive, elapsedSeconds, totalTokens, compact) {
7813
+ const elapsedStr = elapsedSeconds > 0 ? fmtElapsed(elapsedSeconds) : "0s";
7814
+ if (compact) {
7815
+ const compactPrefix = isActive ? "esc" : "done";
7816
+ const compactTokens = totalTokens > 0 ? ` \xB7 \u2191 ${formatTokens(totalTokens)}` : "";
7817
+ return `${compactPrefix} \xB7 ${elapsedStr}${compactTokens}`;
7818
+ }
7819
+ const tokenStr = totalTokens > 0 ? `\u2191 ${formatTokens(totalTokens)}` : "";
7820
+ return isActive ? `esc to interrupt \xB7 ${elapsedStr}${tokenStr ? ` \xB7 ${tokenStr}` : ""}` : `done \xB7 ${elapsedStr}${tokenStr ? ` \xB7 ${tokenStr}` : ""}`;
7821
+ }
7768
7822
  var ProcessingView = ({
7769
7823
  statusMain,
7770
7824
  detailText,
@@ -7773,25 +7827,30 @@ var ProcessingView = ({
7773
7827
  liveProgress,
7774
7828
  isActive = true
7775
7829
  }) => {
7830
+ const { columns } = useTerminalSize();
7776
7831
  const safe = liveProgress ?? DEFAULT_LIVE_PROGRESS;
7832
+ const compactMeta = shouldStackProcessingMeta(columns);
7777
7833
  const stage = safe.stage || statusMain;
7778
- const elapsedStr = statusElapsed > 0 ? fmtElapsed(statusElapsed) : "0s";
7779
- const tokenStr = totalTokens > 0 ? `\u2191 ${formatTokens(totalTokens)}` : "";
7780
- const metaSuffix = isActive ? `esc to interrupt \xB7 ${elapsedStr}${tokenStr ? ` \xB7 ${tokenStr}` : ""}` : `done \xB7 ${elapsedStr}${tokenStr ? ` \xB7 ${tokenStr}` : ""}`;
7834
+ const metaSuffix = buildProcessingMetaSuffix(isActive, statusElapsed, totalTokens, compactMeta);
7781
7835
  const detailContent = safe.activeTool ? `tool: ${safe.activeTool}` : safe.reasoningPreview ? `thought: ${truncate(safe.reasoningPreview, 80)}` : safe.responsePreview ? `output: ${truncate(safe.responsePreview, 80)}` : safe.detail || detailText || "";
7782
- const stageText = truncate(stage, 72);
7783
- return /* @__PURE__ */ jsxs7(Box9, { flexDirection: "column", children: [
7784
- /* @__PURE__ */ jsxs7(Box9, { children: [
7836
+ const stageWidth = compactMeta ? Math.max(12, columns - 6) : Math.max(12, columns - Math.min(metaSuffix.length + 8, 32) - 6);
7837
+ const stageText = truncate(stage, Math.min(72, stageWidth));
7838
+ return /* @__PURE__ */ jsxs7(Box9, { flexDirection: "column", width: "100%", children: [
7839
+ /* @__PURE__ */ jsxs7(Box9, { width: "100%", children: [
7785
7840
  /* @__PURE__ */ jsx12(Box9, { width: 2, flexShrink: 0, children: /* @__PURE__ */ jsx12(BlinkingCircle, { color: THEME.primary }) }),
7786
- /* @__PURE__ */ jsx12(ShimmerText, { bold: true, variant: isActive ? "accent" : "ready", children: stageText }),
7787
- /* @__PURE__ */ jsxs7(Text10, { color: THEME.dimGray, wrap: "truncate", children: [
7841
+ /* @__PURE__ */ jsx12(Box9, { flexGrow: 1, minWidth: 0, children: isActive ? /* @__PURE__ */ jsx12(Text10, { color: THEME.primary, bold: true, wrap: "truncate-end", children: stageText }) : /* @__PURE__ */ jsx12(ShimmerText, { bold: true, variant: "ready", children: stageText }) }),
7842
+ !compactMeta && /* @__PURE__ */ jsx12(Box9, { flexShrink: 0, children: /* @__PURE__ */ jsxs7(Text10, { color: THEME.dimGray, wrap: "truncate", children: [
7788
7843
  " ",
7789
7844
  metaSuffix
7790
- ] })
7845
+ ] }) })
7791
7846
  ] }),
7792
- detailContent.length > 0 && /* @__PURE__ */ jsxs7(Box9, { children: [
7847
+ compactMeta && /* @__PURE__ */ jsxs7(Box9, { width: "100%", children: [
7793
7848
  /* @__PURE__ */ jsx12(Box9, { width: 2, flexShrink: 0 }),
7794
- /* @__PURE__ */ jsx12(Text10, { color: THEME.dimGray, wrap: "truncate", children: truncate(detailContent, TUI_DISPLAY_LIMITS.DETAIL_TEXT_WIDTH) })
7849
+ /* @__PURE__ */ jsx12(Text10, { color: THEME.dimGray, wrap: "truncate-end", children: metaSuffix })
7850
+ ] }),
7851
+ detailContent.length > 0 && /* @__PURE__ */ jsxs7(Box9, { width: "100%", children: [
7852
+ /* @__PURE__ */ jsx12(Box9, { width: 2, flexShrink: 0 }),
7853
+ /* @__PURE__ */ jsx12(Text10, { color: THEME.dimGray, wrap: "truncate-end", children: truncate(detailContent, TUI_DISPLAY_LIMITS.DETAIL_TEXT_WIDTH) })
7795
7854
  ] })
7796
7855
  ] });
7797
7856
  };
@@ -7806,6 +7865,10 @@ function parseStatusLines(status) {
7806
7865
  detail: isThinking && lines.length > 1 ? lines[lines.length - 1].slice(0, 120) : ""
7807
7866
  };
7808
7867
  }
7868
+ function shouldShowActiveStatus(isProcessing, liveProgress) {
7869
+ if (isProcessing) return true;
7870
+ return liveProgress.mode === "tool" || liveProgress.activeTool.length > 0;
7871
+ }
7809
7872
  var StatusDisplay = memo9(({
7810
7873
  retryState,
7811
7874
  isProcessing,
@@ -7816,7 +7879,8 @@ var StatusDisplay = memo9(({
7816
7879
  }) => {
7817
7880
  const safe = liveProgress ?? DEFAULT_LIVE_PROGRESS;
7818
7881
  const isWaitingForInput = inputRequest?.status === "active";
7819
- const statusElapsed = useStatusTimer(currentStatus, isProcessing && !isWaitingForInput);
7882
+ const showActiveStatus = shouldShowActiveStatus(isProcessing, safe);
7883
+ const statusElapsed = useStatusTimer(currentStatus, showActiveStatus && !isWaitingForInput);
7820
7884
  if (retryState?.status === "retrying") {
7821
7885
  return /* @__PURE__ */ jsx13(RetryView, { retryState });
7822
7886
  }
@@ -7849,7 +7913,7 @@ var StatusDisplay = memo9(({
7849
7913
  statusElapsed,
7850
7914
  totalTokens,
7851
7915
  liveProgress: safe,
7852
- isActive: false
7916
+ isActive: showActiveStatus
7853
7917
  }
7854
7918
  );
7855
7919
  }
@@ -7857,8 +7921,8 @@ var StatusDisplay = memo9(({
7857
7921
  });
7858
7922
 
7859
7923
  // src/platform/tui/components/ChatInput.tsx
7860
- import { useMemo as useMemo4, useCallback as useCallback14, useRef as useRef12, memo as memo10, useState as useState12 } from "react";
7861
- import { Box as Box14, Text as Text15 } from "ink";
7924
+ import { useMemo as useMemo5, useCallback as useCallback14, useRef as useRef13, memo as memo10, useState as useState12 } from "react";
7925
+ import { Box as Box15, Text as Text16 } from "ink";
7862
7926
 
7863
7927
  // src/platform/tui/components/input/AutocompletePreview.tsx
7864
7928
  import { Box as Box10, Text as Text11 } from "ink";
@@ -7925,6 +7989,7 @@ var SimpleTextInput = ({
7925
7989
  onSubmit,
7926
7990
  placeholder,
7927
7991
  isPassword,
7992
+ placeholderColor = THEME.dimGray,
7928
7993
  onSpecialKey
7929
7994
  }) => {
7930
7995
  const chars = useMemo3(() => Array.from(value || ""), [value]);
@@ -8014,7 +8079,7 @@ var SimpleTextInput = ({
8014
8079
  if (displayChars.length === 0) {
8015
8080
  return /* @__PURE__ */ jsxs9(Box11, { width: "100%", children: [
8016
8081
  /* @__PURE__ */ jsx15(Text12, { inverse: true, children: " " }),
8017
- placeholder ? /* @__PURE__ */ jsx15(Box11, { flexGrow: 1, flexShrink: 1, minWidth: 0, children: /* @__PURE__ */ jsx15(Text12, { color: THEME.dimGray, wrap: "truncate-end", children: placeholder }) }) : null
8082
+ placeholder ? /* @__PURE__ */ jsx15(Box11, { flexGrow: 1, flexShrink: 1, minWidth: 0, children: /* @__PURE__ */ jsx15(Text12, { color: placeholderColor, wrap: "truncate-end", children: placeholder }) }) : null
8018
8083
  ] });
8019
8084
  }
8020
8085
  const c = Math.min(cursorRef.current, displayChars.length);
@@ -8037,6 +8102,7 @@ var SecretInputArea = ({
8037
8102
  setSecretInput,
8038
8103
  onSecretSubmit
8039
8104
  }) => {
8105
+ const placeholder = resolveActiveInputPlaceholder(inputRequest);
8040
8106
  return /* @__PURE__ */ jsxs10(
8041
8107
  Box12,
8042
8108
  {
@@ -8056,7 +8122,8 @@ var SecretInputArea = ({
8056
8122
  value: secretInput,
8057
8123
  onChange: setSecretInput,
8058
8124
  onSubmit: onSecretSubmit,
8059
- placeholder: inputRequest.isPassword ? "hidden input" : "type answer",
8125
+ placeholder,
8126
+ placeholderColor: THEME.primary,
8060
8127
  isPassword: inputRequest.isPassword
8061
8128
  }
8062
8129
  ) })
@@ -8096,6 +8163,7 @@ var NormalInputArea = ({
8096
8163
  onChange,
8097
8164
  onSubmit,
8098
8165
  placeholder: placeholder ?? "Describe the target or type /help",
8166
+ placeholderColor: THEME.primary,
8099
8167
  onSpecialKey
8100
8168
  },
8101
8169
  inputKey
@@ -8106,8 +8174,78 @@ var NormalInputArea = ({
8106
8174
  );
8107
8175
  };
8108
8176
 
8109
- // src/platform/tui/components/ChatInput.tsx
8177
+ // src/platform/tui/components/input/PolicyTextArea.tsx
8178
+ import { useEffect as useEffect9, useMemo as useMemo4, useRef as useRef12 } from "react";
8179
+ import { Box as Box14, Text as Text15, useInput as useInput3, useStdout as useStdout3 } from "ink";
8110
8180
  import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
8181
+ function applyPolicyInputEdit(currentValue, input, key) {
8182
+ if (key.escape) return { kind: "ignore" };
8183
+ if (key.ctrl && (input === "j" || input === "J")) {
8184
+ return { kind: "change", value: `${currentValue}
8185
+ ` };
8186
+ }
8187
+ if (key.return) {
8188
+ return { kind: "submit" };
8189
+ }
8190
+ if (key.backspace || key.delete) {
8191
+ if (currentValue.length === 0) return { kind: "ignore" };
8192
+ return { kind: "change", value: currentValue.slice(0, -1) };
8193
+ }
8194
+ if (!input || key.ctrl || key.meta) {
8195
+ return { kind: "ignore" };
8196
+ }
8197
+ return { kind: "change", value: `${currentValue}${input}` };
8198
+ }
8199
+ var PolicyTextArea = ({
8200
+ value,
8201
+ onChange,
8202
+ onSubmit,
8203
+ placeholder,
8204
+ maxVisibleLines = 8
8205
+ }) => {
8206
+ const { write } = useStdout3();
8207
+ const valueRef = useRef12(value);
8208
+ valueRef.current = value;
8209
+ useEffect9(() => {
8210
+ write?.("\x1B[?25h");
8211
+ return () => {
8212
+ write?.("\x1B[?25l");
8213
+ };
8214
+ }, [write]);
8215
+ useInput3((input, key) => {
8216
+ const result = applyPolicyInputEdit(valueRef.current, input, key);
8217
+ if (result.kind === "submit") {
8218
+ onSubmit();
8219
+ return;
8220
+ }
8221
+ if (result.kind === "change") {
8222
+ onChange(result.value);
8223
+ }
8224
+ }, { isActive: true });
8225
+ const lines = useMemo4(() => {
8226
+ if (!value) return [];
8227
+ return value.split("\n");
8228
+ }, [value]);
8229
+ if (lines.length === 0) {
8230
+ return /* @__PURE__ */ jsxs12(Box14, { flexDirection: "column", width: "100%", children: [
8231
+ /* @__PURE__ */ jsx18(Text15, { inverse: true, children: " " }),
8232
+ /* @__PURE__ */ jsx18(Box14, { marginTop: 0, children: /* @__PURE__ */ jsx18(Text15, { color: THEME.dimGray, wrap: "wrap", children: placeholder }) })
8233
+ ] });
8234
+ }
8235
+ const visibleLines = lines.slice(Math.max(0, lines.length - maxVisibleLines));
8236
+ const lastIndex = visibleLines.length - 1;
8237
+ return /* @__PURE__ */ jsx18(Box14, { flexDirection: "column", width: "100%", children: visibleLines.map((line, index) => {
8238
+ const isLast = index === lastIndex;
8239
+ return /* @__PURE__ */ jsxs12(Box14, { children: [
8240
+ /* @__PURE__ */ jsx18(Text15, { children: isLast ? line : `${line}
8241
+ ` }),
8242
+ isLast && /* @__PURE__ */ jsx18(Text15, { inverse: true, children: " " })
8243
+ ] }, `${index}:${line}`);
8244
+ }) });
8245
+ };
8246
+
8247
+ // src/platform/tui/components/ChatInput.tsx
8248
+ import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
8111
8249
  var MAX_SUGGESTIONS = 6;
8112
8250
  var ChatInput = memo10(({
8113
8251
  value,
@@ -8126,7 +8264,7 @@ var ChatInput = memo10(({
8126
8264
  const isSlashMode = value.startsWith("/");
8127
8265
  const partialCmd = isSlashMode ? value.slice(1).split(" ")[0] : "";
8128
8266
  const hasArgs = isSlashMode && value.includes(" ");
8129
- const suggestions = useMemo4(() => {
8267
+ const suggestions = useMemo5(() => {
8130
8268
  if (!isSlashMode || hasArgs) return [];
8131
8269
  return getMatchingCommands(partialCmd).slice(0, MAX_SUGGESTIONS);
8132
8270
  }, [isSlashMode, partialCmd, hasArgs]);
@@ -8134,31 +8272,31 @@ var ChatInput = memo10(({
8134
8272
  const showCommandHelp = isSlashMode && !hasArgs && suggestions.length === 0 && value.length > 1;
8135
8273
  const [selectedIdx, setSelectedIdx] = useState12(0);
8136
8274
  const clampedIdx = Math.min(selectedIdx, Math.max(0, suggestions.length - 1));
8137
- const selectedIdxRef = useRef12(clampedIdx);
8275
+ const selectedIdxRef = useRef13(clampedIdx);
8138
8276
  selectedIdxRef.current = clampedIdx;
8139
- const suggestionsRef = useRef12(suggestions);
8277
+ const suggestionsRef = useRef13(suggestions);
8140
8278
  suggestionsRef.current = suggestions;
8141
- const isSlashModeRef = useRef12(isSlashMode);
8279
+ const isSlashModeRef = useRef13(isSlashMode);
8142
8280
  isSlashModeRef.current = isSlashMode;
8143
- const hasArgsRef = useRef12(hasArgs);
8281
+ const hasArgsRef = useRef13(hasArgs);
8144
8282
  hasArgsRef.current = hasArgs;
8145
- const showPreviewRef = useRef12(showPreview);
8283
+ const showPreviewRef = useRef13(showPreview);
8146
8284
  showPreviewRef.current = showPreview;
8147
- const inputRequestRef = useRef12(inputRequest);
8285
+ const inputRequestRef = useRef13(inputRequest);
8148
8286
  inputRequestRef.current = inputRequest;
8149
- const onChangeRef = useRef12(onChange);
8287
+ const onChangeRef = useRef13(onChange);
8150
8288
  onChangeRef.current = onChange;
8151
- const onRecallQueuedInputRef = useRef12(onRecallQueuedInput);
8289
+ const onRecallQueuedInputRef = useRef13(onRecallQueuedInput);
8152
8290
  onRecallQueuedInputRef.current = onRecallQueuedInput;
8153
- const queuedCountRef = useRef12(queuedCount);
8291
+ const queuedCountRef = useRef13(queuedCount);
8154
8292
  queuedCountRef.current = queuedCount;
8155
- const latestValueRef = useRef12(value);
8293
+ const latestValueRef = useRef13(value);
8156
8294
  latestValueRef.current = value;
8157
8295
  const handleLocalChange = useCallback14((newVal) => {
8158
8296
  latestValueRef.current = newVal;
8159
8297
  onChange(newVal);
8160
8298
  }, [onChange]);
8161
- const latestSecretRef = useRef12(secretInput);
8299
+ const latestSecretRef = useRef13(secretInput);
8162
8300
  latestSecretRef.current = secretInput;
8163
8301
  const handleSecretChange = useCallback14((newVal) => {
8164
8302
  latestSecretRef.current = newVal;
@@ -8175,7 +8313,7 @@ var ChatInput = memo10(({
8175
8313
  setSelectedIdx(0);
8176
8314
  setInputKey((k) => k + 1);
8177
8315
  }, []);
8178
- const onSubmitRef = useRef12(onSubmit);
8316
+ const onSubmitRef = useRef13(onSubmit);
8179
8317
  onSubmitRef.current = onSubmit;
8180
8318
  const wrappedOnSubmit = useCallback14((_staleVal) => {
8181
8319
  const finalValue = latestValueRef.current;
@@ -8197,7 +8335,7 @@ var ChatInput = memo10(({
8197
8335
  }
8198
8336
  onSubmitRef.current(finalValue);
8199
8337
  }, [completeCommand]);
8200
- const onSecretSubmitRef = useRef12(onSecretSubmit);
8338
+ const onSecretSubmitRef = useRef13(onSecretSubmit);
8201
8339
  onSecretSubmitRef.current = onSecretSubmit;
8202
8340
  const wrappedSecretSubmit = useCallback14((_staleVal) => {
8203
8341
  onSecretSubmitRef.current(latestSecretRef.current);
@@ -8228,24 +8366,24 @@ var ChatInput = memo10(({
8228
8366
  }
8229
8367
  return false;
8230
8368
  }, [completeCommand]);
8231
- return /* @__PURE__ */ jsxs12(Box14, { flexDirection: "column", width: "100%", children: [
8232
- showPreview && /* @__PURE__ */ jsx18(
8369
+ return /* @__PURE__ */ jsxs13(Box15, { flexDirection: "column", width: "100%", children: [
8370
+ showPreview && /* @__PURE__ */ jsx19(
8233
8371
  AutocompletePreview,
8234
8372
  {
8235
8373
  suggestions,
8236
8374
  clampedIdx
8237
8375
  }
8238
8376
  ),
8239
- showCommandHelp && /* @__PURE__ */ jsx18(Box14, { borderStyle: "round", borderColor: THEME.border.default, marginBottom: 1, children: /* @__PURE__ */ jsx18(Text15, { color: THEME.gray, children: "No matching command. Type `/help` to see all commands." }) }),
8240
- inputRequest.status !== "active" && queuedCount > 0 && /* @__PURE__ */ jsxs12(Box14, { marginBottom: 1, width: "100%", children: [
8241
- /* @__PURE__ */ jsx18(Text15, { dimColor: true, children: "queued " }),
8242
- /* @__PURE__ */ jsx18(Text15, { color: THEME.primary, children: queuedCount }),
8243
- queuedPreview && /* @__PURE__ */ jsx18(Text15, { dimColor: true, children: ` next: ${queuedPreview.slice(0, 30)}${queuedPreview.length > 30 ? "..." : ""}` }),
8244
- /* @__PURE__ */ jsx18(Text15, { dimColor: true, children: " \xB7 \u2191 to recall" })
8377
+ showCommandHelp && /* @__PURE__ */ jsx19(Box15, { borderStyle: "round", borderColor: THEME.border.default, marginBottom: 1, children: /* @__PURE__ */ jsx19(Text16, { color: THEME.gray, children: "No matching command. Type `/help` to see all commands." }) }),
8378
+ inputRequest.status !== "active" && queuedCount > 0 && /* @__PURE__ */ jsxs13(Box15, { marginBottom: 1, width: "100%", children: [
8379
+ /* @__PURE__ */ jsx19(Text16, { dimColor: true, children: "queued " }),
8380
+ /* @__PURE__ */ jsx19(Text16, { color: THEME.primary, children: queuedCount }),
8381
+ queuedPreview && /* @__PURE__ */ jsx19(Text16, { dimColor: true, children: ` next: ${queuedPreview.slice(0, 30)}${queuedPreview.length > 30 ? "..." : ""}` }),
8382
+ /* @__PURE__ */ jsx19(Text16, { dimColor: true, children: " \xB7 \u2191 to recall" })
8245
8383
  ] }),
8246
8384
  inputRequest.status === "active" ? (
8247
8385
  /* Active input request — yellow top/bottom border */
8248
- /* @__PURE__ */ jsx18(
8386
+ /* @__PURE__ */ jsx19(
8249
8387
  SecretInputArea,
8250
8388
  {
8251
8389
  inputRequest,
@@ -8257,7 +8395,7 @@ var ChatInput = memo10(({
8257
8395
  )
8258
8396
  ) : (
8259
8397
  /* Normal input — dim top/bottom border */
8260
- /* @__PURE__ */ jsx18(
8398
+ /* @__PURE__ */ jsx19(
8261
8399
  NormalInputArea,
8262
8400
  {
8263
8401
  inputKey,
@@ -8273,9 +8411,9 @@ var ChatInput = memo10(({
8273
8411
  });
8274
8412
 
8275
8413
  // src/platform/tui/components/footer.tsx
8276
- import { memo as memo11, useState as useState13, useEffect as useEffect9 } from "react";
8277
- import { Box as Box15, Text as Text16 } from "ink";
8278
- import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
8414
+ import { memo as memo11, useState as useState13, useEffect as useEffect10 } from "react";
8415
+ import { Box as Box16, Text as Text17 } from "ink";
8416
+ import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
8279
8417
  var SECS_PER_HOUR = 3600;
8280
8418
  var SECS_PER_MINUTE = 60;
8281
8419
  var SHORTCUTS_HINT_DEBOUNCE_MS = 200;
@@ -8310,7 +8448,7 @@ var Footer = memo11(({
8310
8448
  const ctxPct = totalTokens > 0 ? Math.round(totalTokens / LLM_LIMITS.streamMaxTokens * 100) : 0;
8311
8449
  const canShowHint = !isProcessing && inputText.length === 0;
8312
8450
  const [showHint, setShowHint] = useState13(false);
8313
- useEffect9(() => {
8451
+ useEffect10(() => {
8314
8452
  if (!canShowHint) {
8315
8453
  setShowHint(false);
8316
8454
  return;
@@ -8343,18 +8481,18 @@ var Footer = memo11(({
8343
8481
  const rightWidth = rightText.length;
8344
8482
  const availableLeft = Math.max(0, columns - 4 - rightWidth);
8345
8483
  const renderedLeft = truncateTail(leftText, availableLeft);
8346
- return /* @__PURE__ */ jsxs13(Box15, { width: "100%", marginTop: 1, children: [
8347
- /* @__PURE__ */ jsx19(Box15, { flexShrink: 0, children: /* @__PURE__ */ jsx19(Text16, { color: THEME.dimGray, wrap: "truncate-end", children: renderedLeft }) }),
8348
- /* @__PURE__ */ jsx19(Box15, { flexGrow: 1 }),
8349
- rightText.length > 0 && /* @__PURE__ */ jsx19(Box15, { flexShrink: 0, children: /* @__PURE__ */ jsx19(Text16, { color: THEME.dimGray, wrap: "truncate-end", children: rightText }) })
8484
+ return /* @__PURE__ */ jsxs14(Box16, { width: "100%", marginTop: 1, children: [
8485
+ /* @__PURE__ */ jsx20(Box16, { flexShrink: 0, children: /* @__PURE__ */ jsx20(Text17, { color: THEME.dimGray, wrap: "truncate-end", children: renderedLeft }) }),
8486
+ /* @__PURE__ */ jsx20(Box16, { flexGrow: 1 }),
8487
+ rightText.length > 0 && /* @__PURE__ */ jsx20(Box16, { flexShrink: 0, children: /* @__PURE__ */ jsx20(Text17, { color: THEME.dimGray, wrap: "truncate-end", children: rightText }) })
8350
8488
  ] });
8351
8489
  });
8352
8490
  var footer_default = Footer;
8353
8491
 
8354
8492
  // src/platform/tui/components/Modal.tsx
8355
- import { useMemo as useMemo5, memo as memo12, useCallback as useCallback15, useRef as useRef13 } from "react";
8356
- import { Box as Box16, Text as Text17, useInput as useInput3 } from "ink";
8357
- import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
8493
+ import { useMemo as useMemo6, memo as memo12, useCallback as useCallback15, useRef as useRef14 } from "react";
8494
+ import { Box as Box17, Text as Text18, useInput as useInput4 } from "ink";
8495
+ import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
8358
8496
  var MODAL_TITLES = {
8359
8497
  findings: "\u25C8 FINDINGS \u25C8",
8360
8498
  report: "\u25C8 OPERATION REPORT \u25C8",
@@ -8369,21 +8507,21 @@ var Modal = memo12(({
8369
8507
  onScroll,
8370
8508
  onClose
8371
8509
  }) => {
8372
- const onScrollRef = useRef13(onScroll);
8510
+ const onScrollRef = useRef14(onScroll);
8373
8511
  onScrollRef.current = onScroll;
8374
- const onCloseRef = useRef13(onClose);
8512
+ const onCloseRef = useRef14(onClose);
8375
8513
  onCloseRef.current = onClose;
8376
8514
  const { columns, rows } = useTerminalSize();
8377
8515
  const terminalHeight = rows;
8378
8516
  const terminalWidth = columns - 4;
8379
8517
  const maxHeight = Math.max(1, terminalHeight - 6);
8380
- const lines = useMemo5(() => content.split("\n"), [content]);
8518
+ const lines = useMemo6(() => content.split("\n"), [content]);
8381
8519
  const totalLines = lines.length;
8382
- const visibleLines = useMemo5(
8520
+ const visibleLines = useMemo6(
8383
8521
  () => lines.slice(scrollOffset, scrollOffset + maxHeight),
8384
8522
  [lines, scrollOffset, maxHeight]
8385
8523
  );
8386
- useInput3(useCallback15((input, key) => {
8524
+ useInput4(useCallback15((input, key) => {
8387
8525
  if (key.escape || input === "q") {
8388
8526
  onCloseRef.current();
8389
8527
  } else if (key.upArrow || input === "k") {
@@ -8400,20 +8538,20 @@ var Modal = memo12(({
8400
8538
  const endLine = Math.min(scrollOffset + maxHeight, totalLines);
8401
8539
  const scrollbarHeight = Math.max(1, Math.floor(maxHeight * (maxHeight / Math.max(totalLines, 1))));
8402
8540
  const scrollbarPosition = totalLines > maxHeight ? Math.floor(scrollOffset / (totalLines - maxHeight) * (maxHeight - scrollbarHeight)) : 0;
8403
- return /* @__PURE__ */ jsxs14(
8404
- Box16,
8541
+ return /* @__PURE__ */ jsxs15(
8542
+ Box17,
8405
8543
  {
8406
8544
  flexDirection: "column",
8407
8545
  width: terminalWidth,
8408
8546
  height: terminalHeight,
8409
8547
  children: [
8410
- /* @__PURE__ */ jsx20(Box16, { justifyContent: "center", marginBottom: 0, children: /* @__PURE__ */ jsx20(Text17, { color: THEME.primary, bold: true, children: (() => {
8548
+ /* @__PURE__ */ jsx21(Box17, { justifyContent: "center", marginBottom: 0, children: /* @__PURE__ */ jsx21(Text18, { color: THEME.primary, bold: true, children: (() => {
8411
8549
  const title = MODAL_TITLES[type];
8412
8550
  const sideWidth = Math.max(3, Math.floor((terminalWidth - title.length - 2) / 2));
8413
8551
  return `${"\u2500".repeat(sideWidth)} ${title} ${"\u2500".repeat(sideWidth)}`;
8414
8552
  })() }) }),
8415
- /* @__PURE__ */ jsx20(
8416
- Box16,
8553
+ /* @__PURE__ */ jsx21(
8554
+ Box17,
8417
8555
  {
8418
8556
  flexDirection: "column",
8419
8557
  borderStyle: "round",
@@ -8422,17 +8560,17 @@ var Modal = memo12(({
8422
8560
  flexGrow: 1,
8423
8561
  children: visibleLines.map((line, i) => {
8424
8562
  const showScrollbar = totalLines > maxHeight && i >= scrollbarPosition && i < scrollbarPosition + scrollbarHeight;
8425
- return /* @__PURE__ */ jsxs14(Box16, { children: [
8426
- /* @__PURE__ */ jsx20(Text17, { color: THEME.white, wrap: "truncate", children: line }),
8427
- /* @__PURE__ */ jsx20(Box16, { flexGrow: 1 }),
8428
- totalLines > maxHeight && /* @__PURE__ */ jsx20(Text17, { color: showScrollbar ? THEME.primary : THEME.dimGray, children: showScrollbar ? "\u2588" : "\u2502" })
8563
+ return /* @__PURE__ */ jsxs15(Box17, { children: [
8564
+ /* @__PURE__ */ jsx21(Text18, { color: THEME.white, wrap: "truncate", children: line }),
8565
+ /* @__PURE__ */ jsx21(Box17, { flexGrow: 1 }),
8566
+ totalLines > maxHeight && /* @__PURE__ */ jsx21(Text18, { color: showScrollbar ? THEME.primary : THEME.dimGray, children: showScrollbar ? "\u2588" : "\u2502" })
8429
8567
  ] }, i);
8430
8568
  })
8431
8569
  }
8432
8570
  ),
8433
- /* @__PURE__ */ jsxs14(Box16, { justifyContent: "space-between", paddingX: 1, children: [
8434
- /* @__PURE__ */ jsx20(Text17, { color: THEME.dimGray, children: "\u2191\u2193/jk: scroll | g/G: top/bottom | ESC/q: close" }),
8435
- /* @__PURE__ */ jsxs14(Text17, { color: THEME.primary, children: [
8571
+ /* @__PURE__ */ jsxs15(Box17, { justifyContent: "space-between", paddingX: 1, children: [
8572
+ /* @__PURE__ */ jsx21(Text18, { color: THEME.dimGray, children: "\u2191\u2193/jk: scroll | g/G: top/bottom | ESC/q: close" }),
8573
+ /* @__PURE__ */ jsxs15(Text18, { color: THEME.primary, children: [
8436
8574
  startLine,
8437
8575
  "-",
8438
8576
  endLine,
@@ -8446,9 +8584,9 @@ var Modal = memo12(({
8446
8584
  });
8447
8585
 
8448
8586
  // src/platform/tui/components/PolicyComposerModal.tsx
8449
- import { memo as memo13, useCallback as useCallback16, useRef as useRef14 } from "react";
8450
- import { Box as Box17, Text as Text18, useInput as useInput4 } from "ink";
8451
- import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
8587
+ import { memo as memo13, useCallback as useCallback16, useRef as useRef15 } from "react";
8588
+ import { Box as Box18, Text as Text19, useInput as useInput5 } from "ink";
8589
+ import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
8452
8590
  var PolicyComposerModal = memo13(({
8453
8591
  value,
8454
8592
  onChange,
@@ -8457,54 +8595,68 @@ var PolicyComposerModal = memo13(({
8457
8595
  guide,
8458
8596
  placeholder
8459
8597
  }) => {
8460
- const onCloseRef = useRef14(onClose);
8598
+ const onCloseRef = useRef15(onClose);
8461
8599
  onCloseRef.current = onClose;
8462
- const onSubmitRef = useRef14(onSubmit);
8600
+ const onSubmitRef = useRef15(onSubmit);
8463
8601
  onSubmitRef.current = onSubmit;
8464
8602
  const { columns, rows } = useTerminalSize();
8465
- const terminalHeight = rows;
8466
- const terminalWidth = columns - 4;
8467
- useInput4(useCallback16((_input, key) => {
8603
+ const terminalHeight = Math.max(1, rows);
8604
+ const terminalWidth = Math.max(1, columns - 4);
8605
+ const shouldStackFooter = shouldStackPolicyComposerFooter(terminalWidth);
8606
+ useInput5(useCallback16((_input, key) => {
8468
8607
  if (key.escape) {
8469
8608
  onCloseRef.current();
8470
8609
  }
8471
8610
  }, []), { isActive: true });
8472
- return /* @__PURE__ */ jsxs15(Box17, { flexDirection: "column", width: terminalWidth, height: terminalHeight, children: [
8473
- /* @__PURE__ */ jsx21(Box17, { justifyContent: "center", children: /* @__PURE__ */ jsx21(Text18, { color: THEME.primary, bold: true, children: (() => {
8474
- const title = "\u25C8 COMPETITION POLICY \u25C8";
8475
- const sideWidth = Math.max(3, Math.floor((terminalWidth - title.length - 2) / 2));
8476
- return `${"\u2500".repeat(sideWidth)} ${title} ${"\u2500".repeat(sideWidth)}`;
8477
- })() }) }),
8478
- /* @__PURE__ */ jsxs15(
8479
- Box17,
8611
+ return /* @__PURE__ */ jsxs16(Box18, { flexDirection: "column", width: terminalWidth, height: terminalHeight, children: [
8612
+ /* @__PURE__ */ jsx22(Box18, { justifyContent: "center", width: "100%", children: /* @__PURE__ */ jsx22(Text19, { color: THEME.primary, bold: true, wrap: "truncate-end", children: formatPolicyComposerTitle(terminalWidth) }) }),
8613
+ /* @__PURE__ */ jsxs16(
8614
+ Box18,
8480
8615
  {
8481
8616
  flexDirection: "column",
8617
+ width: "100%",
8482
8618
  borderStyle: "round",
8483
8619
  borderColor: THEME.primary,
8484
8620
  paddingX: 1,
8485
8621
  paddingY: 1,
8486
8622
  flexGrow: 1,
8487
8623
  children: [
8488
- /* @__PURE__ */ jsx21(Text18, { color: THEME.white, bold: true, children: "Optional bootstrap policy before /start" }),
8489
- /* @__PURE__ */ jsx21(Text18, { color: THEME.dimGray, children: " " }),
8490
- guide.split("\n").map((line, index) => /* @__PURE__ */ jsx21(Text18, { color: THEME.gray, wrap: "wrap", children: line }, index)),
8491
- /* @__PURE__ */ jsx21(Text18, { color: THEME.dimGray, children: " " }),
8492
- /* @__PURE__ */ jsx21(Box17, { borderStyle: "round", borderColor: THEME.primary, paddingX: 1, paddingY: 0, children: /* @__PURE__ */ jsx21(
8493
- NormalInputArea,
8624
+ /* @__PURE__ */ jsx22(Text19, { color: THEME.white, bold: true, children: "Optional bootstrap policy before /start" }),
8625
+ /* @__PURE__ */ jsx22(Text19, { color: THEME.dimGray, children: " " }),
8626
+ guide.split("\n").map((line, index) => /* @__PURE__ */ jsx22(Text19, { color: THEME.gray, wrap: "wrap", children: line }, index)),
8627
+ /* @__PURE__ */ jsx22(Text19, { color: THEME.dimGray, children: " " }),
8628
+ /* @__PURE__ */ jsx22(
8629
+ Box18,
8494
8630
  {
8495
- inputKey: 0,
8496
- value,
8497
- onChange,
8498
- onSubmit: () => onSubmitRef.current(),
8499
- placeholder
8631
+ width: "100%",
8632
+ borderStyle: "round",
8633
+ borderColor: THEME.primary,
8634
+ paddingX: 1,
8635
+ paddingY: 0,
8636
+ flexGrow: 1,
8637
+ children: /* @__PURE__ */ jsx22(
8638
+ PolicyTextArea,
8639
+ {
8640
+ value,
8641
+ onChange,
8642
+ onSubmit: onSubmitRef.current,
8643
+ placeholder
8644
+ }
8645
+ )
8500
8646
  }
8501
- ) })
8647
+ )
8502
8648
  ]
8503
8649
  }
8504
8650
  ),
8505
- /* @__PURE__ */ jsxs15(Box17, { justifyContent: "space-between", paddingX: 1, children: [
8506
- /* @__PURE__ */ jsx21(Text18, { color: THEME.dimGray, children: "Enter: continue | Esc: cancel start" }),
8507
- /* @__PURE__ */ jsxs15(Text18, { color: THEME.primary, children: [
8651
+ shouldStackFooter ? /* @__PURE__ */ jsxs16(Box18, { flexDirection: "column", paddingX: 1, width: "100%", children: [
8652
+ /* @__PURE__ */ jsx22(Text19, { color: THEME.dimGray, wrap: "wrap", children: "Enter: continue | Ctrl+J: newline | Esc: cancel start" }),
8653
+ /* @__PURE__ */ jsx22(Box18, { justifyContent: "flex-end", width: "100%", children: /* @__PURE__ */ jsxs16(Text19, { color: THEME.primary, children: [
8654
+ value.trim().length,
8655
+ " chars"
8656
+ ] }) })
8657
+ ] }) : /* @__PURE__ */ jsxs16(Box18, { justifyContent: "space-between", paddingX: 1, width: "100%", children: [
8658
+ /* @__PURE__ */ jsx22(Text19, { color: THEME.dimGray, wrap: "wrap", children: "Enter: continue | Ctrl+J: newline | Esc: cancel start" }),
8659
+ /* @__PURE__ */ jsxs16(Text19, { color: THEME.primary, children: [
8508
8660
  value.trim().length,
8509
8661
  " chars"
8510
8662
  ] })
@@ -8513,8 +8665,8 @@ var PolicyComposerModal = memo13(({
8513
8665
  });
8514
8666
 
8515
8667
  // src/platform/tui/components/app/bottom-region.tsx
8516
- import { Box as Box18, Text as Text19 } from "ink";
8517
- import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
8668
+ import { Box as Box19, Text as Text20 } from "ink";
8669
+ import { jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
8518
8670
  var BottomRegion = ({
8519
8671
  input,
8520
8672
  setInput,
@@ -8539,8 +8691,9 @@ var BottomRegion = ({
8539
8691
  }) => {
8540
8692
  const { columns } = useTerminalSize();
8541
8693
  const inputSeparatorColor = resolveInputSeparatorColor({ isProcessing, inputRequest });
8542
- return /* @__PURE__ */ jsxs16(Box18, { flexDirection: "column", width: "100%", children: [
8543
- /* @__PURE__ */ jsx22(
8694
+ const inputPlaceholder = resolveInputPlaceholder({ isProcessing, inputRequest });
8695
+ return /* @__PURE__ */ jsxs17(Box19, { flexDirection: "column", width: "100%", children: [
8696
+ /* @__PURE__ */ jsx23(
8544
8697
  StatusDisplay,
8545
8698
  {
8546
8699
  retryState,
@@ -8551,8 +8704,8 @@ var BottomRegion = ({
8551
8704
  inputRequest
8552
8705
  }
8553
8706
  ),
8554
- /* @__PURE__ */ jsx22(Text19, { color: inputSeparatorColor, children: "\u2500".repeat(Math.max(1, columns - 2)) }),
8555
- /* @__PURE__ */ jsx22(Box18, { width: "100%", children: /* @__PURE__ */ jsx22(
8707
+ /* @__PURE__ */ jsx23(Text20, { color: inputSeparatorColor, children: "\u2500".repeat(Math.max(1, columns - 2)) }),
8708
+ /* @__PURE__ */ jsx23(Box19, { width: "100%", children: /* @__PURE__ */ jsx23(
8556
8709
  ChatInput,
8557
8710
  {
8558
8711
  value: input,
@@ -8561,7 +8714,7 @@ var BottomRegion = ({
8561
8714
  onRecallQueuedInput: recallQueuedInput,
8562
8715
  queuedCount: messageQueue.length,
8563
8716
  queuedPreview,
8564
- placeholder: "Describe the target or type /help",
8717
+ placeholder: inputPlaceholder,
8565
8718
  inputRequest,
8566
8719
  pendingInputCount: pendingInputRequests,
8567
8720
  secretInput,
@@ -8569,8 +8722,8 @@ var BottomRegion = ({
8569
8722
  onSecretSubmit: handleSecretSubmit
8570
8723
  }
8571
8724
  ) }),
8572
- /* @__PURE__ */ jsx22(Text19, { color: inputSeparatorColor, children: "\u2500".repeat(Math.max(1, columns - 2)) }),
8573
- /* @__PURE__ */ jsx22(Box18, { width: "100%", children: /* @__PURE__ */ jsx22(
8725
+ /* @__PURE__ */ jsx23(Text20, { color: inputSeparatorColor, children: "\u2500".repeat(Math.max(1, columns - 2)) }),
8726
+ /* @__PURE__ */ jsx23(Box19, { width: "100%", children: /* @__PURE__ */ jsx23(
8574
8727
  footer_default,
8575
8728
  {
8576
8729
  phase: stats.phase,
@@ -8591,8 +8744,8 @@ var BottomRegion = ({
8591
8744
  };
8592
8745
 
8593
8746
  // src/platform/tui/hooks/useModalMouseWheel.ts
8594
- import { useEffect as useEffect10 } from "react";
8595
- import { useStdin, useStdout as useStdout3 } from "ink";
8747
+ import { useEffect as useEffect11 } from "react";
8748
+ import { useStdin, useStdout as useStdout4 } from "ink";
8596
8749
  var ENABLE_MOUSE_REPORTING = "\x1B[?1000h\x1B[?1006h";
8597
8750
  var DISABLE_MOUSE_REPORTING = "\x1B[?1000l\x1B[?1006l";
8598
8751
  var SGR_MOUSE_RE = /\x1b\[<(\d+);(\d+);(\d+)([mM])/g;
@@ -8610,8 +8763,8 @@ function useModalMouseWheel({
8610
8763
  onScroll
8611
8764
  }) {
8612
8765
  const { stdin, setRawMode } = useStdin();
8613
- const { stdout } = useStdout3();
8614
- useEffect10(() => {
8766
+ const { stdout } = useStdout4();
8767
+ useEffect11(() => {
8615
8768
  if (!isActive) return;
8616
8769
  setRawMode?.(true);
8617
8770
  stdout.write?.(ENABLE_MOUSE_REPORTING);
@@ -8629,7 +8782,7 @@ function useModalMouseWheel({
8629
8782
  }
8630
8783
 
8631
8784
  // src/platform/tui/app.tsx
8632
- import { jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
8785
+ import { jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
8633
8786
  var MODEL_NAME = getModel() || DEFAULT_MODEL;
8634
8787
  var App = ({ autoApprove = false, target }) => {
8635
8788
  const {
@@ -8672,7 +8825,7 @@ var App = ({ autoApprove = false, target }) => {
8672
8825
  onScroll: handleModalScroll
8673
8826
  });
8674
8827
  if (policyComposer.isOpen) {
8675
- return /* @__PURE__ */ jsx23(Box19, { flexDirection: "column", paddingX: 1, width: terminalWidth, height: terminalHeight - 1, children: /* @__PURE__ */ jsx23(
8828
+ return /* @__PURE__ */ jsx24(Box20, { flexDirection: "column", paddingX: 1, width: terminalWidth, height: terminalHeight - 1, children: /* @__PURE__ */ jsx24(
8676
8829
  PolicyComposerModal,
8677
8830
  {
8678
8831
  value: policyComposer.value,
@@ -8687,7 +8840,7 @@ var App = ({ autoApprove = false, target }) => {
8687
8840
  ) });
8688
8841
  }
8689
8842
  if (modal.type) {
8690
- return /* @__PURE__ */ jsx23(Box19, { flexDirection: "column", paddingX: 1, width: terminalWidth, height: terminalHeight - 1, children: /* @__PURE__ */ jsx23(
8843
+ return /* @__PURE__ */ jsx24(Box20, { flexDirection: "column", paddingX: 1, width: terminalWidth, height: terminalHeight - 1, children: /* @__PURE__ */ jsx24(
8691
8844
  Modal,
8692
8845
  {
8693
8846
  type: modal.type,
@@ -8698,8 +8851,8 @@ var App = ({ autoApprove = false, target }) => {
8698
8851
  }
8699
8852
  ) });
8700
8853
  }
8701
- return /* @__PURE__ */ jsxs17(Box19, { flexDirection: "column", paddingX: 1, paddingBottom: 1, width: terminalWidth, children: [
8702
- /* @__PURE__ */ jsx23(Box19, { flexDirection: "column", width: "100%", children: /* @__PURE__ */ jsx23(
8854
+ return /* @__PURE__ */ jsxs18(Box20, { flexDirection: "column", paddingX: 1, paddingBottom: 1, width: terminalWidth, children: [
8855
+ /* @__PURE__ */ jsx24(Box20, { flexDirection: "column", width: "100%", children: /* @__PURE__ */ jsx24(
8703
8856
  MessageList,
8704
8857
  {
8705
8858
  messages,
@@ -8708,7 +8861,7 @@ var App = ({ autoApprove = false, target }) => {
8708
8861
  version: APP_VERSION
8709
8862
  }
8710
8863
  ) }),
8711
- /* @__PURE__ */ jsx23(Box19, { flexDirection: "column", marginTop: 1, width: "100%", children: /* @__PURE__ */ jsx23(
8864
+ /* @__PURE__ */ jsx24(Box20, { flexDirection: "column", marginTop: 1, width: "100%", children: /* @__PURE__ */ jsx24(
8712
8865
  BottomRegion,
8713
8866
  {
8714
8867
  input,
@@ -8738,8 +8891,8 @@ var App = ({ autoApprove = false, target }) => {
8738
8891
  var app_default = App;
8739
8892
 
8740
8893
  // src/platform/tui/components/SplashScreen.tsx
8741
- import { useEffect as useEffect11, useState as useState14 } from "react";
8742
- import { Box as Box20, Text as Text20 } from "ink";
8894
+ import { useEffect as useEffect12, useState as useState14 } from "react";
8895
+ import { Box as Box21, Text as Text21 } from "ink";
8743
8896
 
8744
8897
  // src/platform/tui/components/CoinFrames.ts
8745
8898
  var COIN_FRAMES = [
@@ -9430,14 +9583,14 @@ var COIN_FRAMES = [
9430
9583
  ];
9431
9584
 
9432
9585
  // src/platform/tui/components/SplashScreen.tsx
9433
- import { jsx as jsx24 } from "react/jsx-runtime";
9586
+ import { jsx as jsx25 } from "react/jsx-runtime";
9434
9587
  var SplashScreen = ({
9435
9588
  onComplete,
9436
9589
  durationMs = 3e3
9437
9590
  }) => {
9438
9591
  const { columns, rows } = useTerminalSize();
9439
9592
  const [frameIdx, setFrameIdx] = useState14(0);
9440
- useEffect11(() => {
9593
+ useEffect12(() => {
9441
9594
  const start = Date.now();
9442
9595
  const interval = setInterval(() => {
9443
9596
  const now = Date.now();
@@ -9452,27 +9605,27 @@ var SplashScreen = ({
9452
9605
  return () => clearInterval(interval);
9453
9606
  }, [durationMs, onComplete]);
9454
9607
  const currentFrame = COIN_FRAMES[frameIdx % COIN_FRAMES.length];
9455
- return /* @__PURE__ */ jsx24(
9456
- Box20,
9608
+ return /* @__PURE__ */ jsx25(
9609
+ Box21,
9457
9610
  {
9458
9611
  width: columns,
9459
9612
  minHeight: rows,
9460
9613
  flexDirection: "column",
9461
9614
  alignItems: "center",
9462
9615
  justifyContent: "center",
9463
- children: /* @__PURE__ */ jsx24(Box20, { flexDirection: "column", alignItems: "center", flexShrink: 0, children: /* @__PURE__ */ jsx24(Box20, { flexDirection: "column", alignItems: "center", children: currentFrame.map((line, i) => /* @__PURE__ */ jsx24(Box20, { flexShrink: 0, height: 1, children: /* @__PURE__ */ jsx24(Text20, { color: THEME.white, bold: true, wrap: "truncate-end", children: line }, `coin-text-${i}`) }, `coin-row-${i}`)) }) })
9616
+ children: /* @__PURE__ */ jsx25(Box21, { flexDirection: "column", alignItems: "center", flexShrink: 0, children: /* @__PURE__ */ jsx25(Box21, { flexDirection: "column", alignItems: "center", children: currentFrame.map((line, i) => /* @__PURE__ */ jsx25(Box21, { flexShrink: 0, height: 1, children: /* @__PURE__ */ jsx25(Text21, { color: THEME.white, bold: true, wrap: "truncate-end", children: line }, `coin-text-${i}`) }, `coin-row-${i}`)) }) })
9464
9617
  }
9465
9618
  );
9466
9619
  };
9467
9620
 
9468
9621
  // src/platform/tui/cli/interactive-runtime.tsx
9469
- import { jsx as jsx25 } from "react/jsx-runtime";
9622
+ import { jsx as jsx26 } from "react/jsx-runtime";
9470
9623
  var InteractiveRoot = ({ autoApprove, target }) => {
9471
- const [showSplash, setShowSplash] = React17.useState(true);
9624
+ const [showSplash, setShowSplash] = React18.useState(true);
9472
9625
  if (showSplash) {
9473
- return /* @__PURE__ */ jsx25(SplashScreen, { durationMs: 3e3, onComplete: () => setShowSplash(false) });
9626
+ return /* @__PURE__ */ jsx26(SplashScreen, { durationMs: 3e3, onComplete: () => setShowSplash(false) });
9474
9627
  }
9475
- return /* @__PURE__ */ jsx25(
9628
+ return /* @__PURE__ */ jsx26(
9476
9629
  app_default,
9477
9630
  {
9478
9631
  autoApprove,
@@ -9482,7 +9635,7 @@ var InteractiveRoot = ({ autoApprove, target }) => {
9482
9635
  };
9483
9636
  async function renderInteractiveApp(props) {
9484
9637
  const { waitUntilExit } = render(
9485
- /* @__PURE__ */ jsx25(AnimationProvider, { children: /* @__PURE__ */ jsx25(InteractiveRoot, { ...props }) })
9638
+ /* @__PURE__ */ jsx26(AnimationProvider, { children: /* @__PURE__ */ jsx26(InteractiveRoot, { ...props }) })
9486
9639
  );
9487
9640
  await waitUntilExit();
9488
9641
  }
@@ -3,7 +3,7 @@ import {
3
3
  clearWorkspace,
4
4
  loadState,
5
5
  saveState
6
- } from "./chunk-5JXATHQ3.js";
6
+ } from "./chunk-4UNNRHYY.js";
7
7
  import "./chunk-S5ZMXFHR.js";
8
8
  export {
9
9
  StateSerializer,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pentesting",
3
- "version": "0.73.12",
3
+ "version": "0.73.13",
4
4
  "description": "Autonomous Penetration Testing AI Agent",
5
5
  "type": "module",
6
6
  "main": "dist/main.js",