pentesting 0.70.3 → 0.70.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +290 -266
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -120,7 +120,7 @@ var ICONS = {
|
|
|
120
120
|
};
|
|
121
121
|
|
|
122
122
|
// src/shared/utils/debug/debug-logger.ts
|
|
123
|
-
import { appendFileSync, writeFileSync } from "fs";
|
|
123
|
+
import { appendFileSync, writeFileSync, statSync, readFileSync } from "fs";
|
|
124
124
|
import { join } from "path";
|
|
125
125
|
|
|
126
126
|
// src/shared/utils/file-ops/file-utils.ts
|
|
@@ -275,10 +275,14 @@ var FILE_PATTERNS = {
|
|
|
275
275
|
};
|
|
276
276
|
|
|
277
277
|
// src/shared/utils/debug/debug-logger.ts
|
|
278
|
+
var ROTATE_BYTES = 5 * 1024 * 1024;
|
|
279
|
+
var WIPE_BYTES = 20 * 1024 * 1024;
|
|
280
|
+
var ROTATE_CHECK_INTERVAL = 500;
|
|
278
281
|
var DebugLogger = class _DebugLogger {
|
|
279
282
|
static instance;
|
|
280
283
|
logPath;
|
|
281
284
|
initialized = false;
|
|
285
|
+
writeCount = 0;
|
|
282
286
|
constructor(clearOnInit = false) {
|
|
283
287
|
const debugDir = WORKSPACE.DEBUG;
|
|
284
288
|
try {
|
|
@@ -306,6 +310,31 @@ var DebugLogger = class _DebugLogger {
|
|
|
306
310
|
_DebugLogger.instance = new _DebugLogger(clearOnInit);
|
|
307
311
|
return _DebugLogger.instance;
|
|
308
312
|
}
|
|
313
|
+
/**
|
|
314
|
+
* Rotate or wipe debug.log if it exceeds size thresholds.
|
|
315
|
+
* Called every ROTATE_CHECK_INTERVAL writes to amortize statSync cost.
|
|
316
|
+
*
|
|
317
|
+
* Policy:
|
|
318
|
+
* > 20 MB → wipe entirely (too much data, disk pressure)
|
|
319
|
+
* > 5 MB → keep latest half (recent logs more useful than old ones)
|
|
320
|
+
*/
|
|
321
|
+
rotateIfNeeded() {
|
|
322
|
+
try {
|
|
323
|
+
const size = statSync(this.logPath).size;
|
|
324
|
+
if (size > WIPE_BYTES) {
|
|
325
|
+
writeFileSync(this.logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] [GENERAL] === LOG WIPED (exceeded ${Math.round(WIPE_BYTES / 1024 / 1024)}MB) ===
|
|
326
|
+
`);
|
|
327
|
+
} else if (size > ROTATE_BYTES) {
|
|
328
|
+
const content = readFileSync(this.logPath, "utf-8");
|
|
329
|
+
const half = content.slice(Math.floor(content.length / 2));
|
|
330
|
+
const firstNewline = half.indexOf("\n");
|
|
331
|
+
const trimmed = firstNewline >= 0 ? half.slice(firstNewline + 1) : half;
|
|
332
|
+
writeFileSync(this.logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] [GENERAL] === LOG ROTATED (exceeded ${Math.round(ROTATE_BYTES / 1024 / 1024)}MB, kept latest half) ===
|
|
333
|
+
` + trimmed);
|
|
334
|
+
}
|
|
335
|
+
} catch {
|
|
336
|
+
}
|
|
337
|
+
}
|
|
309
338
|
log(category, message, data) {
|
|
310
339
|
if (!this.initialized || !this.logPath) return;
|
|
311
340
|
try {
|
|
@@ -316,6 +345,9 @@ var DebugLogger = class _DebugLogger {
|
|
|
316
345
|
}
|
|
317
346
|
logLine += "\n";
|
|
318
347
|
appendFileSync(this.logPath, logLine);
|
|
348
|
+
if (++this.writeCount % ROTATE_CHECK_INTERVAL === 0) {
|
|
349
|
+
this.rotateIfNeeded();
|
|
350
|
+
}
|
|
319
351
|
} catch (e) {
|
|
320
352
|
console.error("[DebugLogger] Write error:", e);
|
|
321
353
|
}
|
|
@@ -329,6 +361,9 @@ ${raw}
|
|
|
329
361
|
---
|
|
330
362
|
`;
|
|
331
363
|
appendFileSync(this.logPath, logLine);
|
|
364
|
+
if (++this.writeCount % ROTATE_CHECK_INTERVAL === 0) {
|
|
365
|
+
this.rotateIfNeeded();
|
|
366
|
+
}
|
|
332
367
|
} catch (e) {
|
|
333
368
|
console.error("[DebugLogger] Write error:", e);
|
|
334
369
|
}
|
|
@@ -727,7 +762,7 @@ var INPUT_PROMPT_PATTERNS = [
|
|
|
727
762
|
|
|
728
763
|
// src/shared/constants/agent.ts
|
|
729
764
|
var APP_NAME = "Pentest AI";
|
|
730
|
-
var APP_VERSION = "0.70.
|
|
765
|
+
var APP_VERSION = "0.70.5";
|
|
731
766
|
var APP_DESCRIPTION = "Autonomous Penetration Testing AI Agent";
|
|
732
767
|
var LLM_ROLES = {
|
|
733
768
|
SYSTEM: "system",
|
|
@@ -782,7 +817,7 @@ import { render } from "ink";
|
|
|
782
817
|
import chalk from "chalk";
|
|
783
818
|
|
|
784
819
|
// src/platform/tui/app.tsx
|
|
785
|
-
import { useState as
|
|
820
|
+
import { useState as useState7, useCallback as useCallback11, useRef as useRef10 } from "react";
|
|
786
821
|
import { Box as Box19, useApp, useStdout as useStdout4 } from "ink";
|
|
787
822
|
|
|
788
823
|
// src/platform/tui/hooks/useAgent.ts
|
|
@@ -2458,7 +2493,7 @@ var EpisodicMemory = class {
|
|
|
2458
2493
|
};
|
|
2459
2494
|
|
|
2460
2495
|
// src/shared/utils/agent-memory/persistent-memory.ts
|
|
2461
|
-
import { existsSync as existsSync2, readFileSync, writeFileSync as writeFileSync2, unlinkSync } from "fs";
|
|
2496
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, unlinkSync } from "fs";
|
|
2462
2497
|
import { join as join2 } from "path";
|
|
2463
2498
|
|
|
2464
2499
|
// src/shared/utils/agent-memory/similarity.ts
|
|
@@ -2634,7 +2669,7 @@ var PersistentMemory = class {
|
|
|
2634
2669
|
loadSessionSnapshot() {
|
|
2635
2670
|
try {
|
|
2636
2671
|
if (existsSync2(SNAPSHOT_FILE)) {
|
|
2637
|
-
return JSON.parse(
|
|
2672
|
+
return JSON.parse(readFileSync2(SNAPSHOT_FILE, "utf-8"));
|
|
2638
2673
|
}
|
|
2639
2674
|
} catch {
|
|
2640
2675
|
}
|
|
@@ -2670,7 +2705,7 @@ var PersistentMemory = class {
|
|
|
2670
2705
|
load() {
|
|
2671
2706
|
try {
|
|
2672
2707
|
if (existsSync2(MEMORY_FILE)) {
|
|
2673
|
-
const data = JSON.parse(
|
|
2708
|
+
const data = JSON.parse(readFileSync2(MEMORY_FILE, "utf-8"));
|
|
2674
2709
|
return {
|
|
2675
2710
|
...data,
|
|
2676
2711
|
exploitChains: data.exploitChains ?? []
|
|
@@ -4555,7 +4590,7 @@ Suggestion: ${torLeak.suggestion}`
|
|
|
4555
4590
|
}
|
|
4556
4591
|
|
|
4557
4592
|
// src/engine/tools-base/file-operations.ts
|
|
4558
|
-
import { readFileSync as
|
|
4593
|
+
import { readFileSync as readFileSync3, existsSync as existsSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
4559
4594
|
import { dirname } from "path";
|
|
4560
4595
|
import { join as join3 } from "path";
|
|
4561
4596
|
import { tmpdir } from "os";
|
|
@@ -4575,7 +4610,7 @@ async function readFileContent(filePath) {
|
|
|
4575
4610
|
error: `File not found: ${filePath}`
|
|
4576
4611
|
};
|
|
4577
4612
|
}
|
|
4578
|
-
const content =
|
|
4613
|
+
const content = readFileSync3(filePath, "utf-8");
|
|
4579
4614
|
return {
|
|
4580
4615
|
success: true,
|
|
4581
4616
|
output: content
|
|
@@ -4679,7 +4714,7 @@ function startBackgroundProcess(command, options = {}) {
|
|
|
4679
4714
|
}
|
|
4680
4715
|
|
|
4681
4716
|
// src/engine/process/process-interaction.ts
|
|
4682
|
-
import { existsSync as existsSync4, readFileSync as
|
|
4717
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4, appendFileSync as appendFileSync2 } from "fs";
|
|
4683
4718
|
async function sendToProcess(processId, input, waitMs = SYSTEM_LIMITS.DEFAULT_WAIT_MS_INTERACT) {
|
|
4684
4719
|
const proc = getProcess(processId);
|
|
4685
4720
|
if (!proc) return { success: false, output: `Process ${processId} not found`, newOutput: "" };
|
|
@@ -4688,7 +4723,7 @@ async function sendToProcess(processId, input, waitMs = SYSTEM_LIMITS.DEFAULT_WA
|
|
|
4688
4723
|
let currentLen = 0;
|
|
4689
4724
|
try {
|
|
4690
4725
|
if (existsSync4(proc.stdoutFile)) {
|
|
4691
|
-
currentLen =
|
|
4726
|
+
currentLen = readFileSync4(proc.stdoutFile, "utf-8").length;
|
|
4692
4727
|
}
|
|
4693
4728
|
} catch {
|
|
4694
4729
|
}
|
|
@@ -4702,7 +4737,7 @@ async function sendToProcess(processId, input, waitMs = SYSTEM_LIMITS.DEFAULT_WA
|
|
|
4702
4737
|
let fullStdout = "";
|
|
4703
4738
|
try {
|
|
4704
4739
|
if (existsSync4(proc.stdoutFile)) {
|
|
4705
|
-
fullStdout =
|
|
4740
|
+
fullStdout = readFileSync4(proc.stdoutFile, "utf-8");
|
|
4706
4741
|
}
|
|
4707
4742
|
} catch {
|
|
4708
4743
|
}
|
|
@@ -4724,7 +4759,7 @@ function promoteToShell(processId, description) {
|
|
|
4724
4759
|
}
|
|
4725
4760
|
|
|
4726
4761
|
// src/engine/process/process-monitor.ts
|
|
4727
|
-
import { existsSync as existsSync5, readFileSync as
|
|
4762
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5 } from "fs";
|
|
4728
4763
|
function isProcessRunning(processId) {
|
|
4729
4764
|
const proc = getProcess(processId);
|
|
4730
4765
|
if (!proc) return false;
|
|
@@ -4738,7 +4773,7 @@ function isProcessRunning(processId) {
|
|
|
4738
4773
|
if (proc.role === PROCESS_ROLES.LISTENER) {
|
|
4739
4774
|
try {
|
|
4740
4775
|
if (existsSync5(proc.stdoutFile)) {
|
|
4741
|
-
const stdout =
|
|
4776
|
+
const stdout = readFileSync5(proc.stdoutFile, "utf-8");
|
|
4742
4777
|
if (detectConnection(stdout)) {
|
|
4743
4778
|
promoteToShell(processId, "Reverse shell connected (auto-detected)");
|
|
4744
4779
|
logEvent(processId, PROCESS_EVENTS.CONNECTION_DETECTED, `Connection detected on port ${proc.listeningPort}`);
|
|
@@ -4757,7 +4792,7 @@ function getProcessOutput(processId) {
|
|
|
4757
4792
|
let stderr = "";
|
|
4758
4793
|
try {
|
|
4759
4794
|
if (existsSync5(proc.stdoutFile)) {
|
|
4760
|
-
const content =
|
|
4795
|
+
const content = readFileSync5(proc.stdoutFile, "utf-8");
|
|
4761
4796
|
stdout = content.length > SYSTEM_LIMITS.MAX_STDOUT_SLICE ? `... [truncated ${content.length - SYSTEM_LIMITS.MAX_STDOUT_SLICE} chars] ...
|
|
4762
4797
|
` + content.slice(-SYSTEM_LIMITS.MAX_STDOUT_SLICE) : content;
|
|
4763
4798
|
}
|
|
@@ -4765,7 +4800,7 @@ function getProcessOutput(processId) {
|
|
|
4765
4800
|
}
|
|
4766
4801
|
try {
|
|
4767
4802
|
if (existsSync5(proc.stderrFile)) {
|
|
4768
|
-
const content =
|
|
4803
|
+
const content = readFileSync5(proc.stderrFile, "utf-8");
|
|
4769
4804
|
stderr = content.length > SYSTEM_LIMITS.MAX_STDERR_SLICE ? `... [truncated ${content.length - SYSTEM_LIMITS.MAX_STDERR_SLICE} chars] ...
|
|
4770
4805
|
` + content.slice(-SYSTEM_LIMITS.MAX_STDERR_SLICE) : content;
|
|
4771
4806
|
}
|
|
@@ -4938,7 +4973,7 @@ async function cleanupAllProcesses() {
|
|
|
4938
4973
|
}
|
|
4939
4974
|
|
|
4940
4975
|
// src/engine/process/resource-summary.ts
|
|
4941
|
-
import { existsSync as existsSync6, readFileSync as
|
|
4976
|
+
import { existsSync as existsSync6, readFileSync as readFileSync6 } from "fs";
|
|
4942
4977
|
function getResourceSummary() {
|
|
4943
4978
|
const procs = listBackgroundProcesses();
|
|
4944
4979
|
const running = procs.filter((p) => p.isRunning);
|
|
@@ -4958,7 +4993,7 @@ function getResourceSummary() {
|
|
|
4958
4993
|
let lastOutput = "";
|
|
4959
4994
|
try {
|
|
4960
4995
|
if (p.stdoutFile && existsSync6(p.stdoutFile)) {
|
|
4961
|
-
const content =
|
|
4996
|
+
const content = readFileSync6(p.stdoutFile, "utf-8");
|
|
4962
4997
|
const outputLines = content.trim().split("\n");
|
|
4963
4998
|
lastOutput = outputLines.slice(-SYSTEM_LIMITS.RECENT_OUTPUT_LINES).join(" | ").replace(/\n/g, " ");
|
|
4964
4999
|
}
|
|
@@ -5203,7 +5238,7 @@ BLOCKED (leak real IP): ping, traceroute, dig, nslookup, nmap -sU`
|
|
|
5203
5238
|
};
|
|
5204
5239
|
|
|
5205
5240
|
// src/engine/state/persistence/saver.ts
|
|
5206
|
-
import { writeFileSync as writeFileSync5, readdirSync, statSync, unlinkSync as unlinkSync5 } from "fs";
|
|
5241
|
+
import { writeFileSync as writeFileSync5, readdirSync, statSync as statSync2, unlinkSync as unlinkSync5 } from "fs";
|
|
5207
5242
|
import { join as join4 } from "path";
|
|
5208
5243
|
function saveState(state) {
|
|
5209
5244
|
const sessionsDir = WORKSPACE.SESSIONS;
|
|
@@ -5236,7 +5271,7 @@ function pruneOldSessions(sessionsDir) {
|
|
|
5236
5271
|
return {
|
|
5237
5272
|
name: f,
|
|
5238
5273
|
path: filePath,
|
|
5239
|
-
mtime:
|
|
5274
|
+
mtime: statSync2(filePath).mtimeMs
|
|
5240
5275
|
};
|
|
5241
5276
|
}).sort((a, b) => b.mtime - a.mtime);
|
|
5242
5277
|
const toDelete = sessionFiles.slice(AGENT_LIMITS.MAX_SESSION_FILES);
|
|
@@ -5248,7 +5283,7 @@ function pruneOldSessions(sessionsDir) {
|
|
|
5248
5283
|
}
|
|
5249
5284
|
|
|
5250
5285
|
// src/engine/state/persistence/loader.ts
|
|
5251
|
-
import { readFileSync as
|
|
5286
|
+
import { readFileSync as readFileSync7, existsSync as existsSync7 } from "fs";
|
|
5252
5287
|
import { join as join5 } from "path";
|
|
5253
5288
|
function loadState(state) {
|
|
5254
5289
|
const latestFile = join5(WORKSPACE.SESSIONS, "latest.json");
|
|
@@ -5256,7 +5291,7 @@ function loadState(state) {
|
|
|
5256
5291
|
return false;
|
|
5257
5292
|
}
|
|
5258
5293
|
try {
|
|
5259
|
-
const raw =
|
|
5294
|
+
const raw = readFileSync7(latestFile, "utf-8");
|
|
5260
5295
|
const snapshot = JSON.parse(raw);
|
|
5261
5296
|
if (snapshot.version !== 1) {
|
|
5262
5297
|
debugLog("general", `Unknown snapshot version: ${snapshot.version}`);
|
|
@@ -10357,7 +10392,7 @@ function mutatePayload(request) {
|
|
|
10357
10392
|
}
|
|
10358
10393
|
|
|
10359
10394
|
// src/domains/exploit/tools.ts
|
|
10360
|
-
import { existsSync as existsSync10, statSync as
|
|
10395
|
+
import { existsSync as existsSync10, statSync as statSync3, readdirSync as readdirSync2 } from "fs";
|
|
10361
10396
|
import { join as join10 } from "path";
|
|
10362
10397
|
var hashCrackTool = {
|
|
10363
10398
|
name: TOOL_NAMES.HASH_CRACK,
|
|
@@ -10516,7 +10551,7 @@ Returns: All available wordlists with their paths, sizes, and categories.`,
|
|
|
10516
10551
|
const processFile = (fullPath, fileName) => {
|
|
10517
10552
|
const ext = fileName.split(".").pop()?.toLowerCase();
|
|
10518
10553
|
if (!WORDLIST_EXTENSIONS.has(ext || "")) return;
|
|
10519
|
-
const stats =
|
|
10554
|
+
const stats = statSync3(fullPath);
|
|
10520
10555
|
if (stats.size < minSize) return;
|
|
10521
10556
|
if (!matchesCategory(fullPath)) return;
|
|
10522
10557
|
if (!matchesSearch(fullPath, fileName)) return;
|
|
@@ -13135,7 +13170,7 @@ var PHASE_TECHNIQUE_MAP = {
|
|
|
13135
13170
|
};
|
|
13136
13171
|
|
|
13137
13172
|
// src/agents/prompt-builder/prompt-loader.ts
|
|
13138
|
-
import { readFileSync as
|
|
13173
|
+
import { readFileSync as readFileSync8, existsSync as existsSync11 } from "fs";
|
|
13139
13174
|
import { join as join12, dirname as dirname4 } from "path";
|
|
13140
13175
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
13141
13176
|
var __dirname2 = dirname4(fileURLToPath2(import.meta.url));
|
|
@@ -13143,13 +13178,13 @@ var PROMPTS_DIR = join12(__dirname2, "../prompts");
|
|
|
13143
13178
|
var TECHNIQUES_DIR = join12(PROMPTS_DIR, PROMPT_PATHS.TECHNIQUES_DIR);
|
|
13144
13179
|
function loadPromptFile(filename) {
|
|
13145
13180
|
const path2 = join12(PROMPTS_DIR, filename);
|
|
13146
|
-
return existsSync11(path2) ?
|
|
13181
|
+
return existsSync11(path2) ? readFileSync8(path2, PROMPT_CONFIG.ENCODING) : "";
|
|
13147
13182
|
}
|
|
13148
13183
|
function loadTechniqueFile(techniqueName) {
|
|
13149
13184
|
const filePath = join12(TECHNIQUES_DIR, `${techniqueName}.md`);
|
|
13150
13185
|
try {
|
|
13151
13186
|
if (!existsSync11(filePath)) return "";
|
|
13152
|
-
return
|
|
13187
|
+
return readFileSync8(filePath, PROMPT_CONFIG.ENCODING);
|
|
13153
13188
|
} catch {
|
|
13154
13189
|
return "";
|
|
13155
13190
|
}
|
|
@@ -13294,11 +13329,11 @@ ${lines.join("\n")}
|
|
|
13294
13329
|
}
|
|
13295
13330
|
|
|
13296
13331
|
// src/shared/utils/journal/reader.ts
|
|
13297
|
-
import { readFileSync as
|
|
13332
|
+
import { readFileSync as readFileSync9, existsSync as existsSync13 } from "fs";
|
|
13298
13333
|
import { join as join14 } from "path";
|
|
13299
13334
|
|
|
13300
13335
|
// src/shared/utils/journal/rotation.ts
|
|
13301
|
-
import { existsSync as existsSync12, readdirSync as readdirSync3, statSync as
|
|
13336
|
+
import { existsSync as existsSync12, readdirSync as readdirSync3, statSync as statSync4, rmSync as rmSync2 } from "fs";
|
|
13302
13337
|
import { join as join13 } from "path";
|
|
13303
13338
|
function parseTurnNumbers(turnsDir) {
|
|
13304
13339
|
if (!existsSync12(turnsDir)) return [];
|
|
@@ -13308,7 +13343,7 @@ function rotateTurnRecords() {
|
|
|
13308
13343
|
try {
|
|
13309
13344
|
const turnsDir = WORKSPACE.TURNS;
|
|
13310
13345
|
if (!existsSync12(turnsDir)) return;
|
|
13311
|
-
const turnDirs = parseTurnNumbers(turnsDir).map((n) => `${TURN_FOLDER_PREFIX}${n}`).filter((e) =>
|
|
13346
|
+
const turnDirs = parseTurnNumbers(turnsDir).map((n) => `${TURN_FOLDER_PREFIX}${n}`).filter((e) => statSync4(join13(turnsDir, e)).isDirectory()).sort((a, b) => Number(a.slice(TURN_FOLDER_PREFIX.length)) - Number(b.slice(TURN_FOLDER_PREFIX.length)));
|
|
13312
13347
|
if (turnDirs.length > MEMORY_LIMITS.MAX_TURN_ENTRIES) {
|
|
13313
13348
|
const dirsToDel = turnDirs.slice(0, turnDirs.length - MEMORY_LIMITS.MAX_TURN_ENTRIES);
|
|
13314
13349
|
for (const dir of dirsToDel) {
|
|
@@ -13334,7 +13369,7 @@ function readJournalSummary() {
|
|
|
13334
13369
|
for (const turn of turnDirs) {
|
|
13335
13370
|
const summaryPath = join14(WORKSPACE.turnPath(turn), TURN_FILES.SUMMARY);
|
|
13336
13371
|
if (existsSync13(summaryPath)) {
|
|
13337
|
-
return
|
|
13372
|
+
return readFileSync9(summaryPath, "utf-8");
|
|
13338
13373
|
}
|
|
13339
13374
|
}
|
|
13340
13375
|
return "";
|
|
@@ -13351,7 +13386,7 @@ function getRecentEntries(count = MEMORY_LIMITS.MAX_TURN_ENTRIES) {
|
|
|
13351
13386
|
try {
|
|
13352
13387
|
const filePath = join14(WORKSPACE.turnPath(turn), TURN_FILES.STRUCTURED);
|
|
13353
13388
|
if (existsSync13(filePath)) {
|
|
13354
|
-
const raw =
|
|
13389
|
+
const raw = readFileSync9(filePath, "utf-8");
|
|
13355
13390
|
entries.push(JSON.parse(raw));
|
|
13356
13391
|
}
|
|
13357
13392
|
} catch {
|
|
@@ -14073,7 +14108,7 @@ function formatForPrompt(directive, isStale = false) {
|
|
|
14073
14108
|
}
|
|
14074
14109
|
|
|
14075
14110
|
// src/agents/strategist/prompt-loader.ts
|
|
14076
|
-
import { readFileSync as
|
|
14111
|
+
import { readFileSync as readFileSync10, existsSync as existsSync14 } from "fs";
|
|
14077
14112
|
import { join as join16, dirname as dirname5 } from "path";
|
|
14078
14113
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
14079
14114
|
var __dirname3 = dirname5(fileURLToPath3(import.meta.url));
|
|
@@ -14081,7 +14116,7 @@ var STRATEGIST_PROMPT_PATH = join16(__dirname3, "../prompts", "strategist-system
|
|
|
14081
14116
|
function loadSystemPrompt() {
|
|
14082
14117
|
try {
|
|
14083
14118
|
if (existsSync14(STRATEGIST_PROMPT_PATH)) {
|
|
14084
|
-
return
|
|
14119
|
+
return readFileSync10(STRATEGIST_PROMPT_PATH, "utf-8");
|
|
14085
14120
|
}
|
|
14086
14121
|
} catch {
|
|
14087
14122
|
}
|
|
@@ -14477,7 +14512,7 @@ async function processReflection(toolJournal, memo14, phase, reflector) {
|
|
|
14477
14512
|
}
|
|
14478
14513
|
|
|
14479
14514
|
// src/agents/main-agent/turn-recorder.ts
|
|
14480
|
-
import { writeFileSync as writeFileSync10, existsSync as existsSync15, readFileSync as
|
|
14515
|
+
import { writeFileSync as writeFileSync10, existsSync as existsSync15, readFileSync as readFileSync11 } from "fs";
|
|
14481
14516
|
import { join as join17 } from "path";
|
|
14482
14517
|
async function recordTurn(context) {
|
|
14483
14518
|
const { turnCounter, phase, toolJournal, memo: memo14, reflections, summaryRegenerator } = context;
|
|
@@ -14550,7 +14585,7 @@ async function regenerateSummary(turnCounter, summaryRegenerator, ctx) {
|
|
|
14550
14585
|
if (prevTurn >= 1) {
|
|
14551
14586
|
const prevSummaryPath = join17(WORKSPACE.turnPath(prevTurn), TURN_FILES.SUMMARY);
|
|
14552
14587
|
if (existsSync15(prevSummaryPath)) {
|
|
14553
|
-
existingSummary =
|
|
14588
|
+
existingSummary = readFileSync11(prevSummaryPath, "utf-8");
|
|
14554
14589
|
}
|
|
14555
14590
|
}
|
|
14556
14591
|
const turnData = formatTurnRecord({
|
|
@@ -15202,11 +15237,12 @@ ${firstLine}`);
|
|
|
15202
15237
|
}
|
|
15203
15238
|
|
|
15204
15239
|
// src/platform/tui/hooks/useAgentEvents/handlers/input.ts
|
|
15205
|
-
function setupInputHandlers(setInputRequest) {
|
|
15240
|
+
function setupInputHandlers(setInputRequest, addMessage) {
|
|
15206
15241
|
setInputHandler((p) => {
|
|
15207
15242
|
return new Promise((resolve) => {
|
|
15208
15243
|
const isPassword = /password|passphrase/i.test(p);
|
|
15209
15244
|
const inputType = /sudo/i.test(p) ? INPUT_TYPES.SUDO_PASSWORD : isPassword ? INPUT_TYPES.PASSWORD : INPUT_TYPES.TEXT;
|
|
15245
|
+
addMessage("ai", `\u{1F512} ${p.trim()}`);
|
|
15210
15246
|
setInputRequest({
|
|
15211
15247
|
status: "active",
|
|
15212
15248
|
prompt: p.trim(),
|
|
@@ -15220,6 +15256,7 @@ function setupInputHandlers(setInputRequest) {
|
|
|
15220
15256
|
return new Promise((resolve) => {
|
|
15221
15257
|
const isPassword = SENSITIVE_INPUT_TYPES.includes(request.type);
|
|
15222
15258
|
const displayPrompt = buildCredentialPrompt(request);
|
|
15259
|
+
addMessage("ai", `\u{1F512} ${displayPrompt}`);
|
|
15223
15260
|
setInputRequest({
|
|
15224
15261
|
status: "active",
|
|
15225
15262
|
prompt: displayPrompt,
|
|
@@ -15287,7 +15324,7 @@ var useAgentEvents = (agent, eventsRef, state) => {
|
|
|
15287
15324
|
lastStepTokensRef
|
|
15288
15325
|
}, reasoningBufferRef);
|
|
15289
15326
|
const reasoningHandlers = createReasoningHandlers({ addMessage, setCurrentStatus }, reasoningBufferRef);
|
|
15290
|
-
const cleanupInput = setupInputHandlers(setInputRequest);
|
|
15327
|
+
const cleanupInput = setupInputHandlers(setInputRequest, addMessage);
|
|
15291
15328
|
const cleanupCommand = setupCommandHandlers(addMessage);
|
|
15292
15329
|
const updateStats = () => {
|
|
15293
15330
|
const s = agent.getState();
|
|
@@ -16122,6 +16159,23 @@ var useKeyboardShortcuts = ({
|
|
|
16122
16159
|
return { handleCtrlC };
|
|
16123
16160
|
};
|
|
16124
16161
|
|
|
16162
|
+
// src/platform/tui/hooks/useAnimationTick.tsx
|
|
16163
|
+
import { createContext, useContext, useState as useState3, useEffect as useEffect5 } from "react";
|
|
16164
|
+
import { jsx } from "react/jsx-runtime";
|
|
16165
|
+
var ANIM_TICK_MS = 100;
|
|
16166
|
+
var AnimationContext = createContext(0);
|
|
16167
|
+
var AnimationProvider = ({ children }) => {
|
|
16168
|
+
const [tick, setTick] = useState3(0);
|
|
16169
|
+
useEffect5(() => {
|
|
16170
|
+
const timer = setInterval(() => {
|
|
16171
|
+
setTick((t) => t + 1);
|
|
16172
|
+
}, ANIM_TICK_MS);
|
|
16173
|
+
return () => clearInterval(timer);
|
|
16174
|
+
}, []);
|
|
16175
|
+
return /* @__PURE__ */ jsx(AnimationContext.Provider, { value: tick, children });
|
|
16176
|
+
};
|
|
16177
|
+
var useAnimationTick = () => useContext(AnimationContext);
|
|
16178
|
+
|
|
16125
16179
|
// src/platform/tui/components/MessageList.tsx
|
|
16126
16180
|
import { memo as memo7, useState as useState4, useCallback as useCallback8, useRef as useRef6 } from "react";
|
|
16127
16181
|
import { Box as Box8, Text as Text8, useInput as useInput2 } from "ink";
|
|
@@ -16129,7 +16183,7 @@ import { Box as Box8, Text as Text8, useInput as useInput2 } from "ink";
|
|
|
16129
16183
|
// src/platform/tui/components/messages/ThinkingBlock.tsx
|
|
16130
16184
|
import { memo } from "react";
|
|
16131
16185
|
import { Box, Text } from "ink";
|
|
16132
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
16186
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
16133
16187
|
var THINKING_PREVIEW_LINES = 3;
|
|
16134
16188
|
var ThinkingBlock = memo(({ msg, isExpanded }) => {
|
|
16135
16189
|
const lines = msg.content.split("\n");
|
|
@@ -16139,19 +16193,19 @@ var ThinkingBlock = memo(({ msg, isExpanded }) => {
|
|
|
16139
16193
|
const visibleLines = isExpanded ? lines : lines.slice(0, THINKING_PREVIEW_LINES);
|
|
16140
16194
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 0, children: [
|
|
16141
16195
|
/* @__PURE__ */ jsxs(Box, { children: [
|
|
16142
|
-
/* @__PURE__ */
|
|
16143
|
-
/* @__PURE__ */
|
|
16144
|
-
/* @__PURE__ */
|
|
16145
|
-
!isExpanded && hiddenCount > 0 && /* @__PURE__ */
|
|
16146
|
-
isExpanded && /* @__PURE__ */
|
|
16196
|
+
/* @__PURE__ */ jsx2(Text, { color: THEME.dimGray, children: " \u25C6 " }),
|
|
16197
|
+
/* @__PURE__ */ jsx2(Text, { color: THEME.gray, children: "Reasoning" }),
|
|
16198
|
+
/* @__PURE__ */ jsx2(Text, { color: THEME.dimGray, children: ` (~${estTokens} tokens)` }),
|
|
16199
|
+
!isExpanded && hiddenCount > 0 && /* @__PURE__ */ jsx2(Text, { color: THEME.dimGray, children: ` [+${hiddenCount} lines \xB7 R]` }),
|
|
16200
|
+
isExpanded && /* @__PURE__ */ jsx2(Text, { color: THEME.dimGray, children: " [R to collapse]" })
|
|
16147
16201
|
] }),
|
|
16148
16202
|
visibleLines.map((line, i) => /* @__PURE__ */ jsxs(Box, { children: [
|
|
16149
|
-
/* @__PURE__ */
|
|
16150
|
-
/* @__PURE__ */
|
|
16203
|
+
/* @__PURE__ */ jsx2(Text, { dimColor: true, children: " \u2502 " }),
|
|
16204
|
+
/* @__PURE__ */ jsx2(Text, { dimColor: true, children: line })
|
|
16151
16205
|
] }, i)),
|
|
16152
16206
|
!isExpanded && hiddenCount > 0 && /* @__PURE__ */ jsxs(Box, { children: [
|
|
16153
|
-
/* @__PURE__ */
|
|
16154
|
-
/* @__PURE__ */
|
|
16207
|
+
/* @__PURE__ */ jsx2(Text, { dimColor: true, children: " \u2502 " }),
|
|
16208
|
+
/* @__PURE__ */ jsx2(Text, { dimColor: true, children: "..." })
|
|
16155
16209
|
] })
|
|
16156
16210
|
] });
|
|
16157
16211
|
});
|
|
@@ -16198,7 +16252,7 @@ var MESSAGE_STYLES = {
|
|
|
16198
16252
|
|
|
16199
16253
|
// src/platform/tui/components/inline-status.tsx
|
|
16200
16254
|
import { Box as Box2, Text as Text2 } from "ink";
|
|
16201
|
-
import { Fragment, jsx as
|
|
16255
|
+
import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
16202
16256
|
function formatDuration3(ms) {
|
|
16203
16257
|
const seconds = Math.floor(ms / 1e3);
|
|
16204
16258
|
if (seconds < 60) return `${seconds}s`;
|
|
@@ -16246,13 +16300,13 @@ function ProcessRow({ proc, isCompact }) {
|
|
|
16246
16300
|
const purpose = proc.purpose || proc.description || "";
|
|
16247
16301
|
const truncatedPurpose = isCompact && purpose.length > TUI_DISPLAY_LIMITS.purposeMaxLength ? purpose.slice(0, TUI_DISPLAY_LIMITS.purposeTruncated) + "..." : purpose;
|
|
16248
16302
|
return /* @__PURE__ */ jsxs2(Box2, { children: [
|
|
16249
|
-
/* @__PURE__ */
|
|
16303
|
+
/* @__PURE__ */ jsx3(StatusIndicator, { isRunning: proc.isRunning, exitCode: proc.exitCode }),
|
|
16250
16304
|
/* @__PURE__ */ jsxs2(Text2, { color: THEME.gray, children: [
|
|
16251
16305
|
"[",
|
|
16252
16306
|
proc.id,
|
|
16253
16307
|
"]"
|
|
16254
16308
|
] }),
|
|
16255
|
-
/* @__PURE__ */
|
|
16309
|
+
/* @__PURE__ */ jsx3(Text2, { children: " " }),
|
|
16256
16310
|
/* @__PURE__ */ jsxs2(Text2, { color: getRoleColor(proc.role), bold: true, children: [
|
|
16257
16311
|
proc.role,
|
|
16258
16312
|
port
|
|
@@ -16263,8 +16317,8 @@ function ProcessRow({ proc, isCompact }) {
|
|
|
16263
16317
|
")"
|
|
16264
16318
|
] }),
|
|
16265
16319
|
truncatedPurpose && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
16266
|
-
/* @__PURE__ */
|
|
16267
|
-
/* @__PURE__ */
|
|
16320
|
+
/* @__PURE__ */ jsx3(Text2, { color: THEME.gray, children: " - " }),
|
|
16321
|
+
/* @__PURE__ */ jsx3(Text2, { color: THEME.gray, children: truncatedPurpose })
|
|
16268
16322
|
] })
|
|
16269
16323
|
] });
|
|
16270
16324
|
}
|
|
@@ -16275,7 +16329,7 @@ var InlineStatus = ({
|
|
|
16275
16329
|
isCompact = true
|
|
16276
16330
|
}) => {
|
|
16277
16331
|
if (processes.length === 0 && zombies.length === 0) {
|
|
16278
|
-
return /* @__PURE__ */
|
|
16332
|
+
return /* @__PURE__ */ jsx3(Box2, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsx3(Text2, { color: THEME.gray, children: "\u2022 No active background processes" }) });
|
|
16279
16333
|
}
|
|
16280
16334
|
const running = processes.filter((p) => p.isRunning);
|
|
16281
16335
|
const stopped = processes.filter((p) => !p.isRunning);
|
|
@@ -16292,7 +16346,7 @@ var InlineStatus = ({
|
|
|
16292
16346
|
running.length,
|
|
16293
16347
|
")"
|
|
16294
16348
|
] }),
|
|
16295
|
-
running.map((proc) => /* @__PURE__ */
|
|
16349
|
+
running.map((proc) => /* @__PURE__ */ jsx3(ProcessRow, { proc, isCompact }, proc.id))
|
|
16296
16350
|
] }),
|
|
16297
16351
|
stopped.length > 0 && !isCompact && /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", marginTop: running.length > 0 ? 1 : 0, children: [
|
|
16298
16352
|
/* @__PURE__ */ jsxs2(Text2, { color: THEME.gray, children: [
|
|
@@ -16301,7 +16355,7 @@ var InlineStatus = ({
|
|
|
16301
16355
|
stopped.length,
|
|
16302
16356
|
")"
|
|
16303
16357
|
] }),
|
|
16304
|
-
stopped.slice(0, TUI_DISPLAY_LIMITS.maxStoppedProcesses).map((proc) => /* @__PURE__ */
|
|
16358
|
+
stopped.slice(0, TUI_DISPLAY_LIMITS.maxStoppedProcesses).map((proc) => /* @__PURE__ */ jsx3(ProcessRow, { proc, isCompact }, proc.id)),
|
|
16305
16359
|
stopped.length > TUI_DISPLAY_LIMITS.maxStoppedProcesses && /* @__PURE__ */ jsxs2(Text2, { color: THEME.gray, children: [
|
|
16306
16360
|
" ... and ",
|
|
16307
16361
|
stopped.length - TUI_DISPLAY_LIMITS.maxStoppedProcesses,
|
|
@@ -16331,11 +16385,11 @@ var InlineStatus = ({
|
|
|
16331
16385
|
" orphaned children"
|
|
16332
16386
|
] })
|
|
16333
16387
|
] }, z.processId)),
|
|
16334
|
-
/* @__PURE__ */
|
|
16388
|
+
/* @__PURE__ */ jsx3(Text2, { color: THEME.gray, children: " Run /cleanup to terminate" })
|
|
16335
16389
|
] }),
|
|
16336
16390
|
/* @__PURE__ */ jsxs2(Box2, { marginTop: running.length > 0 ? 1 : 0, children: [
|
|
16337
|
-
/* @__PURE__ */
|
|
16338
|
-
/* @__PURE__ */
|
|
16391
|
+
/* @__PURE__ */ jsx3(Text2, { color: THEME.gray, children: "Health: " }),
|
|
16392
|
+
/* @__PURE__ */ jsx3(Text2, { color: healthColor, bold: true, children: health.toUpperCase() })
|
|
16339
16393
|
] })
|
|
16340
16394
|
] });
|
|
16341
16395
|
};
|
|
@@ -16343,7 +16397,7 @@ var InlineStatus = ({
|
|
|
16343
16397
|
// src/platform/tui/components/ToolCard.tsx
|
|
16344
16398
|
import { memo as memo2 } from "react";
|
|
16345
16399
|
import { Box as Box3, Text as Text3 } from "ink";
|
|
16346
|
-
import { Fragment as Fragment2, jsx as
|
|
16400
|
+
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
16347
16401
|
var ARGS_MAX = 72;
|
|
16348
16402
|
function truncate(s, max) {
|
|
16349
16403
|
return s.length > max ? s.slice(0, max - 1) + "\u2026" : s;
|
|
@@ -16388,12 +16442,12 @@ function parseToolContent(content) {
|
|
|
16388
16442
|
var ToolCard = memo2(({ content }) => {
|
|
16389
16443
|
const { name, args } = parseToolContent(content);
|
|
16390
16444
|
return /* @__PURE__ */ jsxs3(Box3, { children: [
|
|
16391
|
-
/* @__PURE__ */
|
|
16392
|
-
/* @__PURE__ */
|
|
16445
|
+
/* @__PURE__ */ jsx4(Text3, { color: THEME.primary, children: " \u2295 " }),
|
|
16446
|
+
/* @__PURE__ */ jsx4(Text3, { color: THEME.white, bold: true, children: name }),
|
|
16393
16447
|
args && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
16394
|
-
/* @__PURE__ */
|
|
16395
|
-
/* @__PURE__ */
|
|
16396
|
-
/* @__PURE__ */
|
|
16448
|
+
/* @__PURE__ */ jsx4(Text3, { color: THEME.dimGray, children: "(" }),
|
|
16449
|
+
/* @__PURE__ */ jsx4(Text3, { color: THEME.gray, children: args }),
|
|
16450
|
+
/* @__PURE__ */ jsx4(Text3, { color: THEME.dimGray, children: ")" })
|
|
16397
16451
|
] })
|
|
16398
16452
|
] });
|
|
16399
16453
|
});
|
|
@@ -16401,7 +16455,7 @@ var ToolCard = memo2(({ content }) => {
|
|
|
16401
16455
|
// src/platform/tui/components/MarkdownText.tsx
|
|
16402
16456
|
import { memo as memo3 } from "react";
|
|
16403
16457
|
import { Box as Box4, Text as Text4 } from "ink";
|
|
16404
|
-
import { Fragment as Fragment3, jsx as
|
|
16458
|
+
import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
16405
16459
|
function tokenizeLine(line) {
|
|
16406
16460
|
const tokens = [];
|
|
16407
16461
|
let i = 0;
|
|
@@ -16425,14 +16479,14 @@ function tokenizeLine(line) {
|
|
|
16425
16479
|
}
|
|
16426
16480
|
return tokens;
|
|
16427
16481
|
}
|
|
16428
|
-
var InlineContent = ({ tokens }) => /* @__PURE__ */
|
|
16482
|
+
var InlineContent = ({ tokens }) => /* @__PURE__ */ jsx5(Fragment3, { children: tokens.map((tok, i) => {
|
|
16429
16483
|
if (tok.type === "bold") {
|
|
16430
|
-
return /* @__PURE__ */
|
|
16484
|
+
return /* @__PURE__ */ jsx5(Text4, { bold: true, color: THEME.white, children: tok.value }, i);
|
|
16431
16485
|
}
|
|
16432
16486
|
if (tok.type === "code") {
|
|
16433
|
-
return /* @__PURE__ */
|
|
16487
|
+
return /* @__PURE__ */ jsx5(Text4, { color: THEME.cyan, children: `\`${tok.value}\`` }, i);
|
|
16434
16488
|
}
|
|
16435
|
-
return /* @__PURE__ */
|
|
16489
|
+
return /* @__PURE__ */ jsx5(Text4, { color: THEME.white, children: tok.value }, i);
|
|
16436
16490
|
}) });
|
|
16437
16491
|
function parseBlocks(lines) {
|
|
16438
16492
|
const blocks = [];
|
|
@@ -16482,12 +16536,12 @@ function parseBlocks(lines) {
|
|
|
16482
16536
|
}
|
|
16483
16537
|
var BlockRenderer = ({ block, blockIdx }) => {
|
|
16484
16538
|
if (block.type === "blank") {
|
|
16485
|
-
return /* @__PURE__ */
|
|
16539
|
+
return /* @__PURE__ */ jsx5(Text4, { children: " " }, blockIdx);
|
|
16486
16540
|
}
|
|
16487
16541
|
if (block.type === "heading") {
|
|
16488
16542
|
const prefixes = { 1: "\u25B8 ", 2: " \u25B9 ", 3: " \xB7 " };
|
|
16489
16543
|
const colors = { 1: THEME.primary, 2: THEME.cyan, 3: THEME.white };
|
|
16490
|
-
return /* @__PURE__ */
|
|
16544
|
+
return /* @__PURE__ */ jsx5(Box4, { children: /* @__PURE__ */ jsxs4(Text4, { color: colors[block.level], bold: true, children: [
|
|
16491
16545
|
prefixes[block.level],
|
|
16492
16546
|
block.content
|
|
16493
16547
|
] }) }, blockIdx);
|
|
@@ -16499,7 +16553,7 @@ var BlockRenderer = ({ block, blockIdx }) => {
|
|
|
16499
16553
|
bullet,
|
|
16500
16554
|
" "
|
|
16501
16555
|
] }),
|
|
16502
|
-
/* @__PURE__ */
|
|
16556
|
+
/* @__PURE__ */ jsx5(InlineContent, { tokens: tokenizeLine(block.content) })
|
|
16503
16557
|
] }, blockIdx);
|
|
16504
16558
|
}
|
|
16505
16559
|
if (block.type === "codeBlock") {
|
|
@@ -16512,19 +16566,19 @@ var BlockRenderer = ({ block, blockIdx }) => {
|
|
|
16512
16566
|
paddingX: 1,
|
|
16513
16567
|
marginY: 0,
|
|
16514
16568
|
children: [
|
|
16515
|
-
block.lang && /* @__PURE__ */
|
|
16516
|
-
block.lines.map((l, li) => /* @__PURE__ */
|
|
16569
|
+
block.lang && /* @__PURE__ */ jsx5(Text4, { color: THEME.dimGray, children: block.lang }),
|
|
16570
|
+
block.lines.map((l, li) => /* @__PURE__ */ jsx5(Text4, { color: THEME.cyan, children: l }, li))
|
|
16517
16571
|
]
|
|
16518
16572
|
},
|
|
16519
16573
|
blockIdx
|
|
16520
16574
|
);
|
|
16521
16575
|
}
|
|
16522
|
-
return /* @__PURE__ */
|
|
16576
|
+
return /* @__PURE__ */ jsx5(Box4, { children: /* @__PURE__ */ jsx5(InlineContent, { tokens: tokenizeLine(block.content) }) }, blockIdx);
|
|
16523
16577
|
};
|
|
16524
16578
|
var MarkdownText = memo3(({ content }) => {
|
|
16525
16579
|
const lines = content.split("\n");
|
|
16526
16580
|
const blocks = parseBlocks(lines);
|
|
16527
|
-
return /* @__PURE__ */
|
|
16581
|
+
return /* @__PURE__ */ jsx5(Box4, { flexDirection: "column", children: blocks.map((block, i) => /* @__PURE__ */ jsx5(BlockRenderer, { block, blockIdx: i }, i)) });
|
|
16528
16582
|
});
|
|
16529
16583
|
|
|
16530
16584
|
// src/platform/tui/components/messages/parseStatusContent.ts
|
|
@@ -16572,12 +16626,12 @@ function computeResultDisplay(content, isExpanded) {
|
|
|
16572
16626
|
}
|
|
16573
16627
|
|
|
16574
16628
|
// src/platform/tui/components/messages/MessageRow.tsx
|
|
16575
|
-
import { jsx as
|
|
16629
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
16576
16630
|
var MessageRow = memo4(({ msg, isExpanded }) => {
|
|
16577
16631
|
if (msg.type === "status") {
|
|
16578
16632
|
const statusData = parseStatusContent(msg.content);
|
|
16579
16633
|
if (statusData) {
|
|
16580
|
-
return /* @__PURE__ */
|
|
16634
|
+
return /* @__PURE__ */ jsx6(Box5, { flexDirection: "column", children: /* @__PURE__ */ jsx6(
|
|
16581
16635
|
InlineStatus,
|
|
16582
16636
|
{
|
|
16583
16637
|
processes: statusData.processes,
|
|
@@ -16587,15 +16641,15 @@ var MessageRow = memo4(({ msg, isExpanded }) => {
|
|
|
16587
16641
|
) }, msg.id);
|
|
16588
16642
|
}
|
|
16589
16643
|
return /* @__PURE__ */ jsxs5(Box5, { children: [
|
|
16590
|
-
/* @__PURE__ */
|
|
16591
|
-
/* @__PURE__ */
|
|
16644
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, color: THEME.dimGray, children: " \xB7 " }),
|
|
16645
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, color: THEME.gray, children: msg.content })
|
|
16592
16646
|
] }, msg.id);
|
|
16593
16647
|
}
|
|
16594
16648
|
if (msg.type === "thinking") {
|
|
16595
|
-
return /* @__PURE__ */
|
|
16649
|
+
return /* @__PURE__ */ jsx6(ThinkingBlock, { msg, isExpanded });
|
|
16596
16650
|
}
|
|
16597
16651
|
if (msg.type === "tool") {
|
|
16598
|
-
return /* @__PURE__ */
|
|
16652
|
+
return /* @__PURE__ */ jsx6(Box5, { children: /* @__PURE__ */ jsx6(ToolCard, { content: msg.content }) }, msg.id);
|
|
16599
16653
|
}
|
|
16600
16654
|
if (msg.type === "result") {
|
|
16601
16655
|
const kind = classifyResult(msg.content);
|
|
@@ -16605,19 +16659,19 @@ var MessageRow = memo4(({ msg, isExpanded }) => {
|
|
|
16605
16659
|
const isFailure = kind === "failure";
|
|
16606
16660
|
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
|
|
16607
16661
|
/* @__PURE__ */ jsxs5(Box5, { children: [
|
|
16608
|
-
/* @__PURE__ */
|
|
16609
|
-
/* @__PURE__ */
|
|
16610
|
-
hasMore && /* @__PURE__ */
|
|
16611
|
-
effectiveExpanded && hiddenCount > RESULT_PREVIEW_LINES && !isFailure && /* @__PURE__ */
|
|
16662
|
+
/* @__PURE__ */ jsx6(Text5, { color: THEME.dimGray, children: " \u2514 " }),
|
|
16663
|
+
/* @__PURE__ */ jsx6(Text5, { color, children: firstLine }),
|
|
16664
|
+
hasMore && /* @__PURE__ */ jsx6(Text5, { dimColor: true, color: THEME.dimGray, children: ` [+${hiddenCount - RESULT_PREVIEW_LINES} \xB7 T]` }),
|
|
16665
|
+
effectiveExpanded && hiddenCount > RESULT_PREVIEW_LINES && !isFailure && /* @__PURE__ */ jsx6(Text5, { dimColor: true, color: THEME.dimGray, children: " [T \u2193]" })
|
|
16612
16666
|
] }),
|
|
16613
16667
|
visibleRest.map((line, i) => /* @__PURE__ */ jsxs5(Box5, { children: [
|
|
16614
|
-
/* @__PURE__ */
|
|
16615
|
-
/* @__PURE__ */
|
|
16668
|
+
/* @__PURE__ */ jsx6(Text5, { color: THEME.dimGray, children: " " }),
|
|
16669
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, color: THEME.gray, children: line })
|
|
16616
16670
|
] }, i))
|
|
16617
16671
|
] }, msg.id);
|
|
16618
16672
|
}
|
|
16619
16673
|
if (msg.type === "ai" || msg.type === "assistant") {
|
|
16620
|
-
return /* @__PURE__ */
|
|
16674
|
+
return /* @__PURE__ */ jsx6(Box5, { flexDirection: "column", marginBottom: 0, children: /* @__PURE__ */ jsx6(MarkdownText, { content: msg.content }) }, msg.id);
|
|
16621
16675
|
}
|
|
16622
16676
|
if (msg.type === "error") {
|
|
16623
16677
|
const eLines = msg.content.split("\n");
|
|
@@ -16625,32 +16679,32 @@ var MessageRow = memo4(({ msg, isExpanded }) => {
|
|
|
16625
16679
|
const eHidden = eLines.length - 1;
|
|
16626
16680
|
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
|
|
16627
16681
|
/* @__PURE__ */ jsxs5(Box5, { children: [
|
|
16628
|
-
/* @__PURE__ */
|
|
16629
|
-
/* @__PURE__ */
|
|
16630
|
-
!isExpanded && eHidden > 0 && /* @__PURE__ */
|
|
16631
|
-
isExpanded && eHidden > 0 && /* @__PURE__ */
|
|
16682
|
+
/* @__PURE__ */ jsx6(Text5, { color: THEME.red, children: " \u2717 " }),
|
|
16683
|
+
/* @__PURE__ */ jsx6(Text5, { color: THEME.red, children: eFirst }),
|
|
16684
|
+
!isExpanded && eHidden > 0 && /* @__PURE__ */ jsx6(Text5, { dimColor: true, color: THEME.dimGray, children: ` [+${eHidden} \xB7 E]` }),
|
|
16685
|
+
isExpanded && eHidden > 0 && /* @__PURE__ */ jsx6(Text5, { dimColor: true, color: THEME.dimGray, children: " [E \u2191]" })
|
|
16632
16686
|
] }),
|
|
16633
16687
|
isExpanded && eLines.slice(1).map((line, i) => /* @__PURE__ */ jsxs5(Box5, { children: [
|
|
16634
|
-
/* @__PURE__ */
|
|
16635
|
-
/* @__PURE__ */
|
|
16688
|
+
/* @__PURE__ */ jsx6(Text5, { color: THEME.dimGray, children: " " }),
|
|
16689
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, color: THEME.red, children: line })
|
|
16636
16690
|
] }, i))
|
|
16637
16691
|
] }, msg.id);
|
|
16638
16692
|
}
|
|
16639
16693
|
if (msg.type === "user") {
|
|
16640
16694
|
return /* @__PURE__ */ jsxs5(Box5, { children: [
|
|
16641
|
-
/* @__PURE__ */
|
|
16642
|
-
/* @__PURE__ */
|
|
16695
|
+
/* @__PURE__ */ jsx6(Text5, { color: THEME.primary, children: "\u276F " }),
|
|
16696
|
+
/* @__PURE__ */ jsx6(Text5, { color: THEME.white, bold: true, children: msg.content })
|
|
16643
16697
|
] }, msg.id);
|
|
16644
16698
|
}
|
|
16645
16699
|
if (msg.type === "system") {
|
|
16646
16700
|
return /* @__PURE__ */ jsxs5(Box5, { children: [
|
|
16647
|
-
/* @__PURE__ */
|
|
16648
|
-
/* @__PURE__ */
|
|
16701
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, color: THEME.dimGray, children: " \xB7 " }),
|
|
16702
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, color: THEME.gray, children: msg.content })
|
|
16649
16703
|
] }, msg.id);
|
|
16650
16704
|
}
|
|
16651
16705
|
return /* @__PURE__ */ jsxs5(Box5, { children: [
|
|
16652
|
-
/* @__PURE__ */
|
|
16653
|
-
/* @__PURE__ */
|
|
16706
|
+
/* @__PURE__ */ jsx6(Text5, { dimColor: true, color: THEME.dimGray, children: " \xB7 " }),
|
|
16707
|
+
/* @__PURE__ */ jsx6(Text5, { color: MESSAGE_STYLES.colors[msg.type] ?? THEME.gray, children: msg.content })
|
|
16654
16708
|
] }, msg.id);
|
|
16655
16709
|
});
|
|
16656
16710
|
|
|
@@ -16659,60 +16713,38 @@ import { memo as memo6 } from "react";
|
|
|
16659
16713
|
import { Box as Box7, Text as Text7 } from "ink";
|
|
16660
16714
|
|
|
16661
16715
|
// src/platform/tui/components/ShimmerBanner.tsx
|
|
16662
|
-
import {
|
|
16716
|
+
import { memo as memo5 } from "react";
|
|
16663
16717
|
import { Box as Box6, Text as Text6 } from "ink";
|
|
16664
|
-
import { jsx as
|
|
16665
|
-
var FRAME_INTERVAL = 60;
|
|
16666
|
-
var WAVE_SPEED = 0.22;
|
|
16667
|
-
var CHAR_GAP = 0.18;
|
|
16668
|
-
var ROW_GAP = 1.6;
|
|
16669
|
-
function waveColor(sin) {
|
|
16670
|
-
const t = (sin + 1) / 2;
|
|
16671
|
-
const r = Math.round(36 + t * (255 - 36));
|
|
16672
|
-
const g = Math.round(150 + t * (255 - 150));
|
|
16673
|
-
const b = Math.round(237 + t * (255 - 237));
|
|
16674
|
-
return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
|
|
16675
|
-
}
|
|
16718
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
16676
16719
|
var ShimmerBanner = memo5(({ banner }) => {
|
|
16677
|
-
const [tick, setTick] = useState3(0);
|
|
16678
|
-
useEffect5(() => {
|
|
16679
|
-
const timer = setInterval(() => setTick((t) => t + 1), FRAME_INTERVAL);
|
|
16680
|
-
return () => clearInterval(timer);
|
|
16681
|
-
}, []);
|
|
16682
|
-
const globalPhase = tick * WAVE_SPEED;
|
|
16683
16720
|
const lines = banner.split("\n").filter((l) => l.length > 0);
|
|
16684
|
-
return /* @__PURE__ */
|
|
16685
|
-
const phase = globalPhase - col * CHAR_GAP - row * ROW_GAP;
|
|
16686
|
-
const sin = Math.sin(phase);
|
|
16687
|
-
const color = char.trim() === "" ? HEX.primary : waveColor(sin);
|
|
16688
|
-
return /* @__PURE__ */ jsx6(Text6, { color, children: char }, col);
|
|
16689
|
-
}) }, row)) });
|
|
16721
|
+
return /* @__PURE__ */ jsx7(Box6, { flexDirection: "column", children: lines.map((line, row) => /* @__PURE__ */ jsx7(Text6, { color: HEX.primary, children: line }, row)) });
|
|
16690
16722
|
});
|
|
16691
16723
|
|
|
16692
16724
|
// src/platform/tui/components/messages/EmptyState.tsx
|
|
16693
|
-
import { jsx as
|
|
16725
|
+
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
16694
16726
|
var EmptyState = memo6(({ modelName, autoApproveMode, version }) => {
|
|
16695
16727
|
const autoLabel = autoApproveMode ? "ON" : "OFF";
|
|
16696
16728
|
const autoColor = autoApproveMode ? THEME.primary : THEME.gray;
|
|
16697
16729
|
return /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", paddingX: 1, paddingY: 1, children: [
|
|
16698
|
-
/* @__PURE__ */
|
|
16699
|
-
/* @__PURE__ */
|
|
16730
|
+
/* @__PURE__ */ jsx8(ShimmerBanner, { banner: ASCII_BANNER }),
|
|
16731
|
+
/* @__PURE__ */ jsx8(Text7, { children: " " }),
|
|
16700
16732
|
/* @__PURE__ */ jsxs6(Box7, { gap: 2, children: [
|
|
16701
|
-
/* @__PURE__ */
|
|
16702
|
-
version && /* @__PURE__ */
|
|
16733
|
+
/* @__PURE__ */ jsx8(Text7, { color: THEME.primary, bold: true, children: "\u25C8 Pentesting" }),
|
|
16734
|
+
version && /* @__PURE__ */ jsx8(Text7, { color: THEME.dimGray, children: `v${version}` }),
|
|
16703
16735
|
modelName && /* @__PURE__ */ jsxs6(Text7, { color: THEME.dimGray, children: [
|
|
16704
16736
|
"\xB7",
|
|
16705
16737
|
" ",
|
|
16706
|
-
/* @__PURE__ */
|
|
16738
|
+
/* @__PURE__ */ jsx8(Text7, { color: THEME.gray, children: modelName })
|
|
16707
16739
|
] }),
|
|
16708
16740
|
/* @__PURE__ */ jsxs6(Text7, { color: THEME.dimGray, children: [
|
|
16709
16741
|
"\xB7",
|
|
16710
16742
|
" Auto: ",
|
|
16711
|
-
/* @__PURE__ */
|
|
16743
|
+
/* @__PURE__ */ jsx8(Text7, { color: autoColor, children: autoLabel })
|
|
16712
16744
|
] })
|
|
16713
16745
|
] }),
|
|
16714
|
-
/* @__PURE__ */
|
|
16715
|
-
/* @__PURE__ */
|
|
16746
|
+
/* @__PURE__ */ jsx8(Text7, { children: " " }),
|
|
16747
|
+
/* @__PURE__ */ jsx8(Text7, { color: THEME.gray, children: " Get started:" }),
|
|
16716
16748
|
/* @__PURE__ */ jsxs6(Text7, { color: THEME.gray, children: [
|
|
16717
16749
|
" ",
|
|
16718
16750
|
" ",
|
|
@@ -16725,17 +16757,17 @@ var EmptyState = memo6(({ modelName, autoApproveMode, version }) => {
|
|
|
16725
16757
|
/* @__PURE__ */ jsxs6(Text7, { color: THEME.gray, children: [
|
|
16726
16758
|
" ",
|
|
16727
16759
|
" ",
|
|
16728
|
-
/* @__PURE__ */
|
|
16760
|
+
/* @__PURE__ */ jsx8(Text7, { color: THEME.white, children: "/start" }),
|
|
16729
16761
|
" \u2014 Begin autonomous pentest"
|
|
16730
16762
|
] }),
|
|
16731
16763
|
/* @__PURE__ */ jsxs6(Text7, { color: THEME.gray, children: [
|
|
16732
16764
|
" ",
|
|
16733
16765
|
" ",
|
|
16734
|
-
/* @__PURE__ */
|
|
16766
|
+
/* @__PURE__ */ jsx8(Text7, { color: THEME.white, children: "/help" }),
|
|
16735
16767
|
" \u2014 Show all commands"
|
|
16736
16768
|
] }),
|
|
16737
|
-
/* @__PURE__ */
|
|
16738
|
-
/* @__PURE__ */
|
|
16769
|
+
/* @__PURE__ */ jsx8(Text7, { children: " " }),
|
|
16770
|
+
/* @__PURE__ */ jsx8(Text7, { color: THEME.dimGray, children: " Or just type a task and press Enter." })
|
|
16739
16771
|
] });
|
|
16740
16772
|
});
|
|
16741
16773
|
|
|
@@ -16750,7 +16782,7 @@ function computeSlidingWindow(messages, scrollOffset) {
|
|
|
16750
16782
|
}
|
|
16751
16783
|
|
|
16752
16784
|
// src/platform/tui/components/MessageList.tsx
|
|
16753
|
-
import { jsx as
|
|
16785
|
+
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
16754
16786
|
var MessageList = memo7(({ messages, isModalOpen, modelName, autoApproveMode, version, scrollOffset = 0 }) => {
|
|
16755
16787
|
const [expandedIds, setExpandedIds] = useState4(/* @__PURE__ */ new Set());
|
|
16756
16788
|
const messagesRef = useRef6(messages);
|
|
@@ -16806,7 +16838,7 @@ var MessageList = memo7(({ messages, isModalOpen, modelName, autoApproveMode, ve
|
|
|
16806
16838
|
}
|
|
16807
16839
|
}, []));
|
|
16808
16840
|
if (messages.length === 0) {
|
|
16809
|
-
return /* @__PURE__ */
|
|
16841
|
+
return /* @__PURE__ */ jsx9(
|
|
16810
16842
|
EmptyState,
|
|
16811
16843
|
{
|
|
16812
16844
|
modelName,
|
|
@@ -16817,8 +16849,8 @@ var MessageList = memo7(({ messages, isModalOpen, modelName, autoApproveMode, ve
|
|
|
16817
16849
|
}
|
|
16818
16850
|
const { visibleMessages, hiddenAbove, clampedOffset } = computeSlidingWindow(messages, scrollOffset);
|
|
16819
16851
|
return /* @__PURE__ */ jsxs7(Box8, { flexDirection: "column", children: [
|
|
16820
|
-
clampedOffset > 0 && /* @__PURE__ */
|
|
16821
|
-
visibleMessages.map((msg) => /* @__PURE__ */
|
|
16852
|
+
clampedOffset > 0 && /* @__PURE__ */ jsx9(Box8, { paddingX: 1, children: /* @__PURE__ */ jsx9(Text8, { dimColor: true, color: THEME.dimGray, children: `\u2191 ${hiddenAbove} message${hiddenAbove !== 1 ? "s" : ""} above \xB7 PgDn to scroll down` }) }),
|
|
16853
|
+
visibleMessages.map((msg) => /* @__PURE__ */ jsx9(
|
|
16822
16854
|
MessageRow,
|
|
16823
16855
|
{
|
|
16824
16856
|
msg,
|
|
@@ -16861,10 +16893,10 @@ var useStatusTimer = (currentStatus, isProcessing) => {
|
|
|
16861
16893
|
// src/platform/tui/components/status/RetryView.tsx
|
|
16862
16894
|
import { Box as Box9, Text as Text10 } from "ink";
|
|
16863
16895
|
|
|
16864
|
-
// src/platform/tui/components/
|
|
16865
|
-
import {
|
|
16896
|
+
// src/platform/tui/components/StarSpinner.tsx
|
|
16897
|
+
import { memo as memo8 } from "react";
|
|
16866
16898
|
import { Text as Text9 } from "ink";
|
|
16867
|
-
import { jsx as
|
|
16899
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
16868
16900
|
var FRAMES = [
|
|
16869
16901
|
"\xB7",
|
|
16870
16902
|
"\u2726",
|
|
@@ -16881,27 +16913,21 @@ var FRAMES = [
|
|
|
16881
16913
|
"\u2727",
|
|
16882
16914
|
"\u2726"
|
|
16883
16915
|
];
|
|
16884
|
-
var
|
|
16885
|
-
|
|
16886
|
-
const
|
|
16887
|
-
|
|
16888
|
-
const timer = setInterval(() => {
|
|
16889
|
-
setIndex((i) => (i + 1) % FRAMES.length);
|
|
16890
|
-
}, INTERVAL);
|
|
16891
|
-
return () => clearInterval(timer);
|
|
16892
|
-
}, []);
|
|
16893
|
-
return /* @__PURE__ */ jsx9(Text9, { color: color || "yellow", children: FRAMES[index] });
|
|
16916
|
+
var StarSpinner = memo8(({ color }) => {
|
|
16917
|
+
const tick = useAnimationTick();
|
|
16918
|
+
const index = tick % FRAMES.length;
|
|
16919
|
+
return /* @__PURE__ */ jsx10(Text9, { color: color || "yellow", children: FRAMES[index] });
|
|
16894
16920
|
});
|
|
16895
16921
|
|
|
16896
16922
|
// src/platform/tui/components/status/RetryView.tsx
|
|
16897
|
-
import { jsx as
|
|
16923
|
+
import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
16898
16924
|
var RetryView = ({ retryState }) => {
|
|
16899
16925
|
const truncateError = (err) => {
|
|
16900
16926
|
return err.length > DISPLAY_LIMITS.RETRY_ERROR_PREVIEW ? err.substring(0, DISPLAY_LIMITS.RETRY_ERROR_TRUNCATED) + "..." : err;
|
|
16901
16927
|
};
|
|
16902
16928
|
return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", height: 2, children: [
|
|
16903
16929
|
/* @__PURE__ */ jsxs8(Box9, { children: [
|
|
16904
|
-
/* @__PURE__ */
|
|
16930
|
+
/* @__PURE__ */ jsx11(Text10, { color: THEME.yellow, wrap: "truncate", children: /* @__PURE__ */ jsx11(StarSpinner, { color: THEME.yellow }) }),
|
|
16905
16931
|
/* @__PURE__ */ jsxs8(Text10, { color: THEME.yellow, bold: true, wrap: "truncate", children: [
|
|
16906
16932
|
" \u29F3 Retry #",
|
|
16907
16933
|
retryState.attempt,
|
|
@@ -16914,7 +16940,7 @@ var RetryView = ({ retryState }) => {
|
|
|
16914
16940
|
"s"
|
|
16915
16941
|
] })
|
|
16916
16942
|
] }),
|
|
16917
|
-
/* @__PURE__ */
|
|
16943
|
+
/* @__PURE__ */ jsx11(Box9, { children: /* @__PURE__ */ jsxs8(Text10, { color: THEME.gray, wrap: "truncate", children: [
|
|
16918
16944
|
" ",
|
|
16919
16945
|
truncateError(retryState.error)
|
|
16920
16946
|
] }) })
|
|
@@ -16925,11 +16951,10 @@ var RetryView = ({ retryState }) => {
|
|
|
16925
16951
|
import { Box as Box10, Text as Text12 } from "ink";
|
|
16926
16952
|
|
|
16927
16953
|
// src/platform/tui/components/ShimmerText.tsx
|
|
16928
|
-
import {
|
|
16954
|
+
import { memo as memo9 } from "react";
|
|
16929
16955
|
import { Text as Text11 } from "ink";
|
|
16930
|
-
import { jsx as
|
|
16931
|
-
var
|
|
16932
|
-
var WAVE_SPEED2 = 0.25;
|
|
16956
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
16957
|
+
var WAVE_SPEED = 0.25 * (120 / ANIM_TICK_MS);
|
|
16933
16958
|
var CHAR_PHASE_GAP = 0.55;
|
|
16934
16959
|
function sinToColor(sin) {
|
|
16935
16960
|
const t = (sin + 1) / 2;
|
|
@@ -16938,24 +16963,18 @@ function sinToColor(sin) {
|
|
|
16938
16963
|
return `#${hex}${hex}${hex}`;
|
|
16939
16964
|
}
|
|
16940
16965
|
var ShimmerText = memo9(({ children, bold, phase = 0 }) => {
|
|
16941
|
-
const
|
|
16942
|
-
|
|
16943
|
-
|
|
16944
|
-
setTick((t) => t + 1);
|
|
16945
|
-
}, FRAME_INTERVAL2);
|
|
16946
|
-
return () => clearInterval(timer);
|
|
16947
|
-
}, []);
|
|
16948
|
-
const globalPhase = tick * WAVE_SPEED2 + phase;
|
|
16949
|
-
return /* @__PURE__ */ jsx11(Text11, { bold, children: Array.from(children).map((char, i) => {
|
|
16966
|
+
const tick = useAnimationTick();
|
|
16967
|
+
const globalPhase = tick * WAVE_SPEED + phase;
|
|
16968
|
+
return /* @__PURE__ */ jsx12(Text11, { bold, children: Array.from(children).map((char, i) => {
|
|
16950
16969
|
const charPhase = globalPhase - i * CHAR_PHASE_GAP;
|
|
16951
16970
|
const sin = Math.sin(charPhase);
|
|
16952
16971
|
const color = sinToColor(sin);
|
|
16953
|
-
return /* @__PURE__ */
|
|
16972
|
+
return /* @__PURE__ */ jsx12(Text11, { color, children: char }, i);
|
|
16954
16973
|
}) });
|
|
16955
16974
|
});
|
|
16956
16975
|
|
|
16957
16976
|
// src/platform/tui/components/status/ProcessingView.tsx
|
|
16958
|
-
import { jsx as
|
|
16977
|
+
import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
16959
16978
|
var ProcessingView = ({
|
|
16960
16979
|
statusMain,
|
|
16961
16980
|
detailText,
|
|
@@ -16971,41 +16990,53 @@ var ProcessingView = ({
|
|
|
16971
16990
|
return parts.length > 0 ? `(${parts.join(" \xB7 ")})` : "";
|
|
16972
16991
|
};
|
|
16973
16992
|
const meta = buildMeta();
|
|
16993
|
+
const parenIdx = statusMain.indexOf("(");
|
|
16994
|
+
const shimmerPart = parenIdx > -1 ? statusMain.slice(0, parenIdx).trimEnd() : statusMain;
|
|
16995
|
+
const staticSuffix = parenIdx > -1 ? " " + statusMain.slice(parenIdx) : "";
|
|
16974
16996
|
return /* @__PURE__ */ jsxs9(Box10, { flexDirection: "column", height: 2, children: [
|
|
16975
16997
|
/* @__PURE__ */ jsxs9(Box10, { children: [
|
|
16976
|
-
/* @__PURE__ */
|
|
16977
|
-
/* @__PURE__ */
|
|
16978
|
-
/* @__PURE__ */
|
|
16998
|
+
/* @__PURE__ */ jsx13(Text12, { color, wrap: "truncate", children: /* @__PURE__ */ jsx13(StarSpinner, { color }) }),
|
|
16999
|
+
/* @__PURE__ */ jsx13(Text12, { children: " " }),
|
|
17000
|
+
/* @__PURE__ */ jsx13(ShimmerText, { bold: true, phase: 0, children: shimmerPart }),
|
|
17001
|
+
staticSuffix ? /* @__PURE__ */ jsx13(Text12, { color: THEME.dimGray, wrap: "truncate", children: staticSuffix }) : null,
|
|
16979
17002
|
/* @__PURE__ */ jsxs9(Text12, { color: THEME.dimGray, wrap: "truncate", children: [
|
|
16980
17003
|
" ",
|
|
16981
17004
|
meta
|
|
16982
17005
|
] })
|
|
16983
17006
|
] }),
|
|
16984
|
-
/* @__PURE__ */
|
|
17007
|
+
/* @__PURE__ */ jsx13(Box10, { children: detailText ? /* @__PURE__ */ jsxs9(Text12, { color: THEME.dimGray, wrap: "truncate", children: [
|
|
16985
17008
|
" ",
|
|
16986
17009
|
detailText
|
|
16987
|
-
] }) : /* @__PURE__ */
|
|
17010
|
+
] }) : /* @__PURE__ */ jsx13(Text12, { children: " " }) })
|
|
16988
17011
|
] });
|
|
16989
17012
|
};
|
|
16990
17013
|
|
|
16991
17014
|
// src/platform/tui/components/StatusDisplay.tsx
|
|
16992
|
-
import { jsx as
|
|
17015
|
+
import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
16993
17016
|
var StatusDisplay = memo10(({
|
|
16994
17017
|
retryState,
|
|
16995
17018
|
isProcessing,
|
|
16996
17019
|
currentStatus,
|
|
16997
|
-
currentTokens
|
|
17020
|
+
currentTokens,
|
|
17021
|
+
inputRequest
|
|
16998
17022
|
}) => {
|
|
16999
|
-
const
|
|
17023
|
+
const isWaitingForInput = inputRequest?.status === "active";
|
|
17024
|
+
const statusElapsed = useStatusTimer(currentStatus, isProcessing && !isWaitingForInput);
|
|
17000
17025
|
if (retryState && retryState.status === "retrying") {
|
|
17001
|
-
return /* @__PURE__ */
|
|
17026
|
+
return /* @__PURE__ */ jsx14(RetryView, { retryState });
|
|
17027
|
+
}
|
|
17028
|
+
if (isProcessing && isWaitingForInput) {
|
|
17029
|
+
return /* @__PURE__ */ jsxs10(Box11, { flexDirection: "column", height: 2, children: [
|
|
17030
|
+
/* @__PURE__ */ jsx14(Text13, { children: " " }),
|
|
17031
|
+
/* @__PURE__ */ jsx14(Text13, { children: " " })
|
|
17032
|
+
] });
|
|
17002
17033
|
}
|
|
17003
17034
|
if (isProcessing) {
|
|
17004
17035
|
const isThinkingStatus = currentStatus.startsWith("Reasoning");
|
|
17005
17036
|
const statusLines = currentStatus ? currentStatus.split("\n").filter(Boolean) : [];
|
|
17006
17037
|
const statusMain = statusLines[0] || "Processing...";
|
|
17007
17038
|
const detailText = isThinkingStatus && statusLines.length > 1 ? statusLines[statusLines.length - 1].slice(0, 120) : "";
|
|
17008
|
-
return /* @__PURE__ */
|
|
17039
|
+
return /* @__PURE__ */ jsx14(
|
|
17009
17040
|
ProcessingView,
|
|
17010
17041
|
{
|
|
17011
17042
|
statusMain,
|
|
@@ -17017,37 +17048,37 @@ var StatusDisplay = memo10(({
|
|
|
17017
17048
|
);
|
|
17018
17049
|
}
|
|
17019
17050
|
return /* @__PURE__ */ jsxs10(Box11, { flexDirection: "column", height: 2, children: [
|
|
17020
|
-
/* @__PURE__ */
|
|
17021
|
-
/* @__PURE__ */
|
|
17051
|
+
/* @__PURE__ */ jsx14(Text13, { children: " " }),
|
|
17052
|
+
/* @__PURE__ */ jsx14(Text13, { children: " " })
|
|
17022
17053
|
] });
|
|
17023
17054
|
});
|
|
17024
17055
|
|
|
17025
17056
|
// src/platform/tui/components/ChatInput.tsx
|
|
17026
|
-
import { useMemo, useCallback as useCallback9, useRef as useRef8, memo as memo11, useState as
|
|
17057
|
+
import { useMemo, useCallback as useCallback9, useRef as useRef8, memo as memo11, useState as useState6, useEffect as useEffect7 } from "react";
|
|
17027
17058
|
import { Box as Box15, Text as Text17, useInput as useInput3 } from "ink";
|
|
17028
17059
|
|
|
17029
17060
|
// src/platform/tui/components/input/AutocompletePreview.tsx
|
|
17030
17061
|
import { Box as Box12, Text as Text14 } from "ink";
|
|
17031
|
-
import { jsx as
|
|
17062
|
+
import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
17032
17063
|
var AutocompletePreview = ({
|
|
17033
17064
|
suggestions,
|
|
17034
17065
|
clampedIdx
|
|
17035
17066
|
}) => {
|
|
17036
|
-
return /* @__PURE__ */
|
|
17067
|
+
return /* @__PURE__ */ jsx15(Box12, { flexDirection: "column", paddingX: 1, children: suggestions.map((cmd, i) => {
|
|
17037
17068
|
const isSelected = i === clampedIdx;
|
|
17038
17069
|
const argsText = cmd.args ? ` ${cmd.args}` : "";
|
|
17039
17070
|
return /* @__PURE__ */ jsxs11(Box12, { children: [
|
|
17040
|
-
/* @__PURE__ */
|
|
17071
|
+
/* @__PURE__ */ jsx15(Text14, { color: isSelected ? THEME.primary : THEME.dimGray, children: isSelected ? " \u276F " : " " }),
|
|
17041
17072
|
/* @__PURE__ */ jsxs11(Text14, { color: isSelected ? THEME.white : THEME.gray, bold: isSelected, children: [
|
|
17042
17073
|
"/",
|
|
17043
17074
|
cmd.name
|
|
17044
17075
|
] }),
|
|
17045
|
-
/* @__PURE__ */
|
|
17076
|
+
/* @__PURE__ */ jsx15(Text14, { dimColor: true, color: THEME.gray, children: argsText }),
|
|
17046
17077
|
/* @__PURE__ */ jsxs11(Text14, { dimColor: true, color: THEME.dimGray, children: [
|
|
17047
17078
|
" \u2014 ",
|
|
17048
17079
|
cmd.description
|
|
17049
17080
|
] }),
|
|
17050
|
-
isSelected && cmd.alias && /* @__PURE__ */
|
|
17081
|
+
isSelected && cmd.alias && /* @__PURE__ */ jsx15(Text14, { dimColor: true, color: THEME.dimGray, children: ` (/${cmd.alias})` })
|
|
17051
17082
|
] }, cmd.name);
|
|
17052
17083
|
}) });
|
|
17053
17084
|
};
|
|
@@ -17055,7 +17086,7 @@ var AutocompletePreview = ({
|
|
|
17055
17086
|
// src/platform/tui/components/input/SecretInputArea.tsx
|
|
17056
17087
|
import { Box as Box13, Text as Text15, useStdout } from "ink";
|
|
17057
17088
|
import TextInput from "ink-text-input";
|
|
17058
|
-
import { jsx as
|
|
17089
|
+
import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
17059
17090
|
var OUTER_PADDING = 2;
|
|
17060
17091
|
var SecretInputArea = ({
|
|
17061
17092
|
inputRequest,
|
|
@@ -17067,34 +17098,28 @@ var SecretInputArea = ({
|
|
|
17067
17098
|
const borderWidth = Math.max(10, (stdout?.columns ?? 80) - OUTER_PADDING);
|
|
17068
17099
|
const borderLine = "\u2501".repeat(borderWidth);
|
|
17069
17100
|
return /* @__PURE__ */ jsxs12(Box13, { flexDirection: "column", children: [
|
|
17070
|
-
/* @__PURE__ */
|
|
17071
|
-
/* @__PURE__ */ jsxs12(Box13, {
|
|
17072
|
-
/* @__PURE__ */
|
|
17073
|
-
|
|
17074
|
-
|
|
17075
|
-
|
|
17076
|
-
|
|
17077
|
-
|
|
17078
|
-
|
|
17079
|
-
|
|
17080
|
-
|
|
17081
|
-
|
|
17082
|
-
|
|
17083
|
-
onSubmit: onSecretSubmit,
|
|
17084
|
-
placeholder: "(type and press Enter)",
|
|
17085
|
-
mask: inputRequest.isPassword ? "\u2022" : void 0
|
|
17086
|
-
}
|
|
17087
|
-
)
|
|
17088
|
-
] })
|
|
17101
|
+
/* @__PURE__ */ jsx16(Box13, { children: /* @__PURE__ */ jsx16(Text15, { color: THEME.yellow, children: borderLine }) }),
|
|
17102
|
+
/* @__PURE__ */ jsxs12(Box13, { paddingX: 1, children: [
|
|
17103
|
+
/* @__PURE__ */ jsx16(Text15, { color: THEME.yellow, bold: true, children: "\u25B8 " }),
|
|
17104
|
+
/* @__PURE__ */ jsx16(
|
|
17105
|
+
TextInput,
|
|
17106
|
+
{
|
|
17107
|
+
value: secretInput,
|
|
17108
|
+
onChange: setSecretInput,
|
|
17109
|
+
onSubmit: onSecretSubmit,
|
|
17110
|
+
placeholder: inputRequest.isPassword ? "(hidden \xB7 press Enter)" : "(type and press Enter)",
|
|
17111
|
+
mask: inputRequest.isPassword ? "\u2022" : void 0
|
|
17112
|
+
}
|
|
17113
|
+
)
|
|
17089
17114
|
] }),
|
|
17090
|
-
/* @__PURE__ */
|
|
17115
|
+
/* @__PURE__ */ jsx16(Box13, { children: /* @__PURE__ */ jsx16(Text15, { color: THEME.yellow, children: borderLine }) })
|
|
17091
17116
|
] });
|
|
17092
17117
|
};
|
|
17093
17118
|
|
|
17094
17119
|
// src/platform/tui/components/input/NormalInputArea.tsx
|
|
17095
17120
|
import { Box as Box14, Text as Text16, useStdout as useStdout2 } from "ink";
|
|
17096
17121
|
import TextInput2 from "ink-text-input";
|
|
17097
|
-
import { jsx as
|
|
17122
|
+
import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
17098
17123
|
var OUTER_PADDING2 = 2;
|
|
17099
17124
|
var NormalInputArea = ({
|
|
17100
17125
|
inputKey,
|
|
@@ -17107,10 +17132,10 @@ var NormalInputArea = ({
|
|
|
17107
17132
|
const borderWidth = Math.max(10, (stdout?.columns ?? 80) - OUTER_PADDING2);
|
|
17108
17133
|
const borderLine = "\u2500".repeat(borderWidth);
|
|
17109
17134
|
return /* @__PURE__ */ jsxs13(Box14, { flexDirection: "column", children: [
|
|
17110
|
-
/* @__PURE__ */
|
|
17135
|
+
/* @__PURE__ */ jsx17(Box14, { children: /* @__PURE__ */ jsx17(Text16, { dimColor: true, color: THEME.dimGray, children: borderLine }) }),
|
|
17111
17136
|
/* @__PURE__ */ jsxs13(Box14, { paddingX: 1, children: [
|
|
17112
|
-
/* @__PURE__ */
|
|
17113
|
-
/* @__PURE__ */
|
|
17137
|
+
/* @__PURE__ */ jsx17(Text16, { color: THEME.primary, children: "\u276F " }),
|
|
17138
|
+
/* @__PURE__ */ jsx17(
|
|
17114
17139
|
TextInput2,
|
|
17115
17140
|
{
|
|
17116
17141
|
value,
|
|
@@ -17121,12 +17146,12 @@ var NormalInputArea = ({
|
|
|
17121
17146
|
inputKey
|
|
17122
17147
|
)
|
|
17123
17148
|
] }),
|
|
17124
|
-
/* @__PURE__ */
|
|
17149
|
+
/* @__PURE__ */ jsx17(Box14, { children: /* @__PURE__ */ jsx17(Text16, { dimColor: true, color: THEME.dimGray, children: borderLine }) })
|
|
17125
17150
|
] });
|
|
17126
17151
|
};
|
|
17127
17152
|
|
|
17128
17153
|
// src/platform/tui/components/ChatInput.tsx
|
|
17129
|
-
import { jsx as
|
|
17154
|
+
import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
17130
17155
|
var MAX_SUGGESTIONS = 6;
|
|
17131
17156
|
var ChatInput = memo11(({
|
|
17132
17157
|
value,
|
|
@@ -17146,7 +17171,7 @@ var ChatInput = memo11(({
|
|
|
17146
17171
|
return getMatchingCommands(partialCmd).slice(0, MAX_SUGGESTIONS);
|
|
17147
17172
|
}, [isSlashMode, partialCmd, hasArgs]);
|
|
17148
17173
|
const showPreview = isSlashMode && !hasArgs && suggestions.length > 0;
|
|
17149
|
-
const [selectedIdx, setSelectedIdx] =
|
|
17174
|
+
const [selectedIdx, setSelectedIdx] = useState6(0);
|
|
17150
17175
|
const clampedIdx = Math.min(selectedIdx, Math.max(0, suggestions.length - 1));
|
|
17151
17176
|
const selectedIdxRef = useRef8(clampedIdx);
|
|
17152
17177
|
selectedIdxRef.current = clampedIdx;
|
|
@@ -17162,10 +17187,10 @@ var ChatInput = memo11(({
|
|
|
17162
17187
|
inputRequestRef.current = inputRequest;
|
|
17163
17188
|
const onChangeRef = useRef8(onChange);
|
|
17164
17189
|
onChangeRef.current = onChange;
|
|
17165
|
-
const [pastedHint, setPastedHint] =
|
|
17190
|
+
const [pastedHint, setPastedHint] = useState6(null);
|
|
17166
17191
|
const prevValueRef = useRef8(value);
|
|
17167
17192
|
const pasteTimerRef = useRef8(null);
|
|
17168
|
-
|
|
17193
|
+
useEffect7(() => {
|
|
17169
17194
|
const diff = value.length - prevValueRef.current.length;
|
|
17170
17195
|
if (diff > 20) {
|
|
17171
17196
|
if (pasteTimerRef.current) clearTimeout(pasteTimerRef.current);
|
|
@@ -17177,7 +17202,7 @@ var ChatInput = memo11(({
|
|
|
17177
17202
|
if (pasteTimerRef.current) clearTimeout(pasteTimerRef.current);
|
|
17178
17203
|
};
|
|
17179
17204
|
}, [value]);
|
|
17180
|
-
const [inputKey, setInputKey] =
|
|
17205
|
+
const [inputKey, setInputKey] = useState6(0);
|
|
17181
17206
|
const completeCommand = useCallback9((idx) => {
|
|
17182
17207
|
const sug = suggestionsRef.current;
|
|
17183
17208
|
if (!sug.length) return;
|
|
@@ -17226,7 +17251,7 @@ var ChatInput = memo11(({
|
|
|
17226
17251
|
}
|
|
17227
17252
|
}, [completeCommand]));
|
|
17228
17253
|
return /* @__PURE__ */ jsxs14(Box15, { flexDirection: "column", children: [
|
|
17229
|
-
showPreview && /* @__PURE__ */
|
|
17254
|
+
showPreview && /* @__PURE__ */ jsx18(
|
|
17230
17255
|
AutocompletePreview,
|
|
17231
17256
|
{
|
|
17232
17257
|
suggestions,
|
|
@@ -17235,7 +17260,7 @@ var ChatInput = memo11(({
|
|
|
17235
17260
|
),
|
|
17236
17261
|
inputRequest.status === "active" ? (
|
|
17237
17262
|
/* Active input request — yellow top/bottom border */
|
|
17238
|
-
/* @__PURE__ */
|
|
17263
|
+
/* @__PURE__ */ jsx18(
|
|
17239
17264
|
SecretInputArea,
|
|
17240
17265
|
{
|
|
17241
17266
|
inputRequest,
|
|
@@ -17246,7 +17271,7 @@ var ChatInput = memo11(({
|
|
|
17246
17271
|
)
|
|
17247
17272
|
) : (
|
|
17248
17273
|
/* Normal input — dim top/bottom border */
|
|
17249
|
-
/* @__PURE__ */
|
|
17274
|
+
/* @__PURE__ */ jsx18(
|
|
17250
17275
|
NormalInputArea,
|
|
17251
17276
|
{
|
|
17252
17277
|
inputKey,
|
|
@@ -17257,14 +17282,14 @@ var ChatInput = memo11(({
|
|
|
17257
17282
|
}
|
|
17258
17283
|
)
|
|
17259
17284
|
),
|
|
17260
|
-
pastedHint && /* @__PURE__ */
|
|
17285
|
+
pastedHint && /* @__PURE__ */ jsx18(Box15, { paddingX: 2, children: /* @__PURE__ */ jsx18(Text17, { dimColor: true, color: THEME.dimGray, children: pastedHint }) })
|
|
17261
17286
|
] });
|
|
17262
17287
|
});
|
|
17263
17288
|
|
|
17264
17289
|
// src/platform/tui/components/footer.tsx
|
|
17265
17290
|
import { memo as memo12 } from "react";
|
|
17266
17291
|
import { Box as Box16, Text as Text18 } from "ink";
|
|
17267
|
-
import { jsx as
|
|
17292
|
+
import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
17268
17293
|
var CTX_WARN_THRESHOLD = 0.8;
|
|
17269
17294
|
var MAX_CONTEXT_TOKENS = LLM_LIMITS.streamMaxTokens;
|
|
17270
17295
|
var formatElapsed = (totalSeconds) => {
|
|
@@ -17291,26 +17316,26 @@ var Footer = memo12(({ phase, targets, findings, todo, elapsedTime, isProcessing
|
|
|
17291
17316
|
/* @__PURE__ */ jsxs15(Box16, { gap: 2, children: [
|
|
17292
17317
|
/* @__PURE__ */ jsxs15(Text18, { color: THEME.gray, children: [
|
|
17293
17318
|
"Phase: ",
|
|
17294
|
-
/* @__PURE__ */
|
|
17319
|
+
/* @__PURE__ */ jsx19(Text18, { color: THEME.white, children: phase })
|
|
17295
17320
|
] }),
|
|
17296
17321
|
/* @__PURE__ */ jsxs15(Text18, { color: THEME.gray, children: [
|
|
17297
17322
|
"Targets: ",
|
|
17298
|
-
/* @__PURE__ */
|
|
17323
|
+
/* @__PURE__ */ jsx19(Text18, { color: THEME.white, children: targets })
|
|
17299
17324
|
] }),
|
|
17300
17325
|
/* @__PURE__ */ jsxs15(Text18, { color: THEME.gray, children: [
|
|
17301
17326
|
"Findings: ",
|
|
17302
|
-
/* @__PURE__ */
|
|
17327
|
+
/* @__PURE__ */ jsx19(Text18, { color: THEME.white, children: findings })
|
|
17303
17328
|
] }),
|
|
17304
17329
|
/* @__PURE__ */ jsxs15(Text18, { color: THEME.gray, children: [
|
|
17305
17330
|
"Tasks: ",
|
|
17306
|
-
/* @__PURE__ */
|
|
17331
|
+
/* @__PURE__ */ jsx19(Text18, { color: THEME.white, children: todo })
|
|
17307
17332
|
] })
|
|
17308
17333
|
] }),
|
|
17309
17334
|
/* @__PURE__ */ jsxs15(Box16, { gap: 2, children: [
|
|
17310
17335
|
isProcessing ? /* @__PURE__ */ jsxs15(Box16, { gap: 1, children: [
|
|
17311
|
-
/* @__PURE__ */
|
|
17312
|
-
/* @__PURE__ */
|
|
17313
|
-
] }) : /* @__PURE__ */
|
|
17336
|
+
/* @__PURE__ */ jsx19(Text18, { dimColor: true, color: THEME.dimGray, children: "[ESC] abort" }),
|
|
17337
|
+
/* @__PURE__ */ jsx19(Text18, { dimColor: true, color: THEME.dimGray, children: "[^C\xD72] exit" })
|
|
17338
|
+
] }) : /* @__PURE__ */ jsx19(Text18, { dimColor: true, color: THEME.dimGray, children: "[/help] commands" }),
|
|
17314
17339
|
turnCount > 0 && /* @__PURE__ */ jsxs15(Text18, { dimColor: true, color: THEME.dimGray, children: [
|
|
17315
17340
|
"turn:",
|
|
17316
17341
|
turnCount
|
|
@@ -17324,8 +17349,8 @@ var Footer = memo12(({ phase, targets, findings, todo, elapsedTime, isProcessing
|
|
|
17324
17349
|
"\u2191",
|
|
17325
17350
|
formatTokens(totalTokens)
|
|
17326
17351
|
] }),
|
|
17327
|
-
/* @__PURE__ */
|
|
17328
|
-
/* @__PURE__ */
|
|
17352
|
+
/* @__PURE__ */ jsx19(Text18, { color: isProcessing ? THEME.primary : THEME.gray, children: isProcessing ? "Running " : "Idle " }),
|
|
17353
|
+
/* @__PURE__ */ jsx19(Text18, { color: THEME.white, children: formatElapsed(elapsedTime) })
|
|
17329
17354
|
] })
|
|
17330
17355
|
]
|
|
17331
17356
|
}
|
|
@@ -17336,7 +17361,7 @@ var footer_default = Footer;
|
|
|
17336
17361
|
// src/platform/tui/components/Modal.tsx
|
|
17337
17362
|
import { useMemo as useMemo2, memo as memo13, useCallback as useCallback10, useRef as useRef9 } from "react";
|
|
17338
17363
|
import { Box as Box17, Text as Text19, useStdout as useStdout3, useInput as useInput4 } from "ink";
|
|
17339
|
-
import { jsx as
|
|
17364
|
+
import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
17340
17365
|
var MODAL_TITLES = {
|
|
17341
17366
|
findings: "\u25C8 FINDINGS \u25C8",
|
|
17342
17367
|
graph: "\u25C8 ATTACK GRAPH \u25C8",
|
|
@@ -17387,12 +17412,12 @@ var Modal = memo13(({
|
|
|
17387
17412
|
width: terminalWidth,
|
|
17388
17413
|
height: terminalHeight,
|
|
17389
17414
|
children: [
|
|
17390
|
-
/* @__PURE__ */
|
|
17415
|
+
/* @__PURE__ */ jsx20(Box17, { justifyContent: "center", marginBottom: 0, children: /* @__PURE__ */ jsx20(Text19, { color: THEME.cyan, bold: true, children: (() => {
|
|
17391
17416
|
const title = MODAL_TITLES[type];
|
|
17392
17417
|
const sideWidth = Math.max(3, Math.floor((terminalWidth - title.length - 2) / 2));
|
|
17393
17418
|
return `${"\u2500".repeat(sideWidth)} ${title} ${"\u2500".repeat(sideWidth)}`;
|
|
17394
17419
|
})() }) }),
|
|
17395
|
-
/* @__PURE__ */
|
|
17420
|
+
/* @__PURE__ */ jsx20(
|
|
17396
17421
|
Box17,
|
|
17397
17422
|
{
|
|
17398
17423
|
flexDirection: "column",
|
|
@@ -17403,15 +17428,15 @@ var Modal = memo13(({
|
|
|
17403
17428
|
children: visibleLines.map((line, i) => {
|
|
17404
17429
|
const showScrollbar = totalLines > maxHeight && i >= scrollbarPosition && i < scrollbarPosition + scrollbarHeight;
|
|
17405
17430
|
return /* @__PURE__ */ jsxs16(Box17, { children: [
|
|
17406
|
-
/* @__PURE__ */
|
|
17407
|
-
/* @__PURE__ */
|
|
17408
|
-
totalLines > maxHeight && /* @__PURE__ */
|
|
17431
|
+
/* @__PURE__ */ jsx20(Text19, { color: THEME.white, wrap: "truncate", children: line }),
|
|
17432
|
+
/* @__PURE__ */ jsx20(Box17, { flexGrow: 1 }),
|
|
17433
|
+
totalLines > maxHeight && /* @__PURE__ */ jsx20(Text19, { color: showScrollbar ? THEME.cyan : THEME.dimGray, children: showScrollbar ? "\u2588" : "\u2502" })
|
|
17409
17434
|
] }, i);
|
|
17410
17435
|
})
|
|
17411
17436
|
}
|
|
17412
17437
|
),
|
|
17413
17438
|
/* @__PURE__ */ jsxs16(Box17, { justifyContent: "space-between", paddingX: 1, children: [
|
|
17414
|
-
/* @__PURE__ */
|
|
17439
|
+
/* @__PURE__ */ jsx20(Text19, { dimColor: true, color: THEME.gray, children: "\u2191\u2193/jk: scroll | g/G: top/bottom | ESC/q: close" }),
|
|
17415
17440
|
/* @__PURE__ */ jsxs16(Text19, { dimColor: true, color: THEME.cyan, children: [
|
|
17416
17441
|
startLine,
|
|
17417
17442
|
"-",
|
|
@@ -17427,7 +17452,7 @@ var Modal = memo13(({
|
|
|
17427
17452
|
|
|
17428
17453
|
// src/platform/tui/components/app/bottom-region.tsx
|
|
17429
17454
|
import { Box as Box18 } from "ink";
|
|
17430
|
-
import { jsx as
|
|
17455
|
+
import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
17431
17456
|
var BottomRegion = ({
|
|
17432
17457
|
input,
|
|
17433
17458
|
setInput,
|
|
@@ -17450,19 +17475,19 @@ var BottomRegion = ({
|
|
|
17450
17475
|
const hasArgs = isSlashMode && input.includes(" ");
|
|
17451
17476
|
const suggestionCount = isSlashMode && !hasArgs && inputRequest.status !== "active" ? Math.min(getMatchingCommands(partialCmd).length, MAX_SUGGESTIONS) : 0;
|
|
17452
17477
|
const previewHeight = suggestionCount;
|
|
17453
|
-
const
|
|
17454
|
-
const bottomMinHeight = 7 + inputExtraHeight;
|
|
17478
|
+
const bottomMinHeight = 7;
|
|
17455
17479
|
return /* @__PURE__ */ jsxs17(Box18, { flexDirection: "column", minHeight: bottomMinHeight, children: [
|
|
17456
|
-
/* @__PURE__ */
|
|
17480
|
+
/* @__PURE__ */ jsx21(
|
|
17457
17481
|
StatusDisplay,
|
|
17458
17482
|
{
|
|
17459
17483
|
retryState,
|
|
17460
17484
|
isProcessing,
|
|
17461
17485
|
currentStatus,
|
|
17462
|
-
currentTokens
|
|
17486
|
+
currentTokens,
|
|
17487
|
+
inputRequest
|
|
17463
17488
|
}
|
|
17464
17489
|
),
|
|
17465
|
-
/* @__PURE__ */
|
|
17490
|
+
/* @__PURE__ */ jsx21(
|
|
17466
17491
|
ChatInput,
|
|
17467
17492
|
{
|
|
17468
17493
|
value: input,
|
|
@@ -17475,7 +17500,7 @@ var BottomRegion = ({
|
|
|
17475
17500
|
onSecretSubmit: handleSecretSubmit
|
|
17476
17501
|
}
|
|
17477
17502
|
),
|
|
17478
|
-
/* @__PURE__ */
|
|
17503
|
+
/* @__PURE__ */ jsx21(Box18, { marginTop: 1, children: /* @__PURE__ */ jsx21(
|
|
17479
17504
|
footer_default,
|
|
17480
17505
|
{
|
|
17481
17506
|
phase: stats.phase,
|
|
@@ -17492,16 +17517,16 @@ var BottomRegion = ({
|
|
|
17492
17517
|
};
|
|
17493
17518
|
|
|
17494
17519
|
// src/platform/tui/app.tsx
|
|
17495
|
-
import { jsx as
|
|
17520
|
+
import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
17496
17521
|
var MODEL_NAME = getModel() || DEFAULT_MODEL;
|
|
17497
17522
|
var App = ({ autoApprove = false, target }) => {
|
|
17498
17523
|
const { exit } = useApp();
|
|
17499
17524
|
const { stdout } = useStdout4();
|
|
17500
17525
|
const terminalWidth = stdout?.columns ?? 80;
|
|
17501
|
-
const [input, setInput] =
|
|
17502
|
-
const [secretInput, setSecretInput] =
|
|
17503
|
-
const [autoApproveMode, setAutoApproveMode] =
|
|
17504
|
-
const [modal, setModal] =
|
|
17526
|
+
const [input, setInput] = useState7("");
|
|
17527
|
+
const [secretInput, setSecretInput] = useState7("");
|
|
17528
|
+
const [autoApproveMode, setAutoApproveMode] = useState7(autoApprove);
|
|
17529
|
+
const [modal, setModal] = useState7({ type: null, content: "", scrollOffset: 0 });
|
|
17505
17530
|
const {
|
|
17506
17531
|
agent,
|
|
17507
17532
|
messages,
|
|
@@ -17534,7 +17559,7 @@ var App = ({ autoApprove = false, target }) => {
|
|
|
17534
17559
|
const clearInput = useCallback11(() => {
|
|
17535
17560
|
setInput("");
|
|
17536
17561
|
}, []);
|
|
17537
|
-
const [historyScrollOffset, setHistoryScrollOffset] =
|
|
17562
|
+
const [historyScrollOffset, setHistoryScrollOffset] = useState7(0);
|
|
17538
17563
|
const handleScroll = useCallback11((delta) => {
|
|
17539
17564
|
setHistoryScrollOffset((prev) => Math.max(0, prev - delta));
|
|
17540
17565
|
}, []);
|
|
@@ -17601,9 +17626,8 @@ var App = ({ autoApprove = false, target }) => {
|
|
|
17601
17626
|
const handleSecretSubmit = useCallback11((value) => {
|
|
17602
17627
|
const ir = inputRequestRef.current;
|
|
17603
17628
|
if (ir.status !== "active") return;
|
|
17604
|
-
const displayText = ir.isPassword ? "\u2022".repeat(value.length) : value;
|
|
17605
|
-
|
|
17606
|
-
addMessage("system", `\u21B3 ${promptLabel} ${displayText}`);
|
|
17629
|
+
const displayText = ir.isPassword ? "\u2022".repeat(Math.min(value.length, 20)) : value;
|
|
17630
|
+
addMessage("system", `\u21B3 ${displayText}`);
|
|
17607
17631
|
ir.resolve(value);
|
|
17608
17632
|
setInputRequest({ status: "inactive" });
|
|
17609
17633
|
setSecretInput("");
|
|
@@ -17621,7 +17645,7 @@ var App = ({ autoApprove = false, target }) => {
|
|
|
17621
17645
|
onScroll: handleScroll
|
|
17622
17646
|
});
|
|
17623
17647
|
if (modal.type) {
|
|
17624
|
-
return /* @__PURE__ */
|
|
17648
|
+
return /* @__PURE__ */ jsx22(Box19, { flexDirection: "column", paddingX: 1, width: terminalWidth, children: /* @__PURE__ */ jsx22(
|
|
17625
17649
|
Modal,
|
|
17626
17650
|
{
|
|
17627
17651
|
type: modal.type,
|
|
@@ -17633,7 +17657,7 @@ var App = ({ autoApprove = false, target }) => {
|
|
|
17633
17657
|
) });
|
|
17634
17658
|
}
|
|
17635
17659
|
return /* @__PURE__ */ jsxs18(Box19, { flexDirection: "column", paddingX: 1, width: terminalWidth, children: [
|
|
17636
|
-
/* @__PURE__ */
|
|
17660
|
+
/* @__PURE__ */ jsx22(Box19, { flexDirection: "column", children: /* @__PURE__ */ jsx22(
|
|
17637
17661
|
MessageList,
|
|
17638
17662
|
{
|
|
17639
17663
|
messages,
|
|
@@ -17644,7 +17668,7 @@ var App = ({ autoApprove = false, target }) => {
|
|
|
17644
17668
|
scrollOffset: historyScrollOffset
|
|
17645
17669
|
}
|
|
17646
17670
|
) }),
|
|
17647
|
-
/* @__PURE__ */
|
|
17671
|
+
/* @__PURE__ */ jsx22(
|
|
17648
17672
|
BottomRegion,
|
|
17649
17673
|
{
|
|
17650
17674
|
input,
|
|
@@ -17669,7 +17693,7 @@ var App = ({ autoApprove = false, target }) => {
|
|
|
17669
17693
|
var app_default = App;
|
|
17670
17694
|
|
|
17671
17695
|
// src/platform/tui/cli/commands/interactive.tsx
|
|
17672
|
-
import { jsx as
|
|
17696
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
17673
17697
|
async function interactiveAction(options) {
|
|
17674
17698
|
const { dangerouslySkipPermissions: skipPermissions = false, target } = options;
|
|
17675
17699
|
console.clear();
|
|
@@ -17678,13 +17702,13 @@ async function interactiveAction(options) {
|
|
|
17678
17702
|
console.log(chalk.hex(HEX.red)("[!] All tool executions will be auto-approved!\n"));
|
|
17679
17703
|
}
|
|
17680
17704
|
const { waitUntilExit } = render(
|
|
17681
|
-
/* @__PURE__ */
|
|
17705
|
+
/* @__PURE__ */ jsx23(AnimationProvider, { children: /* @__PURE__ */ jsx23(
|
|
17682
17706
|
app_default,
|
|
17683
17707
|
{
|
|
17684
17708
|
autoApprove: skipPermissions,
|
|
17685
17709
|
target
|
|
17686
17710
|
}
|
|
17687
|
-
)
|
|
17711
|
+
) })
|
|
17688
17712
|
);
|
|
17689
17713
|
await waitUntilExit();
|
|
17690
17714
|
}
|