@pensar/apex 0.0.88 → 0.0.89-canary.4677df83
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/build/index.js +248 -61
- package/package.json +1 -1
package/build/index.js
CHANGED
|
@@ -31971,7 +31971,7 @@ var package_default2;
|
|
|
31971
31971
|
var init_package = __esm(() => {
|
|
31972
31972
|
package_default2 = {
|
|
31973
31973
|
name: "@pensar/apex",
|
|
31974
|
-
version: "0.0.
|
|
31974
|
+
version: "0.0.89-canary.4677df83",
|
|
31975
31975
|
description: "AI-powered penetration testing CLI tool with terminal UI",
|
|
31976
31976
|
module: "src/tui/index.tsx",
|
|
31977
31977
|
main: "build/index.js",
|
|
@@ -88441,7 +88441,8 @@ async function summarizeConversation(messages, opts, model) {
|
|
|
88441
88441
|
const { text: summary, usage: summaryUsage } = await generateText({
|
|
88442
88442
|
model,
|
|
88443
88443
|
system: `You are a helpful assistant that summarizes conversations to pass to another agent. Review the conversation and system prompt at the end provided by the user.`,
|
|
88444
|
-
messages: summarizedMessages
|
|
88444
|
+
messages: summarizedMessages,
|
|
88445
|
+
abortSignal: opts.abortSignal
|
|
88445
88446
|
});
|
|
88446
88447
|
if (opts.onStepFinish && summaryUsage) {
|
|
88447
88448
|
opts.onStepFinish({
|
|
@@ -88719,7 +88720,8 @@ function streamResponse(opts) {
|
|
|
88719
88720
|
"IMPORTANT: For enum fields like 'severity' or 'riskLevel', use ONLY the exact values from the enum (e.g., 'HIGH', 'CRITICAL', 'MEDIUM', 'LOW').",
|
|
88720
88721
|
"Do not add prefixes, suffixes, or formatting characters like '>', '-', '!', etc."
|
|
88721
88722
|
].join(`
|
|
88722
|
-
`)
|
|
88723
|
+
`),
|
|
88724
|
+
abortSignal
|
|
88723
88725
|
});
|
|
88724
88726
|
if (onStepFinish && repairUsage) {
|
|
88725
88727
|
onStepFinish({
|
|
@@ -88787,6 +88789,7 @@ async function generateObjectResponse(opts) {
|
|
|
88787
88789
|
maxTokens,
|
|
88788
88790
|
temperature,
|
|
88789
88791
|
authConfig,
|
|
88792
|
+
abortSignal,
|
|
88790
88793
|
onTokenUsage
|
|
88791
88794
|
} = opts;
|
|
88792
88795
|
const providerModel = getProviderModel(model, authConfig);
|
|
@@ -88802,7 +88805,8 @@ async function generateObjectResponse(opts) {
|
|
|
88802
88805
|
system,
|
|
88803
88806
|
maxOutputTokens: maxTokens,
|
|
88804
88807
|
temperature,
|
|
88805
|
-
maxRetries: 0
|
|
88808
|
+
maxRetries: 0,
|
|
88809
|
+
abortSignal
|
|
88806
88810
|
});
|
|
88807
88811
|
if (onTokenUsage && usage) {
|
|
88808
88812
|
onTokenUsage(usage.inputTokens ?? 0, usage.outputTokens ?? 0);
|
|
@@ -88849,7 +88853,7 @@ function generateRandomName() {
|
|
|
88849
88853
|
return `${adj}-${noun}`;
|
|
88850
88854
|
}
|
|
88851
88855
|
async function generateSessionName(opts) {
|
|
88852
|
-
const { targets, userMessage, model, authConfig } = opts;
|
|
88856
|
+
const { targets, userMessage, model, authConfig, abortSignal } = opts;
|
|
88853
88857
|
const contextParts = [];
|
|
88854
88858
|
if (targets.length > 0) {
|
|
88855
88859
|
contextParts.push(`Target(s): ${targets.join(", ")}`);
|
|
@@ -88874,7 +88878,8 @@ async function generateSessionName(opts) {
|
|
|
88874
88878
|
prompt,
|
|
88875
88879
|
maxTokens: 50,
|
|
88876
88880
|
temperature: 0.7,
|
|
88877
|
-
authConfig
|
|
88881
|
+
authConfig,
|
|
88882
|
+
abortSignal
|
|
88878
88883
|
});
|
|
88879
88884
|
if (!result?.name)
|
|
88880
88885
|
return null;
|
|
@@ -106937,7 +106942,7 @@ IMPORTANT: Always analyze results and adjust your approach based on findings.`,
|
|
|
106937
106942
|
}
|
|
106938
106943
|
if (ctx4.persistentShell) {
|
|
106939
106944
|
try {
|
|
106940
|
-
const result = await ctx4.persistentShell.execute(command, timeout, ctx4.onCommandOutput);
|
|
106945
|
+
const result = await ctx4.persistentShell.execute(command, timeout, ctx4.onCommandOutput, ctx4.abortSignal);
|
|
106941
106946
|
const { text: stdout, file: outputFile } = maybeSaveFullOutput(result.stdout, ctx4);
|
|
106942
106947
|
return {
|
|
106943
106948
|
success: result.exitCode === 0,
|
|
@@ -107845,14 +107850,15 @@ var init_cvss = __esm(() => {
|
|
|
107845
107850
|
});
|
|
107846
107851
|
|
|
107847
107852
|
// src/core/agents/specialized/cvssScorer/index.ts
|
|
107848
|
-
async function scoreFindingWithCVSS(input, model, authConfig) {
|
|
107853
|
+
async function scoreFindingWithCVSS(input, model, authConfig, abortSignal) {
|
|
107849
107854
|
const prompt = buildScoringPrompt(input);
|
|
107850
107855
|
const assessment = await generateObjectResponse({
|
|
107851
107856
|
model,
|
|
107852
107857
|
schema: CVSSMetricsOutputSchema,
|
|
107853
107858
|
prompt,
|
|
107854
107859
|
system: CVSS_SCORER_SYSTEM_PROMPT,
|
|
107855
|
-
authConfig
|
|
107860
|
+
authConfig,
|
|
107861
|
+
abortSignal
|
|
107856
107862
|
});
|
|
107857
107863
|
const cvssResult = calculateCVSS4Score({
|
|
107858
107864
|
...assessment.metrics
|
|
@@ -108120,7 +108126,7 @@ FINDING STRUCTURE:
|
|
|
108120
108126
|
remediation: input.remediation
|
|
108121
108127
|
},
|
|
108122
108128
|
agentMessages: []
|
|
108123
|
-
}, ctx4.model, ctx4.authConfig);
|
|
108129
|
+
}, ctx4.model, ctx4.authConfig, ctx4.abortSignal);
|
|
108124
108130
|
} catch (cvssError) {
|
|
108125
108131
|
const msg = cvssError instanceof Error ? cvssError.message : String(cvssError);
|
|
108126
108132
|
cvssWarning = `CVSS scoring failed (${msg}), using fallback severity.`;
|
|
@@ -111302,10 +111308,12 @@ class FindingsRegistry {
|
|
|
111302
111308
|
findings = [];
|
|
111303
111309
|
model;
|
|
111304
111310
|
authConfig;
|
|
111311
|
+
abortSignal;
|
|
111305
111312
|
mutex = Promise.resolve();
|
|
111306
111313
|
constructor(opts) {
|
|
111307
111314
|
this.model = opts?.model;
|
|
111308
111315
|
this.authConfig = opts?.authConfig;
|
|
111316
|
+
this.abortSignal = opts?.abortSignal;
|
|
111309
111317
|
}
|
|
111310
111318
|
get size() {
|
|
111311
111319
|
return this.findings.length;
|
|
@@ -111402,7 +111410,8 @@ class FindingsRegistry {
|
|
|
111402
111410
|
schema: SemanticDedupResultSchema,
|
|
111403
111411
|
prompt,
|
|
111404
111412
|
system: SEMANTIC_DEDUP_SYSTEM,
|
|
111405
|
-
authConfig: this.authConfig
|
|
111413
|
+
authConfig: this.authConfig,
|
|
111414
|
+
abortSignal: this.abortSignal
|
|
111406
111415
|
});
|
|
111407
111416
|
if (result.isDuplicate && result.matchedIndex != null) {
|
|
111408
111417
|
const idx = result.matchedIndex - 1;
|
|
@@ -111526,7 +111535,8 @@ Pass every target you want tested — the swarm handles concurrency automaticall
|
|
|
111526
111535
|
}
|
|
111527
111536
|
const findingsRegistry = ctx4.findingsRegistry ?? FindingsRegistry.fromDirectory(ctx4.session.findingsPath, {
|
|
111528
111537
|
model: ctx4.model,
|
|
111529
|
-
authConfig: ctx4.authConfig
|
|
111538
|
+
authConfig: ctx4.authConfig,
|
|
111539
|
+
abortSignal: ctx4.abortSignal
|
|
111530
111540
|
});
|
|
111531
111541
|
const total = targets.length;
|
|
111532
111542
|
console.log(`
|
|
@@ -193567,10 +193577,17 @@ class PersistentShell {
|
|
|
193567
193577
|
this.spawn();
|
|
193568
193578
|
}
|
|
193569
193579
|
}
|
|
193570
|
-
async execute(command, timeoutSeconds, onData) {
|
|
193580
|
+
async execute(command, timeoutSeconds, onData, abortSignal) {
|
|
193571
193581
|
if (this.disposed) {
|
|
193572
193582
|
return { stdout: "", stderr: "Shell has been disposed", exitCode: 1 };
|
|
193573
193583
|
}
|
|
193584
|
+
if (abortSignal?.aborted) {
|
|
193585
|
+
return {
|
|
193586
|
+
stdout: "",
|
|
193587
|
+
stderr: "Command aborted",
|
|
193588
|
+
exitCode: 130
|
|
193589
|
+
};
|
|
193590
|
+
}
|
|
193574
193591
|
this.ensureAlive();
|
|
193575
193592
|
const proc = this.proc;
|
|
193576
193593
|
if (!proc || !proc.stdin || !proc.stdout || !proc.stderr) {
|
|
@@ -193595,11 +193612,38 @@ class PersistentShell {
|
|
|
193595
193612
|
this.pendingStderr = null;
|
|
193596
193613
|
if (timeoutTimer)
|
|
193597
193614
|
clearTimeout(timeoutTimer);
|
|
193615
|
+
if (abortCleanup)
|
|
193616
|
+
abortCleanup();
|
|
193598
193617
|
proc.stdout.removeListener("data", onStdout);
|
|
193599
193618
|
proc.stderr.removeListener("data", onStderr);
|
|
193600
193619
|
resolve4(result);
|
|
193601
193620
|
};
|
|
193602
193621
|
this.pendingCancel = safeResolve;
|
|
193622
|
+
let abortCleanup;
|
|
193623
|
+
if (abortSignal) {
|
|
193624
|
+
const onAbort = () => {
|
|
193625
|
+
if (resolved)
|
|
193626
|
+
return;
|
|
193627
|
+
const pid = proc.pid;
|
|
193628
|
+
if (pid && process.platform !== "win32") {
|
|
193629
|
+
try {
|
|
193630
|
+
spawnSync("pkill", ["-TERM", "-P", pid.toString()], {
|
|
193631
|
+
stdio: "ignore"
|
|
193632
|
+
});
|
|
193633
|
+
} catch {}
|
|
193634
|
+
}
|
|
193635
|
+
setTimeout(() => {
|
|
193636
|
+
safeResolve({
|
|
193637
|
+
stdout: stdout || "(no output)",
|
|
193638
|
+
stderr: stderr ? stderr + `
|
|
193639
|
+
(aborted)` : "(aborted)",
|
|
193640
|
+
exitCode: 130
|
|
193641
|
+
});
|
|
193642
|
+
}, 500);
|
|
193643
|
+
};
|
|
193644
|
+
abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
193645
|
+
abortCleanup = () => abortSignal.removeEventListener("abort", onAbort);
|
|
193646
|
+
}
|
|
193603
193647
|
const onStdout = (data) => {
|
|
193604
193648
|
const chunk = data.toString();
|
|
193605
193649
|
if (onData && !chunk.includes(exitMarkerPrefix)) {
|
|
@@ -194504,6 +194548,35 @@ For \`http_request\`, pass these as the \`headers\` parameter.`, `For \`execute_
|
|
|
194504
194548
|
The following vulnerabilities have already been documented. Do NOT re-test or re-document these — the system will automatically reject duplicates.
|
|
194505
194549
|
${existing}`;
|
|
194506
194550
|
}
|
|
194551
|
+
let knowledgeBaseSection = "";
|
|
194552
|
+
const markerPath = join24(sessionRootPath, "scratchpad", ".knowledge-populated");
|
|
194553
|
+
if (existsSync23(markerPath)) {
|
|
194554
|
+
try {
|
|
194555
|
+
const count = parseInt(readFileSync9(markerPath, "utf-8").trim(), 10) || 0;
|
|
194556
|
+
if (count > 0) {
|
|
194557
|
+
knowledgeBaseSection = `
|
|
194558
|
+
|
|
194559
|
+
## Project Knowledge Available
|
|
194560
|
+
There are ${count} project knowledge entries in the memory system from previous scans, user notes, and resolved issues. Before beginning your testing plan, call \`list_memories\` with tag \`"project-knowledge"\` to check for relevant context. Pay special attention to false positive patterns and technology context that may affect your testing.`;
|
|
194561
|
+
}
|
|
194562
|
+
} catch {}
|
|
194563
|
+
}
|
|
194564
|
+
if (!knowledgeBaseSection) {
|
|
194565
|
+
const knowledgePath = join24(sessionRootPath, "scratchpad", "knowledge-base.md");
|
|
194566
|
+
if (existsSync23(knowledgePath)) {
|
|
194567
|
+
try {
|
|
194568
|
+
const knowledgeContent = readFileSync9(knowledgePath, "utf-8").trim();
|
|
194569
|
+
if (knowledgeContent) {
|
|
194570
|
+
knowledgeBaseSection = `
|
|
194571
|
+
|
|
194572
|
+
## Project Knowledge Base
|
|
194573
|
+
The following is accumulated knowledge about this project from previous scans, user notes, and resolved issues. Use this context to avoid false positives and make better testing decisions.
|
|
194574
|
+
|
|
194575
|
+
${knowledgeContent}`;
|
|
194576
|
+
}
|
|
194577
|
+
} catch {}
|
|
194578
|
+
}
|
|
194579
|
+
}
|
|
194507
194580
|
const outcomeSection = outcomeGuidance ? `
|
|
194508
194581
|
## Outcome Guidance
|
|
194509
194582
|
${outcomeGuidance}
|
|
@@ -194535,6 +194608,7 @@ Do NOT discover or enumerate other endpoints or services. Focus exclusively on t
|
|
|
194535
194608
|
- **URL:** ${target}
|
|
194536
194609
|
${authSection}
|
|
194537
194610
|
${knownFindingsSection}
|
|
194611
|
+
${knowledgeBaseSection}
|
|
194538
194612
|
|
|
194539
194613
|
## Objectives
|
|
194540
194614
|
${objectiveList}
|
|
@@ -194685,7 +194759,9 @@ var init_agent4 = __esm(() => {
|
|
|
194685
194759
|
"email_list_inboxes",
|
|
194686
194760
|
"email_list_messages",
|
|
194687
194761
|
"email_search_messages",
|
|
194688
|
-
"email_get_message"
|
|
194762
|
+
"email_get_message",
|
|
194763
|
+
"list_memories",
|
|
194764
|
+
"get_memory"
|
|
194689
194765
|
],
|
|
194690
194766
|
responseSchema: PentestResponseSchema,
|
|
194691
194767
|
resolveResult: () => {
|
|
@@ -195516,7 +195592,8 @@ async function runPentestWorkflow(input) {
|
|
|
195516
195592
|
}
|
|
195517
195593
|
const findingsRegistry = FindingsRegistry.fromDirectory(session.findingsPath, {
|
|
195518
195594
|
model,
|
|
195519
|
-
authConfig
|
|
195595
|
+
authConfig,
|
|
195596
|
+
abortSignal
|
|
195520
195597
|
});
|
|
195521
195598
|
await runPentestSwarm({
|
|
195522
195599
|
targets: swarmTargets,
|
|
@@ -272247,7 +272324,7 @@ var useTerminalDimensions = () => {
|
|
|
272247
272324
|
};
|
|
272248
272325
|
|
|
272249
272326
|
// src/tui/index.tsx
|
|
272250
|
-
var
|
|
272327
|
+
var import_react88 = __toESM(require_react(), 1);
|
|
272251
272328
|
|
|
272252
272329
|
// src/tui/components/footer.tsx
|
|
272253
272330
|
import os6 from "os";
|
|
@@ -274866,6 +274943,12 @@ function shouldResetHistory(historyIndex, isNavigatingHistory) {
|
|
|
274866
274943
|
}
|
|
274867
274944
|
|
|
274868
274945
|
// src/tui/components/shared/prompt-input.tsx
|
|
274946
|
+
var chatKeyBindings = [
|
|
274947
|
+
{ name: "return", action: "submit" },
|
|
274948
|
+
{ name: "linefeed", action: "newline" },
|
|
274949
|
+
{ name: "return", shift: true, action: "newline" },
|
|
274950
|
+
{ name: "linefeed", shift: true, action: "newline" }
|
|
274951
|
+
];
|
|
274869
274952
|
var PromptInput = import_react29.forwardRef(function PromptInput2({
|
|
274870
274953
|
width,
|
|
274871
274954
|
minHeight = 1,
|
|
@@ -275058,26 +275141,7 @@ var PromptInput = import_react29.forwardRef(function PromptInput2({
|
|
|
275058
275141
|
backgroundColor,
|
|
275059
275142
|
focusedBackgroundColor,
|
|
275060
275143
|
cursorColor: cursorColor ?? colors2.textMuted,
|
|
275061
|
-
keyBindings:
|
|
275062
|
-
{
|
|
275063
|
-
action: "submit",
|
|
275064
|
-
name: "return"
|
|
275065
|
-
},
|
|
275066
|
-
{
|
|
275067
|
-
action: "submit",
|
|
275068
|
-
name: "linefeed"
|
|
275069
|
-
},
|
|
275070
|
-
{
|
|
275071
|
-
action: "newline",
|
|
275072
|
-
shift: true,
|
|
275073
|
-
name: "return"
|
|
275074
|
-
},
|
|
275075
|
-
{
|
|
275076
|
-
action: "newline",
|
|
275077
|
-
shift: true,
|
|
275078
|
-
name: "linefeed"
|
|
275079
|
-
}
|
|
275080
|
-
],
|
|
275144
|
+
keyBindings: chatKeyBindings,
|
|
275081
275145
|
onContentChange: handleContentChange,
|
|
275082
275146
|
onSubmit: handleSubmit
|
|
275083
275147
|
}, undefined, false, undefined, this)
|
|
@@ -285101,13 +285165,16 @@ function NormalInputAreaInner({
|
|
|
285101
285165
|
const { inputValue, setInputValue } = useInput();
|
|
285102
285166
|
const promptRef = import_react77.useRef(null);
|
|
285103
285167
|
const isExternalUpdate = import_react77.useRef(false);
|
|
285168
|
+
const prevValueRef = import_react77.useRef(value);
|
|
285104
285169
|
import_react77.useEffect(() => {
|
|
285105
|
-
|
|
285170
|
+
const prevValue = prevValueRef.current;
|
|
285171
|
+
prevValueRef.current = value;
|
|
285172
|
+
if (value !== prevValue && value !== inputValue) {
|
|
285106
285173
|
isExternalUpdate.current = true;
|
|
285107
285174
|
setInputValue(value);
|
|
285108
285175
|
promptRef.current?.setValue(value);
|
|
285109
285176
|
}
|
|
285110
|
-
}, [value]);
|
|
285177
|
+
}, [value, inputValue, setInputValue]);
|
|
285111
285178
|
import_react77.useEffect(() => {
|
|
285112
285179
|
if (isExternalUpdate.current) {
|
|
285113
285180
|
isExternalUpdate.current = false;
|
|
@@ -285116,7 +285183,7 @@ function NormalInputAreaInner({
|
|
|
285116
285183
|
if (inputValue !== value) {
|
|
285117
285184
|
onChange(inputValue);
|
|
285118
285185
|
}
|
|
285119
|
-
}, [inputValue]);
|
|
285186
|
+
}, [inputValue, value, onChange]);
|
|
285120
285187
|
const handleSubmit = (val) => {
|
|
285121
285188
|
if (val.trim()) {
|
|
285122
285189
|
onSubmit(val.trim());
|
|
@@ -289634,15 +289701,125 @@ async function detectTerminalMode(timeoutMs = 1000) {
|
|
|
289634
289701
|
});
|
|
289635
289702
|
}
|
|
289636
289703
|
|
|
289704
|
+
// src/tui/console-theme.ts
|
|
289705
|
+
var import_react85 = __toESM(require_react(), 1);
|
|
289706
|
+
var withAlpha = (rgba, a) => RGBA.fromValues(rgba.r, rgba.g, rgba.b, a);
|
|
289707
|
+
var overlayThemeRef = {
|
|
289708
|
+
current: null
|
|
289709
|
+
};
|
|
289710
|
+
function buildConsoleOptions(themeColors) {
|
|
289711
|
+
return {
|
|
289712
|
+
backgroundColor: withAlpha(themeColors.backgroundPanel, 0.85),
|
|
289713
|
+
titleBarColor: withAlpha(themeColors.backgroundElement, 0.9),
|
|
289714
|
+
titleBarTextColor: themeColors.text,
|
|
289715
|
+
colorDefault: themeColors.textMuted,
|
|
289716
|
+
colorInfo: themeColors.info,
|
|
289717
|
+
colorWarn: themeColors.warning,
|
|
289718
|
+
colorError: themeColors.error,
|
|
289719
|
+
colorDebug: themeColors.textMuted,
|
|
289720
|
+
selectionColor: withAlpha(themeColors.primary, 0.35),
|
|
289721
|
+
cursorColor: themeColors.primary,
|
|
289722
|
+
copyButtonColor: themeColors.primary
|
|
289723
|
+
};
|
|
289724
|
+
}
|
|
289725
|
+
function ConsoleThemeSync() {
|
|
289726
|
+
const { colors: colors2 } = useTheme();
|
|
289727
|
+
const renderer = useRenderer();
|
|
289728
|
+
import_react85.useEffect(() => {
|
|
289729
|
+
overlayThemeRef.current = colors2;
|
|
289730
|
+
const c = renderer.console;
|
|
289731
|
+
c.backgroundColor = withAlpha(colors2.backgroundPanel, 0.85);
|
|
289732
|
+
c._rgbaTitleBar = withAlpha(colors2.backgroundElement, 0.9);
|
|
289733
|
+
c._rgbaTitleBarText = colors2.text;
|
|
289734
|
+
c._rgbaDefault = colors2.textMuted;
|
|
289735
|
+
c._rgbaInfo = colors2.info;
|
|
289736
|
+
c._rgbaWarn = colors2.warning;
|
|
289737
|
+
c._rgbaError = colors2.error;
|
|
289738
|
+
c._rgbaDebug = colors2.textMuted;
|
|
289739
|
+
c._rgbaSelection = withAlpha(colors2.primary, 0.35);
|
|
289740
|
+
c._rgbaCursor = colors2.primary;
|
|
289741
|
+
c._rgbaCopyButton = colors2.primary;
|
|
289742
|
+
c.markNeedsRerender();
|
|
289743
|
+
}, [colors2]);
|
|
289744
|
+
return null;
|
|
289745
|
+
}
|
|
289746
|
+
|
|
289747
|
+
// src/tui/clipboard.ts
|
|
289748
|
+
function createClipboardManager(renderer) {
|
|
289749
|
+
let clipboardNotifExpiry = 0;
|
|
289750
|
+
const copyToClipboard = (text2) => {
|
|
289751
|
+
renderer.copyToClipboardOSC52(text2);
|
|
289752
|
+
try {
|
|
289753
|
+
const proc = Bun.spawn(process.platform === "darwin" ? ["pbcopy"] : ["xclip", "-selection", "clipboard"], { stdin: "pipe" });
|
|
289754
|
+
proc.stdin.write(text2);
|
|
289755
|
+
proc.stdin.end();
|
|
289756
|
+
} catch {}
|
|
289757
|
+
clipboardNotifExpiry = Date.now() + 2000;
|
|
289758
|
+
renderer.requestRender();
|
|
289759
|
+
setTimeout(() => renderer.requestRender(), 2010);
|
|
289760
|
+
};
|
|
289761
|
+
const notifLabel = "Copied to clipboard";
|
|
289762
|
+
const notifPadX = 1;
|
|
289763
|
+
const notifBoxWidth = 1 + notifPadX + notifLabel.length + notifPadX + 1;
|
|
289764
|
+
const notifBoxHeight = 3;
|
|
289765
|
+
const notifMargin = 1;
|
|
289766
|
+
renderer.addPostProcessFn((buffer) => {
|
|
289767
|
+
if (Date.now() < clipboardNotifExpiry && overlayThemeRef.current) {
|
|
289768
|
+
const c = overlayThemeRef.current;
|
|
289769
|
+
const x4 = buffer.width - notifBoxWidth - notifMargin;
|
|
289770
|
+
const y3 = notifMargin;
|
|
289771
|
+
buffer.fillRect(x4, y3, notifBoxWidth, notifBoxHeight, c.backgroundElement);
|
|
289772
|
+
buffer.drawBox({
|
|
289773
|
+
x: x4,
|
|
289774
|
+
y: y3,
|
|
289775
|
+
width: notifBoxWidth,
|
|
289776
|
+
height: notifBoxHeight,
|
|
289777
|
+
border: true,
|
|
289778
|
+
borderColor: c.border,
|
|
289779
|
+
backgroundColor: c.backgroundElement,
|
|
289780
|
+
shouldFill: false
|
|
289781
|
+
});
|
|
289782
|
+
buffer.drawText(notifLabel, x4 + 1 + notifPadX, y3 + 1, c.text, c.backgroundElement);
|
|
289783
|
+
}
|
|
289784
|
+
});
|
|
289785
|
+
renderer.console.onCopySelection = copyToClipboard;
|
|
289786
|
+
return { copyToClipboard };
|
|
289787
|
+
}
|
|
289788
|
+
|
|
289789
|
+
// src/tui/auto-copy.ts
|
|
289790
|
+
function setupAutoCopy(renderer, copyToClipboard) {
|
|
289791
|
+
renderer.console.getCopyButtonLabel = () => "Select to copy";
|
|
289792
|
+
const originalHandleMouse = renderer.console.handleMouse.bind(renderer.console);
|
|
289793
|
+
renderer.console.handleMouse = (event) => {
|
|
289794
|
+
const result = originalHandleMouse(event);
|
|
289795
|
+
if (event.type === "up") {
|
|
289796
|
+
const c = renderer.console;
|
|
289797
|
+
if (typeof c.hasSelection === "function" && c.hasSelection()) {
|
|
289798
|
+
c.triggerCopy();
|
|
289799
|
+
}
|
|
289800
|
+
}
|
|
289801
|
+
return result;
|
|
289802
|
+
};
|
|
289803
|
+
renderer.on("selection", (selection) => {
|
|
289804
|
+
if (selection && !selection.isDragging) {
|
|
289805
|
+
const text2 = selection.getSelectedText();
|
|
289806
|
+
if (text2) {
|
|
289807
|
+
copyToClipboard(text2);
|
|
289808
|
+
}
|
|
289809
|
+
process.nextTick(() => renderer.clearSelection());
|
|
289810
|
+
}
|
|
289811
|
+
});
|
|
289812
|
+
}
|
|
289813
|
+
|
|
289637
289814
|
// src/tui/index.tsx
|
|
289638
289815
|
function App({ appConfig }) {
|
|
289639
|
-
const [focusIndex, setFocusIndex] =
|
|
289640
|
-
const [cwd, setCwd] =
|
|
289641
|
-
const [ctrlCPressTime, setCtrlCPressTime] =
|
|
289642
|
-
const [showExitWarning, setShowExitWarning] =
|
|
289643
|
-
const [inputKey, setInputKey] =
|
|
289644
|
-
const [showSessionsDialog, setShowSessionsDialog] =
|
|
289645
|
-
const [showShortcutsDialog, setShowShortcutsDialog] =
|
|
289816
|
+
const [focusIndex, setFocusIndex] = import_react88.useState(0);
|
|
289817
|
+
const [cwd, setCwd] = import_react88.useState(process.cwd());
|
|
289818
|
+
const [ctrlCPressTime, setCtrlCPressTime] = import_react88.useState(null);
|
|
289819
|
+
const [showExitWarning, setShowExitWarning] = import_react88.useState(false);
|
|
289820
|
+
const [inputKey, setInputKey] = import_react88.useState(0);
|
|
289821
|
+
const [showSessionsDialog, setShowSessionsDialog] = import_react88.useState(false);
|
|
289822
|
+
const [showShortcutsDialog, setShowShortcutsDialog] = import_react88.useState(false);
|
|
289646
289823
|
const navigableItems = ["command-input"];
|
|
289647
289824
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ConfigProvider, {
|
|
289648
289825
|
config: appConfig,
|
|
@@ -289707,14 +289884,14 @@ function AppContent({
|
|
|
289707
289884
|
const { toast } = useToast();
|
|
289708
289885
|
const { refocusPrompt } = useFocus();
|
|
289709
289886
|
const { setExternalDialogOpen } = useDialog();
|
|
289710
|
-
|
|
289887
|
+
import_react88.useEffect(() => {
|
|
289711
289888
|
checkForUpdate().then(({ updateAvailable, currentVersion, latestVersion }) => {
|
|
289712
289889
|
if (!updateAvailable)
|
|
289713
289890
|
return;
|
|
289714
289891
|
toast(`Update available: v${currentVersion} → v${latestVersion}. Run: pensar upgrade`, "warn", 8000);
|
|
289715
289892
|
});
|
|
289716
289893
|
}, []);
|
|
289717
|
-
|
|
289894
|
+
import_react88.useEffect(() => {
|
|
289718
289895
|
if (route.data.type !== "base")
|
|
289719
289896
|
return;
|
|
289720
289897
|
if (!config3.data.responsibleUseAccepted && route.data.path !== "disclosure") {
|
|
@@ -289723,7 +289900,7 @@ function AppContent({
|
|
|
289723
289900
|
route.navigate({ type: "base", path: "providers" });
|
|
289724
289901
|
}
|
|
289725
289902
|
}, [config3.data.responsibleUseAccepted, route.data]);
|
|
289726
|
-
|
|
289903
|
+
import_react88.useEffect(() => {
|
|
289727
289904
|
if (showExitWarning) {
|
|
289728
289905
|
const timer = setTimeout(() => {
|
|
289729
289906
|
setShowExitWarning(false);
|
|
@@ -289912,7 +290089,14 @@ async function main2() {
|
|
|
289912
290089
|
} else {
|
|
289913
290090
|
mode = await detectTerminalMode();
|
|
289914
290091
|
}
|
|
289915
|
-
const
|
|
290092
|
+
const themeColors = resolveThemeColors(getTheme(themeName), mode);
|
|
290093
|
+
overlayThemeRef.current = themeColors;
|
|
290094
|
+
const renderer = await createCliRenderer({
|
|
290095
|
+
exitOnCtrlC: false,
|
|
290096
|
+
consoleOptions: buildConsoleOptions(themeColors)
|
|
290097
|
+
});
|
|
290098
|
+
const { copyToClipboard } = createClipboardManager(renderer);
|
|
290099
|
+
setupAutoCopy(renderer, copyToClipboard);
|
|
289916
290100
|
const cleanup = () => {
|
|
289917
290101
|
renderer.destroy();
|
|
289918
290102
|
process.exit(0);
|
|
@@ -289934,16 +290118,19 @@ async function main2() {
|
|
|
289934
290118
|
createRoot(renderer).render(/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ThemeProvider, {
|
|
289935
290119
|
initialTheme: themeName,
|
|
289936
290120
|
initialMode: mode,
|
|
289937
|
-
children:
|
|
289938
|
-
|
|
289939
|
-
|
|
289940
|
-
|
|
289941
|
-
|
|
289942
|
-
|
|
289943
|
-
|
|
289944
|
-
|
|
289945
|
-
|
|
289946
|
-
|
|
289947
|
-
|
|
290121
|
+
children: [
|
|
290122
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ConsoleThemeSync, {}, undefined, false, undefined, this),
|
|
290123
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ToastProvider, {
|
|
290124
|
+
children: [
|
|
290125
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ErrorBoundary2, {
|
|
290126
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(App, {
|
|
290127
|
+
appConfig
|
|
290128
|
+
}, undefined, false, undefined, this)
|
|
290129
|
+
}, undefined, false, undefined, this),
|
|
290130
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ToastContainer, {}, undefined, false, undefined, this)
|
|
290131
|
+
]
|
|
290132
|
+
}, undefined, true, undefined, this)
|
|
290133
|
+
]
|
|
290134
|
+
}, undefined, true, undefined, this));
|
|
289948
290135
|
}
|
|
289949
290136
|
main2();
|