pentesting 0.70.7 → 0.70.9

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/dist/main.js +443 -376
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -82,9 +82,9 @@ var THEME = {
82
82
  spinner: COLORS.primary
83
83
  };
84
84
  var ASCII_BANNER = `
85
- \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510
86
- \u2502 P E N T E S T I N G A G E N T \u2502
87
- \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518
85
+ \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510
86
+ \u2502 P E N T E S T I N G A G E N T \u2502
87
+ \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518
88
88
  `;
89
89
  var ICONS = {
90
90
  // Status
@@ -421,7 +421,7 @@ function isZaiProvider() {
421
421
  return baseUrl.includes("z.ai");
422
422
  }
423
423
  function isThinkingEnabled() {
424
- return process.env[ENV_KEYS.THINKING] === "true";
424
+ return process.env[ENV_KEYS.THINKING] !== "false";
425
425
  }
426
426
  function getThinkingBudget() {
427
427
  const val = parseInt(process.env[ENV_KEYS.THINKING_BUDGET] || "", 10);
@@ -759,7 +759,7 @@ var INPUT_PROMPT_PATTERNS = [
759
759
 
760
760
  // src/shared/constants/agent.ts
761
761
  var APP_NAME = "Pentest AI";
762
- var APP_VERSION = "0.70.7";
762
+ var APP_VERSION = "0.70.9";
763
763
  var APP_DESCRIPTION = "Autonomous Penetration Testing AI Agent";
764
764
  var LLM_ROLES = {
765
765
  SYSTEM: "system",
@@ -815,7 +815,7 @@ import chalk from "chalk";
815
815
 
816
816
  // src/platform/tui/app.tsx
817
817
  import { useState as useState6, useCallback as useCallback9, useRef as useRef8 } from "react";
818
- import { Box as Box19, useApp, useStdout as useStdout4 } from "ink";
818
+ import { Box as Box20, useApp, useStdout as useStdout4 } from "ink";
819
819
 
820
820
  // src/platform/tui/hooks/useAgent.ts
821
821
  import { useState as useState2, useEffect as useEffect2, useCallback as useCallback2, useRef as useRef3 } from "react";
@@ -12567,16 +12567,16 @@ function extractHypothesizedReason(failureLine) {
12567
12567
  }
12568
12568
 
12569
12569
  // src/shared/utils/context-digest/formatters.ts
12570
- function formatContextForLLM(memo14) {
12570
+ function formatContextForLLM(memo15) {
12571
12571
  const compact = {};
12572
- if (memo14.keyFindings.length > 0) compact.findings = memo14.keyFindings;
12573
- if (memo14.credentials.length > 0) compact.credentials = memo14.credentials;
12574
- if (memo14.attackVectors.length > 0) compact.attackVectors = memo14.attackVectors;
12575
- if (memo14.failures.length > 0) compact.failures = memo14.failures;
12576
- if (memo14.suspicions.length > 0) compact.suspicions = memo14.suspicions;
12577
- if (memo14.nextSteps.length > 0) compact.nextSteps = memo14.nextSteps;
12578
- compact.attackValue = memo14.attackValue;
12579
- if (memo14.reflection) compact.reflection = memo14.reflection;
12572
+ if (memo15.keyFindings.length > 0) compact.findings = memo15.keyFindings;
12573
+ if (memo15.credentials.length > 0) compact.credentials = memo15.credentials;
12574
+ if (memo15.attackVectors.length > 0) compact.attackVectors = memo15.attackVectors;
12575
+ if (memo15.failures.length > 0) compact.failures = memo15.failures;
12576
+ if (memo15.suspicions.length > 0) compact.suspicions = memo15.suspicions;
12577
+ if (memo15.nextSteps.length > 0) compact.nextSteps = memo15.nextSteps;
12578
+ compact.attackValue = memo15.attackValue;
12579
+ if (memo15.reflection) compact.reflection = memo15.reflection;
12580
12580
  return JSON.stringify(compact);
12581
12581
  }
12582
12582
  function formatAnalystDigest(digest, filePath, originalChars) {
@@ -12634,15 +12634,15 @@ async function digestToolOutput(output, toolName, toolInput, analystFn) {
12634
12634
  try {
12635
12635
  const context = `Tool: ${toolName}${toolInput ? ` | Input: ${toolInput}` : ""}`;
12636
12636
  const rawAnalystResponse = await analystFn(preprocessed, context);
12637
- const memo14 = parseAnalystMemo(rawAnalystResponse);
12637
+ const memo15 = parseAnalystMemo(rawAnalystResponse);
12638
12638
  const formatted = formatAnalystDigest(rawAnalystResponse, savedOutputPath, originalLength);
12639
- const contextForLLM = formatContextForLLM(memo14);
12639
+ const contextForLLM = formatContextForLLM(memo15);
12640
12640
  return {
12641
12641
  digestedOutput: formatted,
12642
12642
  contextForLLM,
12643
12643
  fullOutputPath: savedOutputPath,
12644
12644
  analystUsed: true,
12645
- memo: memo14,
12645
+ memo: memo15,
12646
12646
  originalLength,
12647
12647
  digestedLength: formatted.length,
12648
12648
  compressionRatio: formatted.length / originalLength
@@ -13597,7 +13597,7 @@ function buildSummaryFromEntries(entries) {
13597
13597
 
13598
13598
  // src/shared/utils/journal/formatters/record.ts
13599
13599
  function formatTurnRecord(input) {
13600
- const { turn, timestamp, phase, tools, memo: memo14, reflection } = input;
13600
+ const { turn, timestamp, phase, tools, memo: memo15, reflection } = input;
13601
13601
  const time = timestamp.slice(0, 19).replace("T", " ");
13602
13602
  const sections = [];
13603
13603
  sections.push(`# Turn ${turn} | ${time} | Phase: ${phase}`);
@@ -13614,25 +13614,25 @@ function formatTurnRecord(input) {
13614
13614
  }
13615
13615
  sections.push("");
13616
13616
  sections.push(`## ${TURN_SECTIONS.KEY_INSIGHTS}`);
13617
- if (memo14.keyFindings.length > 0) {
13618
- for (const f of memo14.keyFindings) sections.push(`- ${INSIGHT_TAGS.DISCOVERED}: ${f}`);
13617
+ if (memo15.keyFindings.length > 0) {
13618
+ for (const f of memo15.keyFindings) sections.push(`- ${INSIGHT_TAGS.DISCOVERED}: ${f}`);
13619
13619
  }
13620
- if (memo14.credentials.length > 0) {
13621
- for (const c of memo14.credentials) sections.push(`- ${INSIGHT_TAGS.CREDENTIAL}: ${c}`);
13620
+ if (memo15.credentials.length > 0) {
13621
+ for (const c of memo15.credentials) sections.push(`- ${INSIGHT_TAGS.CREDENTIAL}: ${c}`);
13622
13622
  }
13623
- if (memo14.attackVectors.length > 0) {
13624
- for (const v of memo14.attackVectors) sections.push(`- ${INSIGHT_TAGS.CONFIRMED}: ${v}`);
13623
+ if (memo15.attackVectors.length > 0) {
13624
+ for (const v of memo15.attackVectors) sections.push(`- ${INSIGHT_TAGS.CONFIRMED}: ${v}`);
13625
13625
  }
13626
- if (memo14.failures.length > 0) {
13627
- for (const f of memo14.failures) sections.push(`- ${INSIGHT_TAGS.DEAD_END}: ${f}`);
13626
+ if (memo15.failures.length > 0) {
13627
+ for (const f of memo15.failures) sections.push(`- ${INSIGHT_TAGS.DEAD_END}: ${f}`);
13628
13628
  }
13629
- if (memo14.suspicions.length > 0) {
13630
- for (const s of memo14.suspicions) sections.push(`- ${INSIGHT_TAGS.SUSPICIOUS}: ${s}`);
13629
+ if (memo15.suspicions.length > 0) {
13630
+ for (const s of memo15.suspicions) sections.push(`- ${INSIGHT_TAGS.SUSPICIOUS}: ${s}`);
13631
13631
  }
13632
- if (memo14.nextSteps.length > 0) {
13633
- for (const n of memo14.nextSteps) sections.push(`- ${INSIGHT_TAGS.NEXT}: ${n}`);
13632
+ if (memo15.nextSteps.length > 0) {
13633
+ for (const n of memo15.nextSteps) sections.push(`- ${INSIGHT_TAGS.NEXT}: ${n}`);
13634
13634
  }
13635
- if (memo14.keyFindings.length === 0 && memo14.failures.length === 0 && memo14.credentials.length === 0) {
13635
+ if (memo15.keyFindings.length === 0 && memo15.failures.length === 0 && memo15.credentials.length === 0) {
13636
13636
  sections.push(`- ${TURN_EMPTY_MESSAGES.NO_INSIGHTS}`);
13637
13637
  }
13638
13638
  sections.push("");
@@ -13644,7 +13644,7 @@ function formatTurnRecord(input) {
13644
13644
 
13645
13645
  // src/shared/utils/journal/formatters/reflection.ts
13646
13646
  function formatReflectionInput(input) {
13647
- const { tools, memo: memo14, phase } = input;
13647
+ const { tools, memo: memo15, phase } = input;
13648
13648
  const parts = [
13649
13649
  `\uD604\uC7AC Phase: ${phase}`,
13650
13650
  "",
@@ -13662,12 +13662,12 @@ function formatReflectionInput(input) {
13662
13662
  }
13663
13663
  parts.push("");
13664
13664
  parts.push("Analyst \uCD94\uCD9C \uBA54\uBAA8:");
13665
- if (memo14) {
13666
- if (memo14.keyFindings.length > 0) parts.push(` \uBC1C\uACAC: ${memo14.keyFindings.join(", ")}`);
13667
- if (memo14.credentials.length > 0) parts.push(` \uD06C\uB808\uB374\uC15C: ${memo14.credentials.join(", ")}`);
13668
- if (memo14.failures.length > 0) parts.push(` \uC2E4\uD328: ${memo14.failures.join(", ")}`);
13669
- if (memo14.suspicions.length > 0) parts.push(` \uC758\uC2EC: ${memo14.suspicions.join(", ")}`);
13670
- parts.push(` \uACF5\uACA9 \uAC00\uCE58: ${memo14.attackValue}`);
13665
+ if (memo15) {
13666
+ if (memo15.keyFindings.length > 0) parts.push(` \uBC1C\uACAC: ${memo15.keyFindings.join(", ")}`);
13667
+ if (memo15.credentials.length > 0) parts.push(` \uD06C\uB808\uB374\uC15C: ${memo15.credentials.join(", ")}`);
13668
+ if (memo15.failures.length > 0) parts.push(` \uC2E4\uD328: ${memo15.failures.join(", ")}`);
13669
+ if (memo15.suspicions.length > 0) parts.push(` \uC758\uC2EC: ${memo15.suspicions.join(", ")}`);
13670
+ parts.push(` \uACF5\uACA9 \uAC00\uCE58: ${memo15.attackValue}`);
13671
13671
  } else {
13672
13672
  parts.push(" (\uBD84\uC11D \uACB0\uACFC \uC5C6\uC74C)");
13673
13673
  }
@@ -14561,13 +14561,13 @@ ${extraction.extractedContext}
14561
14561
  }
14562
14562
  return false;
14563
14563
  }
14564
- async function processReflection(toolJournal, memo14, phase, reflector) {
14564
+ async function processReflection(toolJournal, memo15, phase, reflector) {
14565
14565
  if (toolJournal.length === 0) {
14566
14566
  return null;
14567
14567
  }
14568
14568
  const reflection = await reflector.execute({
14569
14569
  tools: toolJournal,
14570
- memo: memo14,
14570
+ memo: memo15,
14571
14571
  phase
14572
14572
  });
14573
14573
  if (reflection.success && reflection.reflection) {
@@ -14580,7 +14580,7 @@ async function processReflection(toolJournal, memo14, phase, reflector) {
14580
14580
  import { writeFileSync as writeFileSync10, existsSync as existsSync15, readFileSync as readFileSync11 } from "fs";
14581
14581
  import { join as join16 } from "path";
14582
14582
  async function recordTurn(context) {
14583
- const { turnCounter, phase, toolJournal, memo: memo14, reflections, summaryRegenerator } = context;
14583
+ const { turnCounter, phase, toolJournal, memo: memo15, reflections, summaryRegenerator } = context;
14584
14584
  if (toolJournal.length === 0) {
14585
14585
  return turnCounter;
14586
14586
  }
@@ -14590,10 +14590,10 @@ async function recordTurn(context) {
14590
14590
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
14591
14591
  phase,
14592
14592
  tools: toolJournal,
14593
- memo: memo14,
14594
- reflection: reflections.length > 0 ? reflections.join(" | ") : memo14.nextSteps.join("; ")
14593
+ memo: memo15,
14594
+ reflection: reflections.length > 0 ? reflections.join(" | ") : memo15.nextSteps.join("; ")
14595
14595
  };
14596
- const entryCtx = { entry, journalTools: toolJournal, memo: memo14, phase, reflections };
14596
+ const entryCtx = { entry, journalTools: toolJournal, memo: memo15, phase, reflections };
14597
14597
  await createTurnArchive(turnCounter, entryCtx);
14598
14598
  await regenerateSummary(turnCounter, summaryRegenerator, entryCtx);
14599
14599
  rotateTurnRecords();
@@ -14602,7 +14602,7 @@ async function recordTurn(context) {
14602
14602
  return turnCounter + 1;
14603
14603
  }
14604
14604
  async function createTurnArchive(turnCounter, ctx) {
14605
- const { entry, journalTools, memo: memo14, phase } = ctx;
14605
+ const { entry, journalTools, memo: memo15, phase } = ctx;
14606
14606
  try {
14607
14607
  const turnDir = WORKSPACE.turnPath(turnCounter);
14608
14608
  const toolsDir = WORKSPACE.turnToolsPath(turnCounter);
@@ -14613,35 +14613,35 @@ async function createTurnArchive(turnCounter, ctx) {
14613
14613
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
14614
14614
  phase,
14615
14615
  tools: journalTools,
14616
- memo: memo14,
14616
+ memo: memo15,
14617
14617
  reflection: entry.reflection
14618
14618
  });
14619
14619
  writeFileSync10(join16(turnDir, TURN_FILES.RECORD), turnContent, "utf-8");
14620
14620
  writeFileSync10(join16(turnDir, TURN_FILES.STRUCTURED), JSON.stringify(entry, null, 2), "utf-8");
14621
- writeAnalystFile(turnDir, memo14);
14621
+ writeAnalystFile(turnDir, memo15);
14622
14622
  } catch {
14623
14623
  }
14624
14624
  }
14625
- function writeAnalystFile(turnDir, memo14) {
14625
+ function writeAnalystFile(turnDir, memo15) {
14626
14626
  const memoLines = [];
14627
- if (memo14.keyFindings.length > 0) memoLines.push("## Key Findings", ...memo14.keyFindings.map((f) => `- ${f}`), "");
14628
- if (memo14.credentials.length > 0) memoLines.push("## Credentials", ...memo14.credentials.map((c) => `- ${c}`), "");
14629
- if (memo14.attackVectors.length > 0) memoLines.push("## Attack Vectors", ...memo14.attackVectors.map((v) => `- ${v}`), "");
14630
- if (memo14.failures.length > 0) memoLines.push("## Failures", ...memo14.failures.map((f) => `- ${f}`), "");
14631
- if (memo14.suspicions.length > 0) memoLines.push("## Suspicious", ...memo14.suspicions.map((s) => `- ${s}`), "");
14632
- if (memo14.nextSteps.length > 0) memoLines.push("## Next Steps", ...memo14.nextSteps.map((n) => `- ${n}`), "");
14627
+ if (memo15.keyFindings.length > 0) memoLines.push("## Key Findings", ...memo15.keyFindings.map((f) => `- ${f}`), "");
14628
+ if (memo15.credentials.length > 0) memoLines.push("## Credentials", ...memo15.credentials.map((c) => `- ${c}`), "");
14629
+ if (memo15.attackVectors.length > 0) memoLines.push("## Attack Vectors", ...memo15.attackVectors.map((v) => `- ${v}`), "");
14630
+ if (memo15.failures.length > 0) memoLines.push("## Failures", ...memo15.failures.map((f) => `- ${f}`), "");
14631
+ if (memo15.suspicions.length > 0) memoLines.push("## Suspicious", ...memo15.suspicions.map((s) => `- ${s}`), "");
14632
+ if (memo15.nextSteps.length > 0) memoLines.push("## Next Steps", ...memo15.nextSteps.map((n) => `- ${n}`), "");
14633
14633
  if (memoLines.length > 0) {
14634
14634
  writeFileSync10(join16(turnDir, TURN_FILES.ANALYST), memoLines.join("\n"), "utf-8");
14635
14635
  flowLog(
14636
14636
  "\u2462Analyst",
14637
14637
  "\u2192",
14638
14638
  `archive/turn-${turnDir.split("/").pop()}/analyst.md`,
14639
- `findings:${memo14.keyFindings.length} creds:${memo14.credentials.length} vectors:${memo14.attackVectors.length} failures:${memo14.failures.length}`
14639
+ `findings:${memo15.keyFindings.length} creds:${memo15.credentials.length} vectors:${memo15.attackVectors.length} failures:${memo15.failures.length}`
14640
14640
  );
14641
14641
  }
14642
14642
  }
14643
14643
  async function regenerateSummary(turnCounter, summaryRegenerator, ctx) {
14644
- const { entry, journalTools, memo: memo14, phase } = ctx;
14644
+ const { entry, journalTools, memo: memo15, phase } = ctx;
14645
14645
  try {
14646
14646
  const turnDir = WORKSPACE.turnPath(turnCounter);
14647
14647
  const summaryPath = join16(turnDir, TURN_FILES.SUMMARY);
@@ -14658,7 +14658,7 @@ async function regenerateSummary(turnCounter, summaryRegenerator, ctx) {
14658
14658
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
14659
14659
  phase,
14660
14660
  tools: journalTools,
14661
- memo: memo14,
14661
+ memo: memo15,
14662
14662
  reflection: entry.reflection
14663
14663
  });
14664
14664
  const summaryResult = await summaryRegenerator.execute({
@@ -14995,7 +14995,13 @@ var TUI_DISPLAY_LIMITS = {
14995
14995
  * sessions accumulate thousands of messages and RAM grows without bound.
14996
14996
  * Oldest messages are pruned first; all content is preserved in the disk archive.
14997
14997
  */
14998
- MAX_MESSAGES: 500
14998
+ MAX_MESSAGES: 500,
14999
+ /** Fallback terminal row count when stdout.rows is unavailable */
15000
+ TERMINAL_DEFAULT_ROWS: 24,
15001
+ /** Reserved rows for modal chrome (header + borders + padding + footer) */
15002
+ MODAL_CHROME_HEIGHT: 6,
15003
+ /** Max chars shown for masked password in message history */
15004
+ PASSWORD_MASK_MAX: 20
14999
15005
  };
15000
15006
 
15001
15007
  // src/platform/tui/hooks/useAgentState.ts
@@ -15009,6 +15015,8 @@ var useAgentState = () => {
15009
15015
  const [inputRequest, setInputRequest] = useState({ status: "inactive" });
15010
15016
  const [stats, setStats] = useState({ phase: DEFAULTS.INIT_PHASE, targets: 0, findings: 0, todo: 0 });
15011
15017
  const [turnCount, setTurnCount] = useState(0);
15018
+ const [liveReasoning, setLiveReasoning] = useState("");
15019
+ const [isReasoning, setIsReasoning] = useState(false);
15012
15020
  const lastResponseMetaRef = useRef(null);
15013
15021
  const startTimeRef = useRef(0);
15014
15022
  const timerRef = useRef(null);
@@ -15076,19 +15084,24 @@ var useAgentState = () => {
15076
15084
  setStats,
15077
15085
  turnCount,
15078
15086
  setTurnCount,
15079
- // Refs
15087
+ liveReasoning,
15088
+ setLiveReasoning,
15089
+ isReasoning,
15090
+ setIsReasoning,
15091
+ // Refs (external consumers only)
15080
15092
  lastResponseMetaRef,
15081
- timerRef,
15082
15093
  retryCountdownRef,
15083
15094
  retryCountRef,
15084
15095
  tokenAccumRef,
15085
15096
  lastStepTokensRef,
15097
+ toolStartedAtRef,
15098
+ // WHY timerRef excluded: internal to manageTimer/clearAllTimers only,
15099
+ // no external consumer exists.
15086
15100
  // Helpers
15087
15101
  addMessage,
15088
15102
  resetCumulativeCounters,
15089
15103
  manageTimer,
15090
- clearAllTimers,
15091
- toolStartedAtRef
15104
+ clearAllTimers
15092
15105
  };
15093
15106
  };
15094
15107
 
@@ -15282,13 +15295,16 @@ function createLifecycleHandlers(agent, state, _reasoningBufferRef) {
15282
15295
 
15283
15296
  // src/platform/tui/hooks/useAgentEvents/handlers/reasoning.ts
15284
15297
  function createReasoningHandlers(state, reasoningBufferRef) {
15285
- const { addMessage, setCurrentStatus } = state;
15298
+ const { addMessage, setCurrentStatus, setLiveReasoning, setIsReasoning } = state;
15286
15299
  const onStart = () => {
15287
15300
  reasoningBufferRef.current = "";
15301
+ setLiveReasoning("");
15302
+ setIsReasoning(true);
15288
15303
  setCurrentStatus("Reasoning\u2026");
15289
15304
  };
15290
15305
  const onDelta = (e) => {
15291
15306
  reasoningBufferRef.current += e.data.content;
15307
+ setLiveReasoning(reasoningBufferRef.current);
15292
15308
  const chars = reasoningBufferRef.current.length;
15293
15309
  const estTokens = Math.round(chars / LLM_LIMITS.charsPerTokenEstimate);
15294
15310
  const firstLine = reasoningBufferRef.current.split("\n")[0]?.slice(0, TUI_DISPLAY_LIMITS.reasoningPreviewChars) || "";
@@ -15298,6 +15314,8 @@ ${firstLine}`);
15298
15314
  const onEnd = () => {
15299
15315
  const text = reasoningBufferRef.current.trim();
15300
15316
  reasoningBufferRef.current = "";
15317
+ setIsReasoning(false);
15318
+ setLiveReasoning("");
15301
15319
  setCurrentStatus("");
15302
15320
  if (text) {
15303
15321
  addMessage("thinking", text);
@@ -15392,7 +15410,9 @@ var useAgentEvents = (agent, eventsRef, state) => {
15392
15410
  tokenAccumRef,
15393
15411
  lastStepTokensRef,
15394
15412
  lastResponseMetaRef,
15395
- setCurrentTokens
15413
+ setCurrentTokens,
15414
+ setLiveReasoning,
15415
+ setIsReasoning
15396
15416
  } = state;
15397
15417
  const reasoningBufferRef = useRef2("");
15398
15418
  useEffect(() => {
@@ -15410,7 +15430,10 @@ var useAgentEvents = (agent, eventsRef, state) => {
15410
15430
  tokenAccumRef,
15411
15431
  lastStepTokensRef
15412
15432
  }, reasoningBufferRef);
15413
- const reasoningHandlers = createReasoningHandlers({ addMessage, setCurrentStatus }, reasoningBufferRef);
15433
+ const reasoningHandlers = createReasoningHandlers(
15434
+ { addMessage, setCurrentStatus, setLiveReasoning, setIsReasoning },
15435
+ reasoningBufferRef
15436
+ );
15414
15437
  const cleanupInput = setupInputHandlers(setInputRequest, addMessage);
15415
15438
  const cleanupCommand = setupCommandHandlers(addMessage, setCurrentStatus);
15416
15439
  const updateStats = () => {
@@ -15460,7 +15483,9 @@ var useAgentEvents = (agent, eventsRef, state) => {
15460
15483
  lastStepTokensRef,
15461
15484
  clearAllTimers,
15462
15485
  toolStartedAtRef,
15463
- eventsRef
15486
+ eventsRef,
15487
+ setLiveReasoning,
15488
+ setIsReasoning
15464
15489
  ]);
15465
15490
  };
15466
15491
 
@@ -15488,7 +15513,9 @@ var useAgent = (shouldAutoApprove, target) => {
15488
15513
  manageTimer,
15489
15514
  resetCumulativeCounters,
15490
15515
  turnCount,
15491
- setTurnCount
15516
+ setTurnCount,
15517
+ liveReasoning,
15518
+ isReasoning
15492
15519
  } = state;
15493
15520
  useEffect2(() => {
15494
15521
  if (target) {
@@ -15569,7 +15596,9 @@ var useAgent = (shouldAutoApprove, target) => {
15569
15596
  abort,
15570
15597
  cancelInputRequest,
15571
15598
  addMessage,
15572
- refreshStats
15599
+ refreshStats,
15600
+ liveReasoning,
15601
+ isReasoning
15573
15602
  };
15574
15603
  };
15575
15604
 
@@ -16246,41 +16275,58 @@ var AnimationProvider = ({ children }) => {
16246
16275
  var useAnimationTick = () => useContext(AnimationContext);
16247
16276
 
16248
16277
  // src/platform/tui/components/MessageList.tsx
16249
- import { memo as memo7 } from "react";
16250
- import { Box as Box8, Static } from "ink";
16278
+ import { memo as memo8 } from "react";
16279
+ import { Box as Box9, Static } from "ink";
16251
16280
 
16252
16281
  // src/platform/tui/components/messages/ThinkingBlock.tsx
16253
16282
  import { memo } from "react";
16254
16283
  import { Box, Text } from "ink";
16255
16284
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
16256
- var THINKING_PREVIEW_LINES = 3;
16257
16285
  var ThinkingBlock = memo(({ msg }) => {
16258
16286
  const lines = msg.content.split("\n");
16259
- const charCount = msg.content.length;
16260
- const estTokens = Math.round(charCount / LLM_LIMITS.charsPerTokenEstimate);
16261
- const hiddenCount = lines.length - THINKING_PREVIEW_LINES;
16262
- const visibleLines = lines.slice(0, THINKING_PREVIEW_LINES);
16287
+ const estTokens = Math.round(msg.content.length / LLM_LIMITS.charsPerTokenEstimate);
16263
16288
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 0, children: [
16264
16289
  /* @__PURE__ */ jsxs(Box, { children: [
16265
- /* @__PURE__ */ jsx2(Text, { color: THEME.dimGray, children: " \u25C6 " }),
16266
- /* @__PURE__ */ jsx2(Text, { color: THEME.gray, children: "Reasoning" }),
16267
- /* @__PURE__ */ jsx2(Text, { color: THEME.dimGray, children: ` (~${estTokens} tokens)` }),
16268
- hiddenCount > 0 && /* @__PURE__ */ jsx2(Text, { color: THEME.dimGray, children: ` [+${hiddenCount} lines]` })
16290
+ /* @__PURE__ */ jsx2(Text, { color: THEME.dimGray, children: "\u25C6 " }),
16291
+ /* @__PURE__ */ jsx2(Text, { color: THEME.gray, bold: true, children: "Reasoning" }),
16292
+ /* @__PURE__ */ jsx2(Text, { color: THEME.dimGray, children: ` ~${estTokens} tok ${lines.length} lines` })
16293
+ ] }),
16294
+ lines.map((line, i) => /* @__PURE__ */ jsxs(Box, { children: [
16295
+ /* @__PURE__ */ jsx2(Text, { color: THEME.dimGray, children: "\u2502 " }),
16296
+ /* @__PURE__ */ jsx2(Text, { color: THEME.dimGray, wrap: "truncate", children: line || " " })
16297
+ ] }, i)),
16298
+ /* @__PURE__ */ jsx2(Box, { children: /* @__PURE__ */ jsx2(Text, { color: THEME.dimGray, children: "\u2575" }) })
16299
+ ] });
16300
+ });
16301
+
16302
+ // src/platform/tui/components/messages/LiveReasoningPanel.tsx
16303
+ import { memo as memo2 } from "react";
16304
+ import { Box as Box2, Text as Text2 } from "ink";
16305
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
16306
+ var LiveReasoningPanel = memo2(({ content, isReasoning }) => {
16307
+ if (!isReasoning) return null;
16308
+ const lines = content.split("\n");
16309
+ const estTokens = Math.round(content.length / LLM_LIMITS.charsPerTokenEstimate);
16310
+ return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", marginY: 0, children: [
16311
+ /* @__PURE__ */ jsxs2(Box2, { children: [
16312
+ /* @__PURE__ */ jsx3(Text2, { color: THEME.yellow, children: "\u27F3 " }),
16313
+ /* @__PURE__ */ jsx3(Text2, { color: THEME.yellow, bold: true, children: "Reasoning" }),
16314
+ /* @__PURE__ */ jsx3(Text2, { color: THEME.dimGray, children: ` ~${estTokens} tok ${lines.length} lines streaming\u2026` })
16269
16315
  ] }),
16270
- visibleLines.map((line, i) => /* @__PURE__ */ jsxs(Box, { children: [
16271
- /* @__PURE__ */ jsx2(Text, { dimColor: true, children: " \u2502 " }),
16272
- /* @__PURE__ */ jsx2(Text, { dimColor: true, children: line })
16316
+ lines.map((line, i) => /* @__PURE__ */ jsxs2(Box2, { children: [
16317
+ /* @__PURE__ */ jsx3(Text2, { color: THEME.dimGray, children: "\u2502 " }),
16318
+ /* @__PURE__ */ jsx3(Text2, { color: THEME.gray, wrap: "truncate", children: line || " " })
16273
16319
  ] }, i)),
16274
- hiddenCount > 0 && /* @__PURE__ */ jsxs(Box, { children: [
16275
- /* @__PURE__ */ jsx2(Text, { dimColor: true, children: " \u2502 " }),
16276
- /* @__PURE__ */ jsx2(Text, { dimColor: true, children: "..." })
16320
+ /* @__PURE__ */ jsxs2(Box2, { children: [
16321
+ /* @__PURE__ */ jsx3(Text2, { color: THEME.dimGray, children: "\u2502 " }),
16322
+ /* @__PURE__ */ jsx3(Text2, { color: THEME.yellow, children: "\u258C" })
16277
16323
  ] })
16278
16324
  ] });
16279
16325
  });
16280
16326
 
16281
16327
  // src/platform/tui/components/messages/MessageRow.tsx
16282
- import { memo as memo4 } from "react";
16283
- import { Box as Box5, Text as Text5 } from "ink";
16328
+ import { memo as memo5 } from "react";
16329
+ import { Box as Box6, Text as Text6 } from "ink";
16284
16330
 
16285
16331
  // src/platform/tui/constants/styles.ts
16286
16332
  var MESSAGE_STYLES = {
@@ -16317,10 +16363,16 @@ var MESSAGE_STYLES = {
16317
16363
  // Thinking/reasoning icon
16318
16364
  }
16319
16365
  };
16366
+ var UI_MESSAGES = {
16367
+ /** Shown when user sends a message while agent is processing */
16368
+ QUEUED: "\u{1F4AC} Message queued \u2014 will be processed at next iteration",
16369
+ /** Prefix for masked secret input in message history */
16370
+ SECRET_PREFIX: "\u21B3 "
16371
+ };
16320
16372
 
16321
16373
  // src/platform/tui/components/inline-status.tsx
16322
- import { Box as Box2, Text as Text2 } from "ink";
16323
- import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
16374
+ import { Box as Box3, Text as Text3 } from "ink";
16375
+ import { Fragment, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
16324
16376
  function formatDuration3(ms) {
16325
16377
  const seconds = Math.floor(ms / 1e3);
16326
16378
  if (seconds < 60) return `${seconds}s`;
@@ -16346,18 +16398,18 @@ function getRoleColor(role) {
16346
16398
  }
16347
16399
  function StatusIndicator({ isRunning, exitCode }) {
16348
16400
  if (isRunning) {
16349
- return /* @__PURE__ */ jsxs2(Text2, { color: THEME.primary, children: [
16401
+ return /* @__PURE__ */ jsxs3(Text3, { color: THEME.primary, children: [
16350
16402
  ICONS.running,
16351
16403
  " "
16352
16404
  ] });
16353
16405
  }
16354
16406
  if (exitCode === 0) {
16355
- return /* @__PURE__ */ jsxs2(Text2, { color: THEME.gray, children: [
16407
+ return /* @__PURE__ */ jsxs3(Text3, { color: THEME.gray, children: [
16356
16408
  ICONS.success,
16357
16409
  " "
16358
16410
  ] });
16359
16411
  }
16360
- return /* @__PURE__ */ jsxs2(Text2, { color: THEME.red, children: [
16412
+ return /* @__PURE__ */ jsxs3(Text3, { color: THEME.red, children: [
16361
16413
  ICONS.error,
16362
16414
  " "
16363
16415
  ] });
@@ -16367,26 +16419,26 @@ function ProcessRow({ proc, isCompact }) {
16367
16419
  const port = proc.listeningPort ? `:${proc.listeningPort}` : "";
16368
16420
  const purpose = proc.purpose || proc.description || "";
16369
16421
  const truncatedPurpose = isCompact && purpose.length > TUI_DISPLAY_LIMITS.purposeMaxLength ? purpose.slice(0, TUI_DISPLAY_LIMITS.purposeTruncated) + "..." : purpose;
16370
- return /* @__PURE__ */ jsxs2(Box2, { children: [
16371
- /* @__PURE__ */ jsx3(StatusIndicator, { isRunning: proc.isRunning, exitCode: proc.exitCode }),
16372
- /* @__PURE__ */ jsxs2(Text2, { color: THEME.gray, children: [
16422
+ return /* @__PURE__ */ jsxs3(Box3, { children: [
16423
+ /* @__PURE__ */ jsx4(StatusIndicator, { isRunning: proc.isRunning, exitCode: proc.exitCode }),
16424
+ /* @__PURE__ */ jsxs3(Text3, { color: THEME.gray, children: [
16373
16425
  "[",
16374
16426
  proc.id,
16375
16427
  "]"
16376
16428
  ] }),
16377
- /* @__PURE__ */ jsx3(Text2, { children: " " }),
16378
- /* @__PURE__ */ jsxs2(Text2, { color: getRoleColor(proc.role), bold: true, children: [
16429
+ /* @__PURE__ */ jsx4(Text3, { children: " " }),
16430
+ /* @__PURE__ */ jsxs3(Text3, { color: getRoleColor(proc.role), bold: true, children: [
16379
16431
  proc.role,
16380
16432
  port
16381
16433
  ] }),
16382
- /* @__PURE__ */ jsxs2(Text2, { color: THEME.gray, children: [
16434
+ /* @__PURE__ */ jsxs3(Text3, { color: THEME.gray, children: [
16383
16435
  " (",
16384
16436
  duration,
16385
16437
  ")"
16386
16438
  ] }),
16387
- truncatedPurpose && /* @__PURE__ */ jsxs2(Fragment, { children: [
16388
- /* @__PURE__ */ jsx3(Text2, { color: THEME.gray, children: " - " }),
16389
- /* @__PURE__ */ jsx3(Text2, { color: THEME.gray, children: truncatedPurpose })
16439
+ truncatedPurpose && /* @__PURE__ */ jsxs3(Fragment, { children: [
16440
+ /* @__PURE__ */ jsx4(Text3, { color: THEME.gray, children: " - " }),
16441
+ /* @__PURE__ */ jsx4(Text3, { color: THEME.gray, children: truncatedPurpose })
16390
16442
  ] })
16391
16443
  ] });
16392
16444
  }
@@ -16397,7 +16449,7 @@ var InlineStatus = ({
16397
16449
  isCompact = true
16398
16450
  }) => {
16399
16451
  if (processes.length === 0 && zombies.length === 0) {
16400
- return /* @__PURE__ */ jsx3(Box2, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsx3(Text2, { color: THEME.gray, children: "\u2022 No active background processes" }) });
16452
+ return /* @__PURE__ */ jsx4(Box3, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsx4(Text3, { color: THEME.gray, children: "\u2022 No active background processes" }) });
16401
16453
  }
16402
16454
  const running = processes.filter((p) => p.isRunning);
16403
16455
  const stopped = processes.filter((p) => !p.isRunning);
@@ -16406,66 +16458,66 @@ var InlineStatus = ({
16406
16458
  warning: THEME.yellow,
16407
16459
  critical: THEME.red
16408
16460
  }[health];
16409
- return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", marginBottom: 1, children: [
16410
- running.length > 0 && /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
16411
- /* @__PURE__ */ jsxs2(Text2, { color: THEME.gray, bold: true, children: [
16461
+ return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", marginBottom: 1, children: [
16462
+ running.length > 0 && /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
16463
+ /* @__PURE__ */ jsxs3(Text3, { color: THEME.gray, bold: true, children: [
16412
16464
  ICONS.running,
16413
16465
  " Active (",
16414
16466
  running.length,
16415
16467
  ")"
16416
16468
  ] }),
16417
- running.map((proc) => /* @__PURE__ */ jsx3(ProcessRow, { proc, isCompact }, proc.id))
16469
+ running.map((proc) => /* @__PURE__ */ jsx4(ProcessRow, { proc, isCompact }, proc.id))
16418
16470
  ] }),
16419
- stopped.length > 0 && !isCompact && /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", marginTop: running.length > 0 ? 1 : 0, children: [
16420
- /* @__PURE__ */ jsxs2(Text2, { color: THEME.gray, children: [
16471
+ stopped.length > 0 && !isCompact && /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", marginTop: running.length > 0 ? 1 : 0, children: [
16472
+ /* @__PURE__ */ jsxs3(Text3, { color: THEME.gray, children: [
16421
16473
  ICONS.completed,
16422
16474
  " Completed (",
16423
16475
  stopped.length,
16424
16476
  ")"
16425
16477
  ] }),
16426
- stopped.slice(0, TUI_DISPLAY_LIMITS.maxStoppedProcesses).map((proc) => /* @__PURE__ */ jsx3(ProcessRow, { proc, isCompact }, proc.id)),
16427
- stopped.length > TUI_DISPLAY_LIMITS.maxStoppedProcesses && /* @__PURE__ */ jsxs2(Text2, { color: THEME.gray, children: [
16478
+ stopped.slice(0, TUI_DISPLAY_LIMITS.maxStoppedProcesses).map((proc) => /* @__PURE__ */ jsx4(ProcessRow, { proc, isCompact }, proc.id)),
16479
+ stopped.length > TUI_DISPLAY_LIMITS.maxStoppedProcesses && /* @__PURE__ */ jsxs3(Text3, { color: THEME.gray, children: [
16428
16480
  " ... and ",
16429
16481
  stopped.length - TUI_DISPLAY_LIMITS.maxStoppedProcesses,
16430
16482
  " more"
16431
16483
  ] })
16432
16484
  ] }),
16433
- zombies.length > 0 && /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", marginTop: 1, children: [
16434
- /* @__PURE__ */ jsxs2(Text2, { color: THEME.yellow, children: [
16485
+ zombies.length > 0 && /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", marginTop: 1, children: [
16486
+ /* @__PURE__ */ jsxs3(Text3, { color: THEME.yellow, children: [
16435
16487
  ICONS.warning,
16436
16488
  " Zombie Processes (",
16437
16489
  zombies.length,
16438
16490
  ")"
16439
16491
  ] }),
16440
- zombies.map((z) => /* @__PURE__ */ jsxs2(Box2, { children: [
16441
- /* @__PURE__ */ jsxs2(Text2, { color: THEME.red, children: [
16492
+ zombies.map((z) => /* @__PURE__ */ jsxs3(Box3, { children: [
16493
+ /* @__PURE__ */ jsxs3(Text3, { color: THEME.red, children: [
16442
16494
  " ",
16443
16495
  ICONS.error,
16444
16496
  " "
16445
16497
  ] }),
16446
- /* @__PURE__ */ jsxs2(Text2, { color: THEME.gray, children: [
16498
+ /* @__PURE__ */ jsxs3(Text3, { color: THEME.gray, children: [
16447
16499
  "[",
16448
16500
  z.processId,
16449
16501
  "] "
16450
16502
  ] }),
16451
- /* @__PURE__ */ jsxs2(Text2, { color: THEME.yellow, children: [
16503
+ /* @__PURE__ */ jsxs3(Text3, { color: THEME.yellow, children: [
16452
16504
  z.orphanedChildren.length,
16453
16505
  " orphaned children"
16454
16506
  ] })
16455
16507
  ] }, z.processId)),
16456
- /* @__PURE__ */ jsx3(Text2, { color: THEME.gray, children: " Run /cleanup to terminate" })
16508
+ /* @__PURE__ */ jsx4(Text3, { color: THEME.gray, children: " Run /cleanup to terminate" })
16457
16509
  ] }),
16458
- /* @__PURE__ */ jsxs2(Box2, { marginTop: running.length > 0 ? 1 : 0, children: [
16459
- /* @__PURE__ */ jsx3(Text2, { color: THEME.gray, children: "Health: " }),
16460
- /* @__PURE__ */ jsx3(Text2, { color: healthColor, bold: true, children: health.toUpperCase() })
16510
+ /* @__PURE__ */ jsxs3(Box3, { marginTop: running.length > 0 ? 1 : 0, children: [
16511
+ /* @__PURE__ */ jsx4(Text3, { color: THEME.gray, children: "Health: " }),
16512
+ /* @__PURE__ */ jsx4(Text3, { color: healthColor, bold: true, children: health.toUpperCase() })
16461
16513
  ] })
16462
16514
  ] });
16463
16515
  };
16464
16516
 
16465
16517
  // src/platform/tui/components/ToolCard.tsx
16466
- import { memo as memo2 } from "react";
16467
- import { Box as Box3, Text as Text3 } from "ink";
16468
- import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
16518
+ import { memo as memo3 } from "react";
16519
+ import { Box as Box4, Text as Text4 } from "ink";
16520
+ import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
16469
16521
  var ARGS_MAX = 72;
16470
16522
  function truncate(s, max) {
16471
16523
  return s.length > max ? s.slice(0, max - 1) + "\u2026" : s;
@@ -16507,23 +16559,23 @@ function parseToolContent(content) {
16507
16559
  }
16508
16560
  return { name: content.trim(), args: "" };
16509
16561
  }
16510
- var ToolCard = memo2(({ content }) => {
16562
+ var ToolCard = memo3(({ content }) => {
16511
16563
  const { name, args } = parseToolContent(content);
16512
- return /* @__PURE__ */ jsxs3(Box3, { children: [
16513
- /* @__PURE__ */ jsx4(Text3, { color: THEME.primary, children: " \u2295 " }),
16514
- /* @__PURE__ */ jsx4(Text3, { color: THEME.white, bold: true, children: name }),
16515
- args && /* @__PURE__ */ jsxs3(Fragment2, { children: [
16516
- /* @__PURE__ */ jsx4(Text3, { color: THEME.dimGray, children: "(" }),
16517
- /* @__PURE__ */ jsx4(Text3, { color: THEME.gray, children: args }),
16518
- /* @__PURE__ */ jsx4(Text3, { color: THEME.dimGray, children: ")" })
16564
+ return /* @__PURE__ */ jsxs4(Box4, { children: [
16565
+ /* @__PURE__ */ jsx5(Text4, { color: THEME.primary, children: " \u2295 " }),
16566
+ /* @__PURE__ */ jsx5(Text4, { color: THEME.white, bold: true, children: name }),
16567
+ args && /* @__PURE__ */ jsxs4(Fragment2, { children: [
16568
+ /* @__PURE__ */ jsx5(Text4, { color: THEME.dimGray, children: "(" }),
16569
+ /* @__PURE__ */ jsx5(Text4, { color: THEME.gray, children: args }),
16570
+ /* @__PURE__ */ jsx5(Text4, { color: THEME.dimGray, children: ")" })
16519
16571
  ] })
16520
16572
  ] });
16521
16573
  });
16522
16574
 
16523
16575
  // src/platform/tui/components/MarkdownText.tsx
16524
- import { memo as memo3 } from "react";
16525
- import { Box as Box4, Text as Text4 } from "ink";
16526
- import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
16576
+ import { memo as memo4 } from "react";
16577
+ import { Box as Box5, Text as Text5 } from "ink";
16578
+ import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
16527
16579
  function tokenizeLine(line) {
16528
16580
  const tokens = [];
16529
16581
  let i = 0;
@@ -16547,14 +16599,14 @@ function tokenizeLine(line) {
16547
16599
  }
16548
16600
  return tokens;
16549
16601
  }
16550
- var InlineContent = ({ tokens }) => /* @__PURE__ */ jsx5(Fragment3, { children: tokens.map((tok, i) => {
16602
+ var InlineContent = ({ tokens }) => /* @__PURE__ */ jsx6(Fragment3, { children: tokens.map((tok, i) => {
16551
16603
  if (tok.type === "bold") {
16552
- return /* @__PURE__ */ jsx5(Text4, { bold: true, color: THEME.white, children: tok.value }, i);
16604
+ return /* @__PURE__ */ jsx6(Text5, { bold: true, color: THEME.white, children: tok.value }, i);
16553
16605
  }
16554
16606
  if (tok.type === "code") {
16555
- return /* @__PURE__ */ jsx5(Text4, { color: THEME.cyan, children: `\`${tok.value}\`` }, i);
16607
+ return /* @__PURE__ */ jsx6(Text5, { color: THEME.cyan, children: `\`${tok.value}\`` }, i);
16556
16608
  }
16557
- return /* @__PURE__ */ jsx5(Text4, { color: THEME.white, children: tok.value }, i);
16609
+ return /* @__PURE__ */ jsx6(Text5, { color: THEME.white, children: tok.value }, i);
16558
16610
  }) });
16559
16611
  function parseBlocks(lines) {
16560
16612
  const blocks = [];
@@ -16604,29 +16656,29 @@ function parseBlocks(lines) {
16604
16656
  }
16605
16657
  var BlockRenderer = ({ block, blockIdx }) => {
16606
16658
  if (block.type === "blank") {
16607
- return /* @__PURE__ */ jsx5(Text4, { children: " " }, blockIdx);
16659
+ return /* @__PURE__ */ jsx6(Text5, { children: " " }, blockIdx);
16608
16660
  }
16609
16661
  if (block.type === "heading") {
16610
16662
  const prefixes = { 1: "\u25B8 ", 2: " \u25B9 ", 3: " \xB7 " };
16611
16663
  const colors = { 1: THEME.primary, 2: THEME.cyan, 3: THEME.white };
16612
- return /* @__PURE__ */ jsx5(Box4, { children: /* @__PURE__ */ jsxs4(Text4, { color: colors[block.level], bold: true, children: [
16664
+ return /* @__PURE__ */ jsx6(Box5, { children: /* @__PURE__ */ jsxs5(Text5, { color: colors[block.level], bold: true, children: [
16613
16665
  prefixes[block.level],
16614
16666
  block.content
16615
16667
  ] }) }, blockIdx);
16616
16668
  }
16617
16669
  if (block.type === "listItem") {
16618
16670
  const bullet = block.ordered ? `${block.index}.` : "\u2022";
16619
- return /* @__PURE__ */ jsxs4(Box4, { paddingLeft: 1, children: [
16620
- /* @__PURE__ */ jsxs4(Text4, { color: THEME.dimGray, children: [
16671
+ return /* @__PURE__ */ jsxs5(Box5, { paddingLeft: 1, children: [
16672
+ /* @__PURE__ */ jsxs5(Text5, { color: THEME.dimGray, children: [
16621
16673
  bullet,
16622
16674
  " "
16623
16675
  ] }),
16624
- /* @__PURE__ */ jsx5(InlineContent, { tokens: tokenizeLine(block.content) })
16676
+ /* @__PURE__ */ jsx6(InlineContent, { tokens: tokenizeLine(block.content) })
16625
16677
  ] }, blockIdx);
16626
16678
  }
16627
16679
  if (block.type === "codeBlock") {
16628
- return /* @__PURE__ */ jsxs4(
16629
- Box4,
16680
+ return /* @__PURE__ */ jsxs5(
16681
+ Box5,
16630
16682
  {
16631
16683
  flexDirection: "column",
16632
16684
  borderStyle: "single",
@@ -16634,19 +16686,19 @@ var BlockRenderer = ({ block, blockIdx }) => {
16634
16686
  paddingX: 1,
16635
16687
  marginY: 0,
16636
16688
  children: [
16637
- block.lang && /* @__PURE__ */ jsx5(Text4, { color: THEME.dimGray, children: block.lang }),
16638
- block.lines.map((l, li) => /* @__PURE__ */ jsx5(Text4, { color: THEME.cyan, children: l }, li))
16689
+ block.lang && /* @__PURE__ */ jsx6(Text5, { color: THEME.dimGray, children: block.lang }),
16690
+ block.lines.map((l, li) => /* @__PURE__ */ jsx6(Text5, { color: THEME.cyan, children: l }, li))
16639
16691
  ]
16640
16692
  },
16641
16693
  blockIdx
16642
16694
  );
16643
16695
  }
16644
- return /* @__PURE__ */ jsx5(Box4, { children: /* @__PURE__ */ jsx5(InlineContent, { tokens: tokenizeLine(block.content) }) }, blockIdx);
16696
+ return /* @__PURE__ */ jsx6(Box5, { children: /* @__PURE__ */ jsx6(InlineContent, { tokens: tokenizeLine(block.content) }) }, blockIdx);
16645
16697
  };
16646
- var MarkdownText = memo3(({ content }) => {
16698
+ var MarkdownText = memo4(({ content }) => {
16647
16699
  const lines = content.split("\n");
16648
16700
  const blocks = parseBlocks(lines);
16649
- return /* @__PURE__ */ jsx5(Box4, { flexDirection: "column", children: blocks.map((block, i) => /* @__PURE__ */ jsx5(BlockRenderer, { block, blockIdx: i }, i)) });
16701
+ return /* @__PURE__ */ jsx6(Box5, { flexDirection: "column", children: blocks.map((block, i) => /* @__PURE__ */ jsx6(BlockRenderer, { block, blockIdx: i }, i)) });
16650
16702
  });
16651
16703
 
16652
16704
  // src/platform/tui/components/messages/parseStatusContent.ts
@@ -16693,12 +16745,12 @@ function computeResultDisplay(content) {
16693
16745
  }
16694
16746
 
16695
16747
  // src/platform/tui/components/messages/MessageRow.tsx
16696
- import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
16697
- var MessageRow = memo4(({ msg }) => {
16748
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
16749
+ var MessageRow = memo5(({ msg }) => {
16698
16750
  if (msg.type === "status") {
16699
16751
  const statusData = parseStatusContent(msg.content);
16700
16752
  if (statusData) {
16701
- return /* @__PURE__ */ jsx6(Box5, { flexDirection: "column", children: /* @__PURE__ */ jsx6(
16753
+ return /* @__PURE__ */ jsx7(Box6, { flexDirection: "column", children: /* @__PURE__ */ jsx7(
16702
16754
  InlineStatus,
16703
16755
  {
16704
16756
  processes: statusData.processes,
@@ -16707,144 +16759,150 @@ var MessageRow = memo4(({ msg }) => {
16707
16759
  }
16708
16760
  ) }, msg.id);
16709
16761
  }
16710
- return /* @__PURE__ */ jsxs5(Box5, { children: [
16711
- /* @__PURE__ */ jsx6(Text5, { dimColor: true, color: THEME.dimGray, children: " \xB7 " }),
16712
- /* @__PURE__ */ jsx6(Text5, { dimColor: true, color: THEME.gray, children: msg.content })
16762
+ return /* @__PURE__ */ jsxs6(Box6, { children: [
16763
+ /* @__PURE__ */ jsx7(Text6, { dimColor: true, color: THEME.dimGray, children: " \xB7 " }),
16764
+ /* @__PURE__ */ jsx7(Text6, { dimColor: true, color: THEME.gray, children: msg.content })
16713
16765
  ] }, msg.id);
16714
16766
  }
16715
16767
  if (msg.type === "thinking") {
16716
- return /* @__PURE__ */ jsx6(ThinkingBlock, { msg });
16768
+ return /* @__PURE__ */ jsx7(ThinkingBlock, { msg });
16717
16769
  }
16718
16770
  if (msg.type === "tool") {
16719
- return /* @__PURE__ */ jsx6(Box5, { children: /* @__PURE__ */ jsx6(ToolCard, { content: msg.content }) }, msg.id);
16771
+ return /* @__PURE__ */ jsx7(Box6, { children: /* @__PURE__ */ jsx7(ToolCard, { content: msg.content }) }, msg.id);
16720
16772
  }
16721
16773
  if (msg.type === "result") {
16722
16774
  const kind = classifyResult(msg.content);
16723
16775
  const color = kind === "success" ? THEME.primary : kind === "failure" ? THEME.red : kind === "warning" ? THEME.yellow : THEME.gray;
16724
16776
  const { firstLine, visibleRest, hasMore } = computeResultDisplay(msg.content);
16725
16777
  const hiddenCount = msg.content.split("\n").length - 1;
16726
- return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
16727
- /* @__PURE__ */ jsxs5(Box5, { children: [
16728
- /* @__PURE__ */ jsx6(Text5, { color: THEME.dimGray, children: " \u2514 " }),
16729
- /* @__PURE__ */ jsx6(Text5, { color, children: firstLine }),
16730
- hasMore && /* @__PURE__ */ jsx6(Text5, { dimColor: true, color: THEME.dimGray, children: ` [+${hiddenCount - RESULT_PREVIEW_LINES}]` })
16778
+ return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
16779
+ /* @__PURE__ */ jsxs6(Box6, { children: [
16780
+ /* @__PURE__ */ jsx7(Text6, { color: THEME.dimGray, children: " \u2514 " }),
16781
+ /* @__PURE__ */ jsx7(Text6, { color, children: firstLine }),
16782
+ hasMore && /* @__PURE__ */ jsx7(Text6, { dimColor: true, color: THEME.dimGray, children: ` [+${hiddenCount - RESULT_PREVIEW_LINES}]` })
16731
16783
  ] }),
16732
- visibleRest.map((line, i) => /* @__PURE__ */ jsxs5(Box5, { children: [
16733
- /* @__PURE__ */ jsx6(Text5, { color: THEME.dimGray, children: " " }),
16734
- /* @__PURE__ */ jsx6(Text5, { dimColor: true, color: THEME.gray, children: line })
16784
+ visibleRest.map((line, i) => /* @__PURE__ */ jsxs6(Box6, { children: [
16785
+ /* @__PURE__ */ jsx7(Text6, { color: THEME.dimGray, children: " " }),
16786
+ /* @__PURE__ */ jsx7(Text6, { dimColor: true, color: THEME.gray, children: line })
16735
16787
  ] }, i))
16736
16788
  ] }, msg.id);
16737
16789
  }
16738
16790
  if (msg.type === "ai" || msg.type === "assistant") {
16739
- return /* @__PURE__ */ jsx6(Box5, { flexDirection: "column", marginBottom: 0, children: /* @__PURE__ */ jsx6(MarkdownText, { content: msg.content }) }, msg.id);
16791
+ return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", marginBottom: 0, children: [
16792
+ /* @__PURE__ */ jsxs6(Box6, { children: [
16793
+ /* @__PURE__ */ jsx7(Text6, { color: THEME.primary, children: "\u25B8 " }),
16794
+ /* @__PURE__ */ jsx7(Text6, { color: THEME.gray, bold: true, children: "Response" })
16795
+ ] }),
16796
+ /* @__PURE__ */ jsx7(Box6, { paddingLeft: 2, children: /* @__PURE__ */ jsx7(MarkdownText, { content: msg.content }) })
16797
+ ] }, msg.id);
16740
16798
  }
16741
16799
  if (msg.type === "error") {
16742
16800
  const eLines = msg.content.split("\n");
16743
16801
  const eFirst = eLines[0] || msg.content;
16744
16802
  const eHidden = eLines.length - 1;
16745
- return /* @__PURE__ */ jsx6(Box5, { flexDirection: "column", children: /* @__PURE__ */ jsxs5(Box5, { children: [
16746
- /* @__PURE__ */ jsx6(Text5, { color: THEME.red, children: " \u2717 " }),
16747
- /* @__PURE__ */ jsx6(Text5, { color: THEME.red, children: eFirst }),
16748
- eHidden > 0 && /* @__PURE__ */ jsx6(Text5, { dimColor: true, color: THEME.dimGray, children: ` [+${eHidden}]` })
16803
+ return /* @__PURE__ */ jsx7(Box6, { flexDirection: "column", children: /* @__PURE__ */ jsxs6(Box6, { children: [
16804
+ /* @__PURE__ */ jsx7(Text6, { color: THEME.red, children: " \u2717 " }),
16805
+ /* @__PURE__ */ jsx7(Text6, { color: THEME.red, children: eFirst }),
16806
+ eHidden > 0 && /* @__PURE__ */ jsx7(Text6, { dimColor: true, color: THEME.dimGray, children: ` [+${eHidden}]` })
16749
16807
  ] }) }, msg.id);
16750
16808
  }
16751
16809
  if (msg.type === "user") {
16752
- return /* @__PURE__ */ jsxs5(Box5, { children: [
16753
- /* @__PURE__ */ jsx6(Text5, { color: THEME.primary, children: "\u276F " }),
16754
- /* @__PURE__ */ jsx6(Text5, { color: THEME.white, bold: true, children: msg.content })
16810
+ return /* @__PURE__ */ jsxs6(Box6, { children: [
16811
+ /* @__PURE__ */ jsx7(Text6, { color: THEME.primary, children: "\u276F " }),
16812
+ /* @__PURE__ */ jsx7(Text6, { color: THEME.white, bold: true, children: msg.content })
16755
16813
  ] }, msg.id);
16756
16814
  }
16757
16815
  if (msg.type === "system") {
16758
- return /* @__PURE__ */ jsxs5(Box5, { children: [
16759
- /* @__PURE__ */ jsx6(Text5, { dimColor: true, color: THEME.dimGray, children: " \xB7 " }),
16760
- /* @__PURE__ */ jsx6(Text5, { dimColor: true, color: THEME.gray, children: msg.content })
16816
+ return /* @__PURE__ */ jsxs6(Box6, { children: [
16817
+ /* @__PURE__ */ jsx7(Text6, { dimColor: true, color: THEME.dimGray, children: " \xB7 " }),
16818
+ /* @__PURE__ */ jsx7(Text6, { dimColor: true, color: THEME.gray, children: msg.content })
16761
16819
  ] }, msg.id);
16762
16820
  }
16763
- return /* @__PURE__ */ jsxs5(Box5, { children: [
16764
- /* @__PURE__ */ jsx6(Text5, { dimColor: true, color: THEME.dimGray, children: " \xB7 " }),
16765
- /* @__PURE__ */ jsx6(Text5, { color: MESSAGE_STYLES.colors[msg.type] ?? THEME.gray, children: msg.content })
16821
+ return /* @__PURE__ */ jsxs6(Box6, { children: [
16822
+ /* @__PURE__ */ jsx7(Text6, { dimColor: true, color: THEME.dimGray, children: " \xB7 " }),
16823
+ /* @__PURE__ */ jsx7(Text6, { color: MESSAGE_STYLES.colors[msg.type] ?? THEME.gray, children: msg.content })
16766
16824
  ] }, msg.id);
16767
16825
  });
16768
16826
 
16769
- // src/platform/tui/components/messages/EmptyState.tsx
16770
- import { memo as memo6 } from "react";
16771
- import { Box as Box7, Text as Text7 } from "ink";
16827
+ // src/platform/tui/components/messages/BrandingHeader.tsx
16828
+ import { memo as memo7 } from "react";
16829
+ import { Box as Box8, Text as Text8 } from "ink";
16772
16830
 
16773
16831
  // src/platform/tui/components/ShimmerBanner.tsx
16774
- import { memo as memo5 } from "react";
16775
- import { Box as Box6, Text as Text6 } from "ink";
16776
- import { jsx as jsx7 } from "react/jsx-runtime";
16777
- var ShimmerBanner = memo5(({ banner }) => {
16832
+ import { memo as memo6 } from "react";
16833
+ import { Box as Box7, Text as Text7 } from "ink";
16834
+ import { jsx as jsx8 } from "react/jsx-runtime";
16835
+ var ShimmerBanner = memo6(({ banner }) => {
16778
16836
  const lines = banner.split("\n").filter((l) => l.length > 0);
16779
- return /* @__PURE__ */ jsx7(Box6, { flexDirection: "column", children: lines.map((line, row) => /* @__PURE__ */ jsx7(Text6, { color: HEX.primary, children: line }, row)) });
16837
+ return /* @__PURE__ */ jsx8(Box7, { flexDirection: "column", children: lines.map((line, row) => /* @__PURE__ */ jsx8(Text7, { color: HEX.primary, children: line }, row)) });
16780
16838
  });
16781
16839
 
16782
- // src/platform/tui/components/messages/EmptyState.tsx
16783
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
16784
- var EmptyState = memo6(({ modelName, autoApproveMode, version }) => {
16840
+ // src/platform/tui/components/messages/BrandingHeader.tsx
16841
+ import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
16842
+ var BrandingHeader = memo7(({ modelName, autoApproveMode, version, showGuide = false }) => {
16785
16843
  const autoLabel = autoApproveMode ? "ON" : "OFF";
16786
- const autoColor = autoApproveMode ? THEME.primary : THEME.gray;
16787
- return /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
16788
- /* @__PURE__ */ jsx8(ShimmerBanner, { banner: ASCII_BANNER }),
16789
- /* @__PURE__ */ jsxs6(Box7, { paddingLeft: 2, gap: 2, children: [
16790
- version && /* @__PURE__ */ jsx8(Text7, { color: THEME.dimGray, children: `v${version}` }),
16791
- modelName && /* @__PURE__ */ jsxs6(Text7, { color: THEME.dimGray, children: [
16792
- "\xB7",
16793
- " ",
16794
- /* @__PURE__ */ jsx8(Text7, { color: THEME.gray, children: modelName })
16844
+ const autoColor = autoApproveMode ? THEME.primary : THEME.dimGray;
16845
+ return /* @__PURE__ */ jsxs7(Box8, { flexDirection: "column", paddingBottom: 1, children: [
16846
+ /* @__PURE__ */ jsx9(ShimmerBanner, { banner: ASCII_BANNER }),
16847
+ /* @__PURE__ */ jsxs7(Box8, { gap: 1, paddingLeft: 1, children: [
16848
+ version && /* @__PURE__ */ jsx9(Text8, { color: THEME.dimGray, children: `v${version}` }),
16849
+ modelName && /* @__PURE__ */ jsxs7(Fragment4, { children: [
16850
+ /* @__PURE__ */ jsx9(Text8, { color: THEME.dimGray, children: "\xB7" }),
16851
+ /* @__PURE__ */ jsx9(Text8, { color: THEME.gray, children: modelName })
16795
16852
  ] }),
16796
- /* @__PURE__ */ jsxs6(Text7, { color: THEME.dimGray, children: [
16797
- "\xB7",
16798
- " Auto: ",
16799
- /* @__PURE__ */ jsx8(Text7, { color: autoColor, children: autoLabel })
16800
- ] })
16853
+ /* @__PURE__ */ jsx9(Text8, { color: THEME.dimGray, children: "\xB7" }),
16854
+ /* @__PURE__ */ jsx9(Text8, { color: THEME.dimGray, children: "Auto:" }),
16855
+ /* @__PURE__ */ jsx9(Text8, { color: autoColor, bold: !!autoApproveMode, children: autoLabel })
16801
16856
  ] }),
16802
- /* @__PURE__ */ jsx8(Text7, { children: " " }),
16803
- /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", paddingLeft: 2, children: [
16804
- /* @__PURE__ */ jsx8(Text7, { color: THEME.gray, children: "Get started:" }),
16805
- /* @__PURE__ */ jsxs6(Text7, { color: THEME.gray, children: [
16806
- " ",
16807
- /* @__PURE__ */ jsxs6(Text7, { color: THEME.white, children: [
16808
- "/target ",
16809
- "<ip>"
16857
+ showGuide && /* @__PURE__ */ jsxs7(Box8, { flexDirection: "column", paddingTop: 1, paddingLeft: 1, children: [
16858
+ /* @__PURE__ */ jsx9(Text8, { color: THEME.dimGray, children: "\u2500".repeat(40) }),
16859
+ /* @__PURE__ */ jsxs7(Box8, { flexDirection: "column", paddingTop: 0, children: [
16860
+ /* @__PURE__ */ jsxs7(Box8, { gap: 2, children: [
16861
+ /* @__PURE__ */ jsx9(Text8, { color: THEME.primary, children: "\u276F" }),
16862
+ /* @__PURE__ */ jsx9(Text8, { color: THEME.white, children: "/target <ip>" }),
16863
+ /* @__PURE__ */ jsx9(Text8, { color: THEME.dimGray, children: "Set target IP or domain" })
16810
16864
  ] }),
16811
- " \u2014 Set target IP or domain"
16812
- ] }),
16813
- /* @__PURE__ */ jsxs6(Text7, { color: THEME.gray, children: [
16814
- " ",
16815
- /* @__PURE__ */ jsx8(Text7, { color: THEME.white, children: "/start" }),
16816
- " \u2014 Begin autonomous pentest"
16817
- ] }),
16818
- /* @__PURE__ */ jsxs6(Text7, { color: THEME.gray, children: [
16819
- " ",
16820
- /* @__PURE__ */ jsx8(Text7, { color: THEME.white, children: "/help" }),
16821
- " \u2014 Show all commands"
16822
- ] }),
16823
- /* @__PURE__ */ jsx8(Text7, { children: " " }),
16824
- /* @__PURE__ */ jsx8(Text7, { color: THEME.dimGray, children: "Or just type a task and press Enter." })
16865
+ /* @__PURE__ */ jsxs7(Box8, { gap: 2, children: [
16866
+ /* @__PURE__ */ jsx9(Text8, { color: THEME.primary, children: "\u276F" }),
16867
+ /* @__PURE__ */ jsx9(Text8, { color: THEME.white, children: "/start" }),
16868
+ /* @__PURE__ */ jsx9(Text8, { color: THEME.dimGray, children: " Begin autonomous pentest" })
16869
+ ] }),
16870
+ /* @__PURE__ */ jsxs7(Box8, { gap: 2, children: [
16871
+ /* @__PURE__ */ jsx9(Text8, { color: THEME.primary, children: "\u276F" }),
16872
+ /* @__PURE__ */ jsx9(Text8, { color: THEME.white, children: "/help" }),
16873
+ /* @__PURE__ */ jsx9(Text8, { color: THEME.dimGray, children: " Show all commands" })
16874
+ ] }),
16875
+ /* @__PURE__ */ jsx9(Box8, { paddingTop: 1, children: /* @__PURE__ */ jsx9(Text8, { color: THEME.dimGray, children: "Or just type a task and press Enter." }) })
16876
+ ] })
16825
16877
  ] })
16826
16878
  ] });
16827
16879
  });
16828
16880
 
16829
16881
  // src/platform/tui/components/MessageList.tsx
16830
- import { jsx as jsx9 } from "react/jsx-runtime";
16831
- var MessageList = memo7(({ messages, modelName, autoApproveMode, version }) => {
16832
- if (messages.length === 0) {
16833
- return /* @__PURE__ */ jsx9(
16834
- EmptyState,
16835
- {
16836
- modelName,
16837
- autoApproveMode,
16838
- version
16839
- }
16840
- );
16841
- }
16842
- return /* @__PURE__ */ jsx9(Box8, { flexDirection: "column", children: /* @__PURE__ */ jsx9(Static, { items: messages, children: (msg) => /* @__PURE__ */ jsx9(MessageRow, { msg }, msg.id) }) });
16882
+ import { jsx as jsx10 } from "react/jsx-runtime";
16883
+ var HEADER_ITEM = { id: "__header__", type: "header" };
16884
+ var MessageList = memo8(({ messages, modelName, autoApproveMode, version }) => {
16885
+ const staticItems = [HEADER_ITEM, ...messages];
16886
+ return /* @__PURE__ */ jsx10(Box9, { flexDirection: "column", children: /* @__PURE__ */ jsx10(Static, { items: staticItems, children: (item) => {
16887
+ if (item.type === "header") {
16888
+ return /* @__PURE__ */ jsx10(
16889
+ BrandingHeader,
16890
+ {
16891
+ modelName,
16892
+ autoApproveMode,
16893
+ version,
16894
+ showGuide: messages.length === 0
16895
+ },
16896
+ "__header__"
16897
+ );
16898
+ }
16899
+ return /* @__PURE__ */ jsx10(MessageRow, { msg: item }, item.id);
16900
+ } }) });
16843
16901
  });
16844
16902
 
16845
16903
  // src/platform/tui/components/StatusDisplay.tsx
16846
- import { memo as memo10 } from "react";
16847
- import { Box as Box11, Text as Text12 } from "ink";
16904
+ import { memo as memo11 } from "react";
16905
+ import { Box as Box12, Text as Text13 } from "ink";
16848
16906
 
16849
16907
  // src/platform/tui/hooks/useStatusTimer.ts
16850
16908
  import { useState as useState4, useEffect as useEffect6, useRef as useRef5 } from "react";
@@ -16872,12 +16930,12 @@ var useStatusTimer = (currentStatus, isProcessing) => {
16872
16930
  };
16873
16931
 
16874
16932
  // src/platform/tui/components/status/RetryView.tsx
16875
- import { Box as Box9, Text as Text9 } from "ink";
16933
+ import { Box as Box10, Text as Text10 } from "ink";
16876
16934
 
16877
16935
  // src/platform/tui/components/StarSpinner.tsx
16878
- import { memo as memo8 } from "react";
16879
- import { Text as Text8 } from "ink";
16880
- import { jsx as jsx10 } from "react/jsx-runtime";
16936
+ import { memo as memo9 } from "react";
16937
+ import { Text as Text9 } from "ink";
16938
+ import { jsx as jsx11 } from "react/jsx-runtime";
16881
16939
  var FRAMES = [
16882
16940
  "\xB7",
16883
16941
  "\u2726",
@@ -16894,34 +16952,34 @@ var FRAMES = [
16894
16952
  "\u2727",
16895
16953
  "\u2726"
16896
16954
  ];
16897
- var StarSpinner = memo8(({ color }) => {
16955
+ var StarSpinner = memo9(({ color }) => {
16898
16956
  const tick = useAnimationTick();
16899
16957
  const index = tick % FRAMES.length;
16900
- return /* @__PURE__ */ jsx10(Text8, { color: color || "yellow", children: FRAMES[index] });
16958
+ return /* @__PURE__ */ jsx11(Text9, { color: color || "yellow", children: FRAMES[index] });
16901
16959
  });
16902
16960
 
16903
16961
  // src/platform/tui/components/status/RetryView.tsx
16904
- import { jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
16962
+ import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
16905
16963
  var RetryView = ({ retryState }) => {
16906
16964
  const truncateError = (err) => {
16907
16965
  return err.length > DISPLAY_LIMITS.RETRY_ERROR_PREVIEW ? err.substring(0, DISPLAY_LIMITS.RETRY_ERROR_TRUNCATED) + "..." : err;
16908
16966
  };
16909
- return /* @__PURE__ */ jsxs7(Box9, { flexDirection: "column", height: 2, children: [
16910
- /* @__PURE__ */ jsxs7(Box9, { children: [
16911
- /* @__PURE__ */ jsx11(Text9, { color: THEME.yellow, wrap: "truncate", children: /* @__PURE__ */ jsx11(StarSpinner, { color: THEME.yellow }) }),
16912
- /* @__PURE__ */ jsxs7(Text9, { color: THEME.yellow, bold: true, wrap: "truncate", children: [
16967
+ return /* @__PURE__ */ jsxs8(Box10, { flexDirection: "column", height: 2, children: [
16968
+ /* @__PURE__ */ jsxs8(Box10, { children: [
16969
+ /* @__PURE__ */ jsx12(Text10, { color: THEME.yellow, wrap: "truncate", children: /* @__PURE__ */ jsx12(StarSpinner, { color: THEME.yellow }) }),
16970
+ /* @__PURE__ */ jsxs8(Text10, { color: THEME.yellow, bold: true, wrap: "truncate", children: [
16913
16971
  " \u29F3 Retry #",
16914
16972
  retryState.attempt,
16915
16973
  "/",
16916
16974
  retryState.maxRetries
16917
16975
  ] }),
16918
- /* @__PURE__ */ jsxs7(Text9, { color: THEME.gray, wrap: "truncate", children: [
16976
+ /* @__PURE__ */ jsxs8(Text10, { color: THEME.gray, wrap: "truncate", children: [
16919
16977
  " \u2014 ",
16920
16978
  retryState.countdown,
16921
16979
  "s"
16922
16980
  ] })
16923
16981
  ] }),
16924
- /* @__PURE__ */ jsx11(Box9, { children: /* @__PURE__ */ jsxs7(Text9, { color: THEME.gray, wrap: "truncate", children: [
16982
+ /* @__PURE__ */ jsx12(Box10, { children: /* @__PURE__ */ jsxs8(Text10, { color: THEME.gray, wrap: "truncate", children: [
16925
16983
  " ",
16926
16984
  truncateError(retryState.error)
16927
16985
  ] }) })
@@ -16929,12 +16987,12 @@ var RetryView = ({ retryState }) => {
16929
16987
  };
16930
16988
 
16931
16989
  // src/platform/tui/components/status/ProcessingView.tsx
16932
- import { Box as Box10, Text as Text11 } from "ink";
16990
+ import { Box as Box11, Text as Text12 } from "ink";
16933
16991
 
16934
16992
  // src/platform/tui/components/ShimmerText.tsx
16935
- import { memo as memo9 } from "react";
16936
- import { Text as Text10 } from "ink";
16937
- import { jsx as jsx12 } from "react/jsx-runtime";
16993
+ import { memo as memo10 } from "react";
16994
+ import { Text as Text11 } from "ink";
16995
+ import { jsx as jsx13 } from "react/jsx-runtime";
16938
16996
  var WAVE_SPEED = 0.25 * (120 / ANIM_TICK_MS);
16939
16997
  var CHAR_PHASE_GAP = 0.55;
16940
16998
  function sinToColor(sin) {
@@ -16943,19 +17001,19 @@ function sinToColor(sin) {
16943
17001
  const hex = brightness.toString(16).padStart(2, "0");
16944
17002
  return `#${hex}${hex}${hex}`;
16945
17003
  }
16946
- var ShimmerText = memo9(({ children, bold, phase = 0 }) => {
17004
+ var ShimmerText = memo10(({ children, bold, phase = 0 }) => {
16947
17005
  const tick = useAnimationTick();
16948
17006
  const globalPhase = tick * WAVE_SPEED + phase;
16949
- return /* @__PURE__ */ jsx12(Text10, { bold, children: Array.from(children).map((char, i) => {
17007
+ return /* @__PURE__ */ jsx13(Text11, { bold, children: Array.from(children).map((char, i) => {
16950
17008
  const charPhase = globalPhase - i * CHAR_PHASE_GAP;
16951
17009
  const sin = Math.sin(charPhase);
16952
17010
  const color = sinToColor(sin);
16953
- return /* @__PURE__ */ jsx12(Text10, { color, children: char }, i);
17011
+ return /* @__PURE__ */ jsx13(Text11, { color, children: char }, i);
16954
17012
  }) });
16955
17013
  });
16956
17014
 
16957
17015
  // src/platform/tui/components/status/ProcessingView.tsx
16958
- import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
17016
+ import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
16959
17017
  var ProcessingView = ({
16960
17018
  statusMain,
16961
17019
  detailText,
@@ -16974,27 +17032,27 @@ var ProcessingView = ({
16974
17032
  const parenIdx = statusMain.indexOf("(");
16975
17033
  const shimmerPart = parenIdx > -1 ? statusMain.slice(0, parenIdx).trimEnd() : statusMain;
16976
17034
  const staticSuffix = parenIdx > -1 ? " " + statusMain.slice(parenIdx) : "";
16977
- return /* @__PURE__ */ jsxs8(Box10, { flexDirection: "column", height: 2, children: [
16978
- /* @__PURE__ */ jsxs8(Box10, { children: [
16979
- /* @__PURE__ */ jsx13(Text11, { color, wrap: "truncate", children: /* @__PURE__ */ jsx13(StarSpinner, { color }) }),
16980
- /* @__PURE__ */ jsx13(Text11, { children: " " }),
16981
- /* @__PURE__ */ jsx13(ShimmerText, { bold: true, phase: 0, children: shimmerPart }),
16982
- staticSuffix ? /* @__PURE__ */ jsx13(Text11, { color: THEME.dimGray, wrap: "truncate", children: staticSuffix }) : null,
16983
- /* @__PURE__ */ jsxs8(Text11, { color: THEME.dimGray, wrap: "truncate", children: [
17035
+ return /* @__PURE__ */ jsxs9(Box11, { flexDirection: "column", height: 2, children: [
17036
+ /* @__PURE__ */ jsxs9(Box11, { children: [
17037
+ /* @__PURE__ */ jsx14(Text12, { color, wrap: "truncate", children: /* @__PURE__ */ jsx14(StarSpinner, { color }) }),
17038
+ /* @__PURE__ */ jsx14(Text12, { children: " " }),
17039
+ /* @__PURE__ */ jsx14(ShimmerText, { bold: true, phase: 0, children: shimmerPart }),
17040
+ staticSuffix ? /* @__PURE__ */ jsx14(Text12, { color: THEME.dimGray, wrap: "truncate", children: staticSuffix }) : null,
17041
+ /* @__PURE__ */ jsxs9(Text12, { color: THEME.dimGray, wrap: "truncate", children: [
16984
17042
  " ",
16985
17043
  meta
16986
17044
  ] })
16987
17045
  ] }),
16988
- /* @__PURE__ */ jsx13(Box10, { children: detailText ? /* @__PURE__ */ jsxs8(Text11, { color: THEME.dimGray, wrap: "truncate", children: [
17046
+ /* @__PURE__ */ jsx14(Box11, { children: detailText ? /* @__PURE__ */ jsxs9(Text12, { color: THEME.dimGray, wrap: "truncate", children: [
16989
17047
  " ",
16990
17048
  detailText
16991
- ] }) : /* @__PURE__ */ jsx13(Text11, { children: " " }) })
17049
+ ] }) : /* @__PURE__ */ jsx14(Text12, { children: " " }) })
16992
17050
  ] });
16993
17051
  };
16994
17052
 
16995
17053
  // src/platform/tui/components/StatusDisplay.tsx
16996
- import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
16997
- var StatusDisplay = memo10(({
17054
+ import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
17055
+ var StatusDisplay = memo11(({
16998
17056
  retryState,
16999
17057
  isProcessing,
17000
17058
  currentStatus,
@@ -17004,12 +17062,12 @@ var StatusDisplay = memo10(({
17004
17062
  const isWaitingForInput = inputRequest?.status === "active";
17005
17063
  const statusElapsed = useStatusTimer(currentStatus, isProcessing && !isWaitingForInput);
17006
17064
  if (retryState && retryState.status === "retrying") {
17007
- return /* @__PURE__ */ jsx14(RetryView, { retryState });
17065
+ return /* @__PURE__ */ jsx15(RetryView, { retryState });
17008
17066
  }
17009
17067
  if (isProcessing && isWaitingForInput) {
17010
- return /* @__PURE__ */ jsxs9(Box11, { flexDirection: "column", height: 2, children: [
17011
- /* @__PURE__ */ jsx14(Text12, { children: " " }),
17012
- /* @__PURE__ */ jsx14(Text12, { children: " " })
17068
+ return /* @__PURE__ */ jsxs10(Box12, { flexDirection: "column", height: 2, children: [
17069
+ /* @__PURE__ */ jsx15(Text13, { children: " " }),
17070
+ /* @__PURE__ */ jsx15(Text13, { children: " " })
17013
17071
  ] });
17014
17072
  }
17015
17073
  if (isProcessing) {
@@ -17017,7 +17075,7 @@ var StatusDisplay = memo10(({
17017
17075
  const statusLines = currentStatus ? currentStatus.split("\n").filter(Boolean) : [];
17018
17076
  const statusMain = statusLines[0] || "Processing...";
17019
17077
  const detailText = isThinkingStatus && statusLines.length > 1 ? statusLines[statusLines.length - 1].slice(0, 120) : "";
17020
- return /* @__PURE__ */ jsx14(
17078
+ return /* @__PURE__ */ jsx15(
17021
17079
  ProcessingView,
17022
17080
  {
17023
17081
  statusMain,
@@ -17028,46 +17086,46 @@ var StatusDisplay = memo10(({
17028
17086
  }
17029
17087
  );
17030
17088
  }
17031
- return /* @__PURE__ */ jsxs9(Box11, { flexDirection: "column", height: 2, children: [
17032
- /* @__PURE__ */ jsx14(Text12, { children: " " }),
17033
- /* @__PURE__ */ jsx14(Text12, { children: " " })
17089
+ return /* @__PURE__ */ jsxs10(Box12, { flexDirection: "column", height: 2, children: [
17090
+ /* @__PURE__ */ jsx15(Text13, { children: " " }),
17091
+ /* @__PURE__ */ jsx15(Text13, { children: " " })
17034
17092
  ] });
17035
17093
  });
17036
17094
 
17037
17095
  // src/platform/tui/components/ChatInput.tsx
17038
- import { useMemo, useCallback as useCallback7, useRef as useRef6, memo as memo11, useState as useState5, useEffect as useEffect7 } from "react";
17039
- import { Box as Box15, Text as Text16, useInput as useInput2 } from "ink";
17096
+ import { useMemo, useCallback as useCallback7, useRef as useRef6, memo as memo12, useState as useState5, useEffect as useEffect7 } from "react";
17097
+ import { Box as Box16, Text as Text17, useInput as useInput2 } from "ink";
17040
17098
 
17041
17099
  // src/platform/tui/components/input/AutocompletePreview.tsx
17042
- import { Box as Box12, Text as Text13 } from "ink";
17043
- import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
17100
+ import { Box as Box13, Text as Text14 } from "ink";
17101
+ import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
17044
17102
  var AutocompletePreview = ({
17045
17103
  suggestions,
17046
17104
  clampedIdx
17047
17105
  }) => {
17048
- return /* @__PURE__ */ jsx15(Box12, { flexDirection: "column", paddingX: 1, children: suggestions.map((cmd, i) => {
17106
+ return /* @__PURE__ */ jsx16(Box13, { flexDirection: "column", paddingX: 1, children: suggestions.map((cmd, i) => {
17049
17107
  const isSelected = i === clampedIdx;
17050
17108
  const argsText = cmd.args ? ` ${cmd.args}` : "";
17051
- return /* @__PURE__ */ jsxs10(Box12, { children: [
17052
- /* @__PURE__ */ jsx15(Text13, { color: isSelected ? THEME.primary : THEME.dimGray, children: isSelected ? " \u276F " : " " }),
17053
- /* @__PURE__ */ jsxs10(Text13, { color: isSelected ? THEME.white : THEME.gray, bold: isSelected, children: [
17109
+ return /* @__PURE__ */ jsxs11(Box13, { children: [
17110
+ /* @__PURE__ */ jsx16(Text14, { color: isSelected ? THEME.primary : THEME.dimGray, children: isSelected ? " \u276F " : " " }),
17111
+ /* @__PURE__ */ jsxs11(Text14, { color: isSelected ? THEME.white : THEME.gray, bold: isSelected, children: [
17054
17112
  "/",
17055
17113
  cmd.name
17056
17114
  ] }),
17057
- /* @__PURE__ */ jsx15(Text13, { dimColor: true, color: THEME.gray, children: argsText }),
17058
- /* @__PURE__ */ jsxs10(Text13, { dimColor: true, color: THEME.dimGray, children: [
17115
+ /* @__PURE__ */ jsx16(Text14, { dimColor: true, color: THEME.gray, children: argsText }),
17116
+ /* @__PURE__ */ jsxs11(Text14, { dimColor: true, color: THEME.dimGray, children: [
17059
17117
  " \u2014 ",
17060
17118
  cmd.description
17061
17119
  ] }),
17062
- isSelected && cmd.alias && /* @__PURE__ */ jsx15(Text13, { dimColor: true, color: THEME.dimGray, children: ` (/${cmd.alias})` })
17120
+ isSelected && cmd.alias && /* @__PURE__ */ jsx16(Text14, { dimColor: true, color: THEME.dimGray, children: ` (/${cmd.alias})` })
17063
17121
  ] }, cmd.name);
17064
17122
  }) });
17065
17123
  };
17066
17124
 
17067
17125
  // src/platform/tui/components/input/SecretInputArea.tsx
17068
- import { Box as Box13, Text as Text14, useStdout } from "ink";
17126
+ import { Box as Box14, Text as Text15, useStdout } from "ink";
17069
17127
  import TextInput from "ink-text-input";
17070
- import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
17128
+ import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
17071
17129
  var OUTER_PADDING = 2;
17072
17130
  var SecretInputArea = ({
17073
17131
  inputRequest,
@@ -17078,11 +17136,11 @@ var SecretInputArea = ({
17078
17136
  const { stdout } = useStdout();
17079
17137
  const borderWidth = Math.max(10, (stdout?.columns ?? 80) - OUTER_PADDING);
17080
17138
  const borderLine = "\u2501".repeat(borderWidth);
17081
- return /* @__PURE__ */ jsxs11(Box13, { flexDirection: "column", children: [
17082
- /* @__PURE__ */ jsx16(Box13, { children: /* @__PURE__ */ jsx16(Text14, { color: THEME.yellow, children: borderLine }) }),
17083
- /* @__PURE__ */ jsxs11(Box13, { paddingX: 1, children: [
17084
- /* @__PURE__ */ jsx16(Text14, { color: THEME.yellow, bold: true, children: "\u25B8 " }),
17085
- /* @__PURE__ */ jsx16(
17139
+ return /* @__PURE__ */ jsxs12(Box14, { flexDirection: "column", children: [
17140
+ /* @__PURE__ */ jsx17(Box14, { children: /* @__PURE__ */ jsx17(Text15, { color: THEME.yellow, children: borderLine }) }),
17141
+ /* @__PURE__ */ jsxs12(Box14, { paddingX: 1, children: [
17142
+ /* @__PURE__ */ jsx17(Text15, { color: THEME.yellow, bold: true, children: "\u25B8 " }),
17143
+ /* @__PURE__ */ jsx17(
17086
17144
  TextInput,
17087
17145
  {
17088
17146
  value: secretInput,
@@ -17093,14 +17151,14 @@ var SecretInputArea = ({
17093
17151
  }
17094
17152
  )
17095
17153
  ] }),
17096
- /* @__PURE__ */ jsx16(Box13, { children: /* @__PURE__ */ jsx16(Text14, { color: THEME.yellow, children: borderLine }) })
17154
+ /* @__PURE__ */ jsx17(Box14, { children: /* @__PURE__ */ jsx17(Text15, { color: THEME.yellow, children: borderLine }) })
17097
17155
  ] });
17098
17156
  };
17099
17157
 
17100
17158
  // src/platform/tui/components/input/NormalInputArea.tsx
17101
- import { Box as Box14, Text as Text15, useStdout as useStdout2 } from "ink";
17159
+ import { Box as Box15, Text as Text16, useStdout as useStdout2 } from "ink";
17102
17160
  import TextInput2 from "ink-text-input";
17103
- import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
17161
+ import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
17104
17162
  var OUTER_PADDING2 = 2;
17105
17163
  var NormalInputArea = ({
17106
17164
  inputKey,
@@ -17112,11 +17170,11 @@ var NormalInputArea = ({
17112
17170
  const { stdout } = useStdout2();
17113
17171
  const borderWidth = Math.max(10, (stdout?.columns ?? 80) - OUTER_PADDING2);
17114
17172
  const borderLine = "\u2500".repeat(borderWidth);
17115
- return /* @__PURE__ */ jsxs12(Box14, { flexDirection: "column", children: [
17116
- /* @__PURE__ */ jsx17(Box14, { children: /* @__PURE__ */ jsx17(Text15, { dimColor: true, color: THEME.dimGray, children: borderLine }) }),
17117
- /* @__PURE__ */ jsxs12(Box14, { paddingX: 1, children: [
17118
- /* @__PURE__ */ jsx17(Text15, { color: THEME.primary, children: "\u276F " }),
17119
- /* @__PURE__ */ jsx17(
17173
+ return /* @__PURE__ */ jsxs13(Box15, { flexDirection: "column", children: [
17174
+ /* @__PURE__ */ jsx18(Box15, { children: /* @__PURE__ */ jsx18(Text16, { dimColor: true, color: THEME.dimGray, children: borderLine }) }),
17175
+ /* @__PURE__ */ jsxs13(Box15, { paddingX: 1, children: [
17176
+ /* @__PURE__ */ jsx18(Text16, { color: THEME.primary, children: "\u276F " }),
17177
+ /* @__PURE__ */ jsx18(
17120
17178
  TextInput2,
17121
17179
  {
17122
17180
  value,
@@ -17127,14 +17185,14 @@ var NormalInputArea = ({
17127
17185
  inputKey
17128
17186
  )
17129
17187
  ] }),
17130
- /* @__PURE__ */ jsx17(Box14, { children: /* @__PURE__ */ jsx17(Text15, { dimColor: true, color: THEME.dimGray, children: borderLine }) })
17188
+ /* @__PURE__ */ jsx18(Box15, { children: /* @__PURE__ */ jsx18(Text16, { dimColor: true, color: THEME.dimGray, children: borderLine }) })
17131
17189
  ] });
17132
17190
  };
17133
17191
 
17134
17192
  // src/platform/tui/components/ChatInput.tsx
17135
- import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
17193
+ import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
17136
17194
  var MAX_SUGGESTIONS = 6;
17137
- var ChatInput = memo11(({
17195
+ var ChatInput = memo12(({
17138
17196
  value,
17139
17197
  onChange,
17140
17198
  onSubmit,
@@ -17231,8 +17289,8 @@ var ChatInput = memo11(({
17231
17289
  completeCommand(selectedIdxRef.current);
17232
17290
  }
17233
17291
  }, [completeCommand]));
17234
- return /* @__PURE__ */ jsxs13(Box15, { flexDirection: "column", children: [
17235
- showPreview && /* @__PURE__ */ jsx18(
17292
+ return /* @__PURE__ */ jsxs14(Box16, { flexDirection: "column", children: [
17293
+ showPreview && /* @__PURE__ */ jsx19(
17236
17294
  AutocompletePreview,
17237
17295
  {
17238
17296
  suggestions,
@@ -17241,7 +17299,7 @@ var ChatInput = memo11(({
17241
17299
  ),
17242
17300
  inputRequest.status === "active" ? (
17243
17301
  /* Active input request — yellow top/bottom border */
17244
- /* @__PURE__ */ jsx18(
17302
+ /* @__PURE__ */ jsx19(
17245
17303
  SecretInputArea,
17246
17304
  {
17247
17305
  inputRequest,
@@ -17252,7 +17310,7 @@ var ChatInput = memo11(({
17252
17310
  )
17253
17311
  ) : (
17254
17312
  /* Normal input — dim top/bottom border */
17255
- /* @__PURE__ */ jsx18(
17313
+ /* @__PURE__ */ jsx19(
17256
17314
  NormalInputArea,
17257
17315
  {
17258
17316
  inputKey,
@@ -17263,14 +17321,14 @@ var ChatInput = memo11(({
17263
17321
  }
17264
17322
  )
17265
17323
  ),
17266
- pastedHint && /* @__PURE__ */ jsx18(Box15, { paddingX: 2, children: /* @__PURE__ */ jsx18(Text16, { dimColor: true, color: THEME.dimGray, children: pastedHint }) })
17324
+ pastedHint && /* @__PURE__ */ jsx19(Box16, { paddingX: 2, children: /* @__PURE__ */ jsx19(Text17, { dimColor: true, color: THEME.dimGray, children: pastedHint }) })
17267
17325
  ] });
17268
17326
  });
17269
17327
 
17270
17328
  // src/platform/tui/components/footer.tsx
17271
- import { memo as memo12 } from "react";
17272
- import { Box as Box16, Text as Text17 } from "ink";
17273
- import { jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
17329
+ import { memo as memo13 } from "react";
17330
+ import { Box as Box17, Text as Text18 } from "ink";
17331
+ import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
17274
17332
  var CTX_WARN_THRESHOLD = 0.8;
17275
17333
  var MAX_CONTEXT_TOKENS = LLM_LIMITS.streamMaxTokens;
17276
17334
  var formatElapsed = (totalSeconds) => {
@@ -17283,55 +17341,55 @@ var formatElapsed = (totalSeconds) => {
17283
17341
  }
17284
17342
  return `${minutes}:${pad(seconds)}`;
17285
17343
  };
17286
- var Footer = memo12(({ phase, targets, findings, todo, elapsedTime, isProcessing, totalTokens, turnCount }) => {
17344
+ var Footer = memo13(({ phase, targets, findings, todo, elapsedTime, isProcessing, totalTokens, turnCount }) => {
17287
17345
  const ctxPct = totalTokens > 0 ? Math.round(totalTokens / MAX_CONTEXT_TOKENS * 100) : 0;
17288
17346
  const ctxColor = ctxPct >= CTX_WARN_THRESHOLD * 100 ? THEME.yellow : THEME.dimGray;
17289
- return /* @__PURE__ */ jsxs14(
17290
- Box16,
17347
+ return /* @__PURE__ */ jsxs15(
17348
+ Box17,
17291
17349
  {
17292
17350
  width: "100%",
17293
17351
  paddingX: 1,
17294
17352
  justifyContent: "space-between",
17295
17353
  overflow: "hidden",
17296
17354
  children: [
17297
- /* @__PURE__ */ jsxs14(Box16, { gap: 2, children: [
17298
- /* @__PURE__ */ jsxs14(Text17, { color: THEME.gray, children: [
17355
+ /* @__PURE__ */ jsxs15(Box17, { gap: 2, children: [
17356
+ /* @__PURE__ */ jsxs15(Text18, { color: THEME.gray, children: [
17299
17357
  "Phase: ",
17300
- /* @__PURE__ */ jsx19(Text17, { color: THEME.white, children: phase })
17358
+ /* @__PURE__ */ jsx20(Text18, { color: THEME.white, children: phase })
17301
17359
  ] }),
17302
- /* @__PURE__ */ jsxs14(Text17, { color: THEME.gray, children: [
17360
+ /* @__PURE__ */ jsxs15(Text18, { color: THEME.gray, children: [
17303
17361
  "Targets: ",
17304
- /* @__PURE__ */ jsx19(Text17, { color: THEME.white, children: targets })
17362
+ /* @__PURE__ */ jsx20(Text18, { color: THEME.white, children: targets })
17305
17363
  ] }),
17306
- /* @__PURE__ */ jsxs14(Text17, { color: THEME.gray, children: [
17364
+ /* @__PURE__ */ jsxs15(Text18, { color: THEME.gray, children: [
17307
17365
  "Findings: ",
17308
- /* @__PURE__ */ jsx19(Text17, { color: THEME.white, children: findings })
17366
+ /* @__PURE__ */ jsx20(Text18, { color: THEME.white, children: findings })
17309
17367
  ] }),
17310
- /* @__PURE__ */ jsxs14(Text17, { color: THEME.gray, children: [
17368
+ /* @__PURE__ */ jsxs15(Text18, { color: THEME.gray, children: [
17311
17369
  "Tasks: ",
17312
- /* @__PURE__ */ jsx19(Text17, { color: THEME.white, children: todo })
17370
+ /* @__PURE__ */ jsx20(Text18, { color: THEME.white, children: todo })
17313
17371
  ] })
17314
17372
  ] }),
17315
- /* @__PURE__ */ jsxs14(Box16, { gap: 2, children: [
17316
- isProcessing ? /* @__PURE__ */ jsxs14(Box16, { gap: 1, children: [
17317
- /* @__PURE__ */ jsx19(Text17, { dimColor: true, color: THEME.dimGray, children: "[ESC] abort" }),
17318
- /* @__PURE__ */ jsx19(Text17, { dimColor: true, color: THEME.dimGray, children: "[^C\xD72] exit" })
17319
- ] }) : /* @__PURE__ */ jsx19(Text17, { dimColor: true, color: THEME.dimGray, children: "[/help] commands" }),
17320
- turnCount > 0 && /* @__PURE__ */ jsxs14(Text17, { dimColor: true, color: THEME.dimGray, children: [
17373
+ /* @__PURE__ */ jsxs15(Box17, { gap: 2, children: [
17374
+ isProcessing ? /* @__PURE__ */ jsxs15(Box17, { gap: 1, children: [
17375
+ /* @__PURE__ */ jsx20(Text18, { dimColor: true, color: THEME.dimGray, children: "[ESC] abort" }),
17376
+ /* @__PURE__ */ jsx20(Text18, { dimColor: true, color: THEME.dimGray, children: "[^C\xD72] exit" })
17377
+ ] }) : /* @__PURE__ */ jsx20(Text18, { dimColor: true, color: THEME.dimGray, children: "[/help] commands" }),
17378
+ turnCount > 0 && /* @__PURE__ */ jsxs15(Text18, { dimColor: true, color: THEME.dimGray, children: [
17321
17379
  "turn:",
17322
17380
  turnCount
17323
17381
  ] }),
17324
- totalTokens > 0 && /* @__PURE__ */ jsxs14(Text17, { dimColor: true, color: ctxColor, children: [
17382
+ totalTokens > 0 && /* @__PURE__ */ jsxs15(Text18, { dimColor: true, color: ctxColor, children: [
17325
17383
  "ctx:",
17326
17384
  ctxPct,
17327
17385
  "%"
17328
17386
  ] }),
17329
- totalTokens > 0 && /* @__PURE__ */ jsxs14(Text17, { dimColor: true, color: THEME.dimGray, children: [
17387
+ totalTokens > 0 && /* @__PURE__ */ jsxs15(Text18, { dimColor: true, color: THEME.dimGray, children: [
17330
17388
  "\u2191",
17331
17389
  formatTokens(totalTokens)
17332
17390
  ] }),
17333
- /* @__PURE__ */ jsx19(Text17, { color: isProcessing ? THEME.primary : THEME.gray, children: isProcessing ? "Running " : "Idle " }),
17334
- /* @__PURE__ */ jsx19(Text17, { color: THEME.white, children: formatElapsed(elapsedTime) })
17391
+ /* @__PURE__ */ jsx20(Text18, { color: isProcessing ? THEME.primary : THEME.gray, children: isProcessing ? "Running " : "Idle " }),
17392
+ /* @__PURE__ */ jsx20(Text18, { color: THEME.white, children: formatElapsed(elapsedTime) })
17335
17393
  ] })
17336
17394
  ]
17337
17395
  }
@@ -17340,15 +17398,15 @@ var Footer = memo12(({ phase, targets, findings, todo, elapsedTime, isProcessing
17340
17398
  var footer_default = Footer;
17341
17399
 
17342
17400
  // src/platform/tui/components/Modal.tsx
17343
- import { useMemo as useMemo2, memo as memo13, useCallback as useCallback8, useRef as useRef7 } from "react";
17344
- import { Box as Box17, Text as Text18, useStdout as useStdout3, useInput as useInput3 } from "ink";
17345
- import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
17401
+ import { useMemo as useMemo2, memo as memo14, useCallback as useCallback8, useRef as useRef7 } from "react";
17402
+ import { Box as Box18, Text as Text19, useStdout as useStdout3, useInput as useInput3 } from "ink";
17403
+ import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
17346
17404
  var MODAL_TITLES = {
17347
17405
  findings: "\u25C8 FINDINGS \u25C8",
17348
17406
  graph: "\u25C8 ATTACK GRAPH \u25C8",
17349
17407
  help: "\u25C8 COMMANDS \u25C8"
17350
17408
  };
17351
- var Modal = memo13(({
17409
+ var Modal = memo14(({
17352
17410
  type,
17353
17411
  content,
17354
17412
  scrollOffset,
@@ -17386,20 +17444,20 @@ var Modal = memo13(({
17386
17444
  const endLine = Math.min(scrollOffset + maxHeight, totalLines);
17387
17445
  const scrollbarHeight = Math.max(1, Math.floor(maxHeight * (maxHeight / Math.max(totalLines, 1))));
17388
17446
  const scrollbarPosition = totalLines > maxHeight ? Math.floor(scrollOffset / (totalLines - maxHeight) * (maxHeight - scrollbarHeight)) : 0;
17389
- return /* @__PURE__ */ jsxs15(
17390
- Box17,
17447
+ return /* @__PURE__ */ jsxs16(
17448
+ Box18,
17391
17449
  {
17392
17450
  flexDirection: "column",
17393
17451
  width: terminalWidth,
17394
17452
  height: terminalHeight,
17395
17453
  children: [
17396
- /* @__PURE__ */ jsx20(Box17, { justifyContent: "center", marginBottom: 0, children: /* @__PURE__ */ jsx20(Text18, { color: THEME.cyan, bold: true, children: (() => {
17454
+ /* @__PURE__ */ jsx21(Box18, { justifyContent: "center", marginBottom: 0, children: /* @__PURE__ */ jsx21(Text19, { color: THEME.cyan, bold: true, children: (() => {
17397
17455
  const title = MODAL_TITLES[type];
17398
17456
  const sideWidth = Math.max(3, Math.floor((terminalWidth - title.length - 2) / 2));
17399
17457
  return `${"\u2500".repeat(sideWidth)} ${title} ${"\u2500".repeat(sideWidth)}`;
17400
17458
  })() }) }),
17401
- /* @__PURE__ */ jsx20(
17402
- Box17,
17459
+ /* @__PURE__ */ jsx21(
17460
+ Box18,
17403
17461
  {
17404
17462
  flexDirection: "column",
17405
17463
  borderStyle: "round",
@@ -17408,17 +17466,17 @@ var Modal = memo13(({
17408
17466
  flexGrow: 1,
17409
17467
  children: visibleLines.map((line, i) => {
17410
17468
  const showScrollbar = totalLines > maxHeight && i >= scrollbarPosition && i < scrollbarPosition + scrollbarHeight;
17411
- return /* @__PURE__ */ jsxs15(Box17, { children: [
17412
- /* @__PURE__ */ jsx20(Text18, { color: THEME.white, wrap: "truncate", children: line }),
17413
- /* @__PURE__ */ jsx20(Box17, { flexGrow: 1 }),
17414
- totalLines > maxHeight && /* @__PURE__ */ jsx20(Text18, { color: showScrollbar ? THEME.cyan : THEME.dimGray, children: showScrollbar ? "\u2588" : "\u2502" })
17469
+ return /* @__PURE__ */ jsxs16(Box18, { children: [
17470
+ /* @__PURE__ */ jsx21(Text19, { color: THEME.white, wrap: "truncate", children: line }),
17471
+ /* @__PURE__ */ jsx21(Box18, { flexGrow: 1 }),
17472
+ totalLines > maxHeight && /* @__PURE__ */ jsx21(Text19, { color: showScrollbar ? THEME.cyan : THEME.dimGray, children: showScrollbar ? "\u2588" : "\u2502" })
17415
17473
  ] }, i);
17416
17474
  })
17417
17475
  }
17418
17476
  ),
17419
- /* @__PURE__ */ jsxs15(Box17, { justifyContent: "space-between", paddingX: 1, children: [
17420
- /* @__PURE__ */ jsx20(Text18, { dimColor: true, color: THEME.gray, children: "\u2191\u2193/jk: scroll | g/G: top/bottom | ESC/q: close" }),
17421
- /* @__PURE__ */ jsxs15(Text18, { dimColor: true, color: THEME.cyan, children: [
17477
+ /* @__PURE__ */ jsxs16(Box18, { justifyContent: "space-between", paddingX: 1, children: [
17478
+ /* @__PURE__ */ jsx21(Text19, { dimColor: true, color: THEME.gray, children: "\u2191\u2193/jk: scroll | g/G: top/bottom | ESC/q: close" }),
17479
+ /* @__PURE__ */ jsxs16(Text19, { dimColor: true, color: THEME.cyan, children: [
17422
17480
  startLine,
17423
17481
  "-",
17424
17482
  endLine,
@@ -17432,8 +17490,8 @@ var Modal = memo13(({
17432
17490
  });
17433
17491
 
17434
17492
  // src/platform/tui/components/app/bottom-region.tsx
17435
- import { Box as Box18 } from "ink";
17436
- import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
17493
+ import { Box as Box19 } from "ink";
17494
+ import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
17437
17495
  var BottomRegion = ({
17438
17496
  input,
17439
17497
  setInput,
@@ -17457,8 +17515,8 @@ var BottomRegion = ({
17457
17515
  const suggestionCount = isSlashMode && !hasArgs && inputRequest.status !== "active" ? Math.min(getMatchingCommands(partialCmd).length, MAX_SUGGESTIONS) : 0;
17458
17516
  const previewHeight = suggestionCount;
17459
17517
  const bottomMinHeight = 7;
17460
- return /* @__PURE__ */ jsxs16(Box18, { flexDirection: "column", minHeight: bottomMinHeight, children: [
17461
- /* @__PURE__ */ jsx21(
17518
+ return /* @__PURE__ */ jsxs17(Box19, { flexDirection: "column", minHeight: bottomMinHeight, children: [
17519
+ /* @__PURE__ */ jsx22(
17462
17520
  StatusDisplay,
17463
17521
  {
17464
17522
  retryState,
@@ -17468,7 +17526,7 @@ var BottomRegion = ({
17468
17526
  inputRequest
17469
17527
  }
17470
17528
  ),
17471
- /* @__PURE__ */ jsx21(
17529
+ /* @__PURE__ */ jsx22(
17472
17530
  ChatInput,
17473
17531
  {
17474
17532
  value: input,
@@ -17481,7 +17539,7 @@ var BottomRegion = ({
17481
17539
  onSecretSubmit: handleSecretSubmit
17482
17540
  }
17483
17541
  ),
17484
- /* @__PURE__ */ jsx21(Box18, { marginTop: 1, children: /* @__PURE__ */ jsx21(
17542
+ /* @__PURE__ */ jsx22(Box19, { marginTop: 1, children: /* @__PURE__ */ jsx22(
17485
17543
  footer_default,
17486
17544
  {
17487
17545
  phase: stats.phase,
@@ -17498,7 +17556,7 @@ var BottomRegion = ({
17498
17556
  };
17499
17557
 
17500
17558
  // src/platform/tui/app.tsx
17501
- import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
17559
+ import { jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
17502
17560
  var MODEL_NAME = getModel() || DEFAULT_MODEL;
17503
17561
  var App = ({ autoApprove = false, target }) => {
17504
17562
  const { exit } = useApp();
@@ -17525,7 +17583,9 @@ var App = ({ autoApprove = false, target }) => {
17525
17583
  abort,
17526
17584
  cancelInputRequest,
17527
17585
  addMessage,
17528
- refreshStats
17586
+ refreshStats,
17587
+ liveReasoning,
17588
+ isReasoning
17529
17589
  } = useAgent(autoApproveMode, target);
17530
17590
  const isProcessingRef = useRef8(isProcessing);
17531
17591
  isProcessingRef.current = isProcessing;
@@ -17549,7 +17609,7 @@ var App = ({ autoApprove = false, target }) => {
17549
17609
  const handleModalScroll = useCallback9((delta) => {
17550
17610
  setModal((prev) => {
17551
17611
  const lines = prev.content.split("\n");
17552
- const maxHeight = (stdout?.rows ?? 24) - 6;
17612
+ const maxHeight = (stdout?.rows ?? TUI_DISPLAY_LIMITS.TERMINAL_DEFAULT_ROWS) - TUI_DISPLAY_LIMITS.MODAL_CHROME_HEIGHT;
17553
17613
  const maxScroll = Math.max(0, lines.length - maxHeight);
17554
17614
  const newOffset = Math.max(0, Math.min(maxScroll, prev.scrollOffset + delta));
17555
17615
  return { ...prev, scrollOffset: newOffset };
@@ -17588,7 +17648,7 @@ var App = ({ autoApprove = false, target }) => {
17588
17648
  await handleCommand(cmd, args);
17589
17649
  } else if (isProcessingRef.current) {
17590
17650
  agent.enqueueUserInput(trimmed);
17591
- addMessage("system", "\u{1F4AC} Message queued \u2014 will be processed at next iteration");
17651
+ addMessage("system", UI_MESSAGES.QUEUED);
17592
17652
  } else {
17593
17653
  await executeTask(trimmed);
17594
17654
  }
@@ -17596,8 +17656,8 @@ var App = ({ autoApprove = false, target }) => {
17596
17656
  const handleSecretSubmit = useCallback9((value) => {
17597
17657
  const ir = inputRequestRef.current;
17598
17658
  if (ir.status !== "active") return;
17599
- const displayText = ir.isPassword ? "\u2022".repeat(Math.min(value.length, 20)) : value;
17600
- addMessage("system", `\u21B3 ${displayText}`);
17659
+ const displayText = ir.isPassword ? "\u2022".repeat(Math.min(value.length, TUI_DISPLAY_LIMITS.PASSWORD_MASK_MAX)) : value;
17660
+ addMessage("system", `${UI_MESSAGES.SECRET_PREFIX}${displayText}`);
17601
17661
  ir.resolve(value);
17602
17662
  setInputRequest({ status: "inactive" });
17603
17663
  setSecretInput("");
@@ -17614,7 +17674,7 @@ var App = ({ autoApprove = false, target }) => {
17614
17674
  clearInput
17615
17675
  });
17616
17676
  if (modal.type) {
17617
- return /* @__PURE__ */ jsx22(Box19, { flexDirection: "column", paddingX: 1, width: terminalWidth, children: /* @__PURE__ */ jsx22(
17677
+ return /* @__PURE__ */ jsx23(Box20, { flexDirection: "column", paddingX: 1, width: terminalWidth, children: /* @__PURE__ */ jsx23(
17618
17678
  Modal,
17619
17679
  {
17620
17680
  type: modal.type,
@@ -17625,8 +17685,8 @@ var App = ({ autoApprove = false, target }) => {
17625
17685
  }
17626
17686
  ) });
17627
17687
  }
17628
- return /* @__PURE__ */ jsxs17(Box19, { flexDirection: "column", paddingX: 1, width: terminalWidth, children: [
17629
- /* @__PURE__ */ jsx22(Box19, { flexDirection: "column", children: /* @__PURE__ */ jsx22(
17688
+ return /* @__PURE__ */ jsxs18(Box20, { flexDirection: "column", width: terminalWidth, children: [
17689
+ /* @__PURE__ */ jsx23(Box20, { flexDirection: "column", children: /* @__PURE__ */ jsx23(
17630
17690
  MessageList,
17631
17691
  {
17632
17692
  messages,
@@ -17635,7 +17695,14 @@ var App = ({ autoApprove = false, target }) => {
17635
17695
  version: APP_VERSION
17636
17696
  }
17637
17697
  ) }),
17638
- /* @__PURE__ */ jsx22(
17698
+ /* @__PURE__ */ jsx23(
17699
+ LiveReasoningPanel,
17700
+ {
17701
+ content: liveReasoning,
17702
+ isReasoning
17703
+ }
17704
+ ),
17705
+ /* @__PURE__ */ jsx23(
17639
17706
  BottomRegion,
17640
17707
  {
17641
17708
  input,
@@ -17660,7 +17727,7 @@ var App = ({ autoApprove = false, target }) => {
17660
17727
  var app_default = App;
17661
17728
 
17662
17729
  // src/platform/tui/cli/commands/interactive.tsx
17663
- import { jsx as jsx23 } from "react/jsx-runtime";
17730
+ import { jsx as jsx24 } from "react/jsx-runtime";
17664
17731
  async function interactiveAction(options) {
17665
17732
  const { dangerouslySkipPermissions: skipPermissions = false, target } = options;
17666
17733
  console.clear();
@@ -17669,7 +17736,7 @@ async function interactiveAction(options) {
17669
17736
  console.log(chalk.hex(HEX.red)("[!] All tool executions will be auto-approved!\n"));
17670
17737
  }
17671
17738
  const { waitUntilExit } = render(
17672
- /* @__PURE__ */ jsx23(AnimationProvider, { children: /* @__PURE__ */ jsx23(
17739
+ /* @__PURE__ */ jsx24(AnimationProvider, { children: /* @__PURE__ */ jsx24(
17673
17740
  app_default,
17674
17741
  {
17675
17742
  autoApprove: skipPermissions,