@pensar/apex 0.0.103 → 0.0.104
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/bin/pensar.js +43 -0
- package/build/auth.js +23 -6
- package/build/index.js +174 -60
- package/package.json +1 -1
package/bin/pensar.js
CHANGED
|
@@ -73,6 +73,26 @@ if (command === "benchmark") {
|
|
|
73
73
|
process.argv = [process.argv[0], uninstallPath, ...args.slice(1)];
|
|
74
74
|
|
|
75
75
|
await import(uninstallPath);
|
|
76
|
+
} else if (command === "projects") {
|
|
77
|
+
const p = join(__dirname, "..", "build", "projects.js");
|
|
78
|
+
process.argv = [process.argv[0], p, ...args.slice(1)];
|
|
79
|
+
await import(p);
|
|
80
|
+
} else if (command === "pentests") {
|
|
81
|
+
const p = join(__dirname, "..", "build", "pentests.js");
|
|
82
|
+
process.argv = [process.argv[0], p, ...args.slice(1)];
|
|
83
|
+
await import(p);
|
|
84
|
+
} else if (command === "issues") {
|
|
85
|
+
const p = join(__dirname, "..", "build", "issues.js");
|
|
86
|
+
process.argv = [process.argv[0], p, ...args.slice(1)];
|
|
87
|
+
await import(p);
|
|
88
|
+
} else if (command === "fixes") {
|
|
89
|
+
const p = join(__dirname, "..", "build", "fixes.js");
|
|
90
|
+
process.argv = [process.argv[0], p, ...args.slice(1)];
|
|
91
|
+
await import(p);
|
|
92
|
+
} else if (command === "logs") {
|
|
93
|
+
const p = join(__dirname, "..", "build", "logs.js");
|
|
94
|
+
process.argv = [process.argv[0], p, ...args.slice(1)];
|
|
95
|
+
await import(p);
|
|
76
96
|
} else if (command === "upgrade" || command === "update") {
|
|
77
97
|
const currentVersion = getCurrentVersion();
|
|
78
98
|
console.log(`Current version: v${currentVersion}`);
|
|
@@ -109,6 +129,21 @@ if (command === "benchmark") {
|
|
|
109
129
|
console.log(
|
|
110
130
|
" pensar auth Connect to Pensar Console for managed inference"
|
|
111
131
|
);
|
|
132
|
+
console.log(
|
|
133
|
+
" pensar projects List workspace projects"
|
|
134
|
+
);
|
|
135
|
+
console.log(
|
|
136
|
+
" pensar pentests List and manage pentests"
|
|
137
|
+
);
|
|
138
|
+
console.log(
|
|
139
|
+
" pensar issues List and manage security issues"
|
|
140
|
+
);
|
|
141
|
+
console.log(
|
|
142
|
+
" pensar fixes View security fixes"
|
|
143
|
+
);
|
|
144
|
+
console.log(
|
|
145
|
+
" pensar logs View agent execution logs"
|
|
146
|
+
);
|
|
112
147
|
console.log();
|
|
113
148
|
console.log("Options:");
|
|
114
149
|
console.log(" -h, --help Show this help message");
|
|
@@ -226,6 +261,14 @@ if (command === "benchmark") {
|
|
|
226
261
|
console.log(" pensar auth");
|
|
227
262
|
console.log(" pensar auth status");
|
|
228
263
|
console.log(" pensar auth logout");
|
|
264
|
+
console.log();
|
|
265
|
+
console.log("Console API:");
|
|
266
|
+
console.log(" pensar projects");
|
|
267
|
+
console.log(" pensar pentests <projectId>");
|
|
268
|
+
console.log(" pensar issues <projectId>");
|
|
269
|
+
console.log(" pensar issues get <issueId>");
|
|
270
|
+
console.log(" pensar fixes <issueId>");
|
|
271
|
+
console.log(" pensar logs <issueId>");
|
|
229
272
|
} else if (args.length === 0) {
|
|
230
273
|
// No command specified, run the TUI
|
|
231
274
|
const appPath = join(__dirname, "..", "build", "index.js");
|
package/build/auth.js
CHANGED
|
@@ -8,7 +8,7 @@ import fs from "fs/promises";
|
|
|
8
8
|
// package.json
|
|
9
9
|
var package_default = {
|
|
10
10
|
name: "@pensar/apex",
|
|
11
|
-
version: "0.0.
|
|
11
|
+
version: "0.0.104",
|
|
12
12
|
description: "AI-powered penetration testing CLI tool with terminal UI",
|
|
13
13
|
module: "src/tui/index.tsx",
|
|
14
14
|
main: "build/index.js",
|
|
@@ -557,14 +557,31 @@ async function status() {
|
|
|
557
557
|
console.log("\nRun `pensar auth login` to connect.");
|
|
558
558
|
return;
|
|
559
559
|
}
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
560
|
+
if (!appConfig.accessToken && appConfig.pensarAPIKey && !appConfig.workspaceSlug) {
|
|
561
|
+
try {
|
|
562
|
+
const apiUrl = getPensarApiUrl();
|
|
563
|
+
const res = await fetch(`${apiUrl}/auth/validate`, {
|
|
564
|
+
headers: { Authorization: `Bearer ${appConfig.pensarAPIKey}` }
|
|
565
|
+
});
|
|
566
|
+
if (res.ok) {
|
|
567
|
+
const data = await res.json();
|
|
568
|
+
if (data.workspace) {
|
|
569
|
+
await config.update({
|
|
570
|
+
workspaceId: data.workspace.id,
|
|
571
|
+
workspaceSlug: data.workspace.slug
|
|
572
|
+
});
|
|
573
|
+
appConfig.workspaceId = data.workspace.id;
|
|
574
|
+
appConfig.workspaceSlug = data.workspace.slug;
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
} catch {}
|
|
563
578
|
}
|
|
579
|
+
console.log("\u2713 Connected to Pensar Console");
|
|
580
|
+
console.log(` Workspace: ${appConfig.workspaceSlug ?? "not set"}`);
|
|
564
581
|
if (appConfig.accessToken) {
|
|
565
|
-
console.log(" Auth: WorkOS
|
|
582
|
+
console.log(" Auth: WorkOS");
|
|
566
583
|
} else {
|
|
567
|
-
console.log(" Auth: API key
|
|
584
|
+
console.log(" Auth: API key");
|
|
568
585
|
}
|
|
569
586
|
}
|
|
570
587
|
function showHelp() {
|
package/build/index.js
CHANGED
|
@@ -31977,7 +31977,7 @@ var package_default2;
|
|
|
31977
31977
|
var init_package = __esm(() => {
|
|
31978
31978
|
package_default2 = {
|
|
31979
31979
|
name: "@pensar/apex",
|
|
31980
|
-
version: "0.0.
|
|
31980
|
+
version: "0.0.104",
|
|
31981
31981
|
description: "AI-powered penetration testing CLI tool with terminal UI",
|
|
31982
31982
|
module: "src/tui/index.tsx",
|
|
31983
31983
|
main: "build/index.js",
|
|
@@ -273074,7 +273074,7 @@ var useTerminalDimensions = () => {
|
|
|
273074
273074
|
};
|
|
273075
273075
|
|
|
273076
273076
|
// src/tui/index.tsx
|
|
273077
|
-
var
|
|
273077
|
+
var import_react90 = __toESM(require_react(), 1);
|
|
273078
273078
|
|
|
273079
273079
|
// src/tui/components/footer.tsx
|
|
273080
273080
|
import os6 from "os";
|
|
@@ -281225,6 +281225,98 @@ var actionsByKey = new Map(allActions.map((action) => [action.key, action]));
|
|
|
281225
281225
|
var actionsById = new Map(allActions.map((action) => [action.id, action]));
|
|
281226
281226
|
// src/tui/keybindings/keybind.tsx
|
|
281227
281227
|
var LeaderKeyContext = import_react62.createContext(null);
|
|
281228
|
+
// src/tui/terminal-focus.ts
|
|
281229
|
+
var bracketedFocusModeEnabled = false;
|
|
281230
|
+
function setupTerminalFocusHandling(renderer, options = {}) {
|
|
281231
|
+
const { onTerminalFocus, debug = false } = options;
|
|
281232
|
+
const log2 = (...args) => {
|
|
281233
|
+
if (debug)
|
|
281234
|
+
console.error("[TerminalFocus]", ...args);
|
|
281235
|
+
};
|
|
281236
|
+
const enableBracketedFocus = () => {
|
|
281237
|
+
if (process.stdout.isTTY) {
|
|
281238
|
+
process.stdout.write("\x1B[?1004h");
|
|
281239
|
+
bracketedFocusModeEnabled = true;
|
|
281240
|
+
log2("Enabled bracketed focus mode");
|
|
281241
|
+
}
|
|
281242
|
+
};
|
|
281243
|
+
const disableBracketedFocus = () => {
|
|
281244
|
+
if (process.stdout.isTTY && bracketedFocusModeEnabled) {
|
|
281245
|
+
process.stdout.write("\x1B[?1004l");
|
|
281246
|
+
bracketedFocusModeEnabled = false;
|
|
281247
|
+
log2("Disabled bracketed focus mode");
|
|
281248
|
+
}
|
|
281249
|
+
};
|
|
281250
|
+
const showCursor = () => {
|
|
281251
|
+
if (process.stdout.isTTY) {
|
|
281252
|
+
process.stdout.write("\x1B[?25h");
|
|
281253
|
+
log2("Showed cursor");
|
|
281254
|
+
}
|
|
281255
|
+
};
|
|
281256
|
+
const handleFocusIn = () => {
|
|
281257
|
+
log2("Terminal gained focus");
|
|
281258
|
+
showCursor();
|
|
281259
|
+
renderer.requestRender();
|
|
281260
|
+
if (onTerminalFocus) {
|
|
281261
|
+
setTimeout(() => {
|
|
281262
|
+
onTerminalFocus();
|
|
281263
|
+
log2("Re-focused prompt input");
|
|
281264
|
+
}, 10);
|
|
281265
|
+
}
|
|
281266
|
+
};
|
|
281267
|
+
const handleFocusOut = () => {
|
|
281268
|
+
log2("Terminal lost focus");
|
|
281269
|
+
};
|
|
281270
|
+
const handleSigCont = () => {
|
|
281271
|
+
log2("Received SIGCONT (terminal resumed)");
|
|
281272
|
+
showCursor();
|
|
281273
|
+
renderer.requestRender();
|
|
281274
|
+
if (onTerminalFocus) {
|
|
281275
|
+
setTimeout(() => {
|
|
281276
|
+
onTerminalFocus();
|
|
281277
|
+
log2("Re-focused prompt input after SIGCONT");
|
|
281278
|
+
}, 10);
|
|
281279
|
+
}
|
|
281280
|
+
};
|
|
281281
|
+
let stdinListenerActive = false;
|
|
281282
|
+
const handleStdinData = (data) => {
|
|
281283
|
+
const str = data.toString();
|
|
281284
|
+
if (str.includes("\x1B[I")) {
|
|
281285
|
+
handleFocusIn();
|
|
281286
|
+
}
|
|
281287
|
+
if (str.includes("\x1B[O")) {
|
|
281288
|
+
handleFocusOut();
|
|
281289
|
+
}
|
|
281290
|
+
};
|
|
281291
|
+
const setupListeners = () => {
|
|
281292
|
+
enableBracketedFocus();
|
|
281293
|
+
showCursor();
|
|
281294
|
+
process.on("SIGCONT", handleSigCont);
|
|
281295
|
+
if (process.stdin.isTTY && !stdinListenerActive) {
|
|
281296
|
+
process.stdin.on("data", handleStdinData);
|
|
281297
|
+
stdinListenerActive = true;
|
|
281298
|
+
log2("Set up stdin listener for bracketed focus events");
|
|
281299
|
+
}
|
|
281300
|
+
};
|
|
281301
|
+
const cleanup = () => {
|
|
281302
|
+
log2("Cleaning up terminal focus handling");
|
|
281303
|
+
disableBracketedFocus();
|
|
281304
|
+
process.off("SIGCONT", handleSigCont);
|
|
281305
|
+
if (stdinListenerActive) {
|
|
281306
|
+
process.stdin.off("data", handleStdinData);
|
|
281307
|
+
stdinListenerActive = false;
|
|
281308
|
+
}
|
|
281309
|
+
};
|
|
281310
|
+
setupListeners();
|
|
281311
|
+
return cleanup;
|
|
281312
|
+
}
|
|
281313
|
+
function cleanupTerminalFocusMode() {
|
|
281314
|
+
if (process.stdout.isTTY && bracketedFocusModeEnabled) {
|
|
281315
|
+
process.stdout.write("\x1B[?1004l");
|
|
281316
|
+
bracketedFocusModeEnabled = false;
|
|
281317
|
+
}
|
|
281318
|
+
}
|
|
281319
|
+
|
|
281228
281320
|
// src/tui/keybindings/registry.ts
|
|
281229
281321
|
function createKeybindings(deps) {
|
|
281230
281322
|
const {
|
|
@@ -281253,6 +281345,7 @@ function createKeybindings(deps) {
|
|
|
281253
281345
|
const now2 = Date.now();
|
|
281254
281346
|
const lastPress = ctrlCPressTime;
|
|
281255
281347
|
if (lastPress && now2 - lastPress < 1000) {
|
|
281348
|
+
cleanupTerminalFocusMode();
|
|
281256
281349
|
renderer.destroy();
|
|
281257
281350
|
process.exit(0);
|
|
281258
281351
|
} else {
|
|
@@ -291109,74 +291202,92 @@ function setupAutoCopy(renderer, copyToClipboard) {
|
|
|
291109
291202
|
});
|
|
291110
291203
|
}
|
|
291111
291204
|
|
|
291205
|
+
// src/tui/components/terminal-focus-handler.tsx
|
|
291206
|
+
var import_react87 = __toESM(require_react(), 1);
|
|
291207
|
+
function TerminalFocusHandler() {
|
|
291208
|
+
const { refocusPrompt } = useFocus();
|
|
291209
|
+
const renderer = useRenderer();
|
|
291210
|
+
import_react87.useEffect(() => {
|
|
291211
|
+
const cleanup = setupTerminalFocusHandling(renderer, {
|
|
291212
|
+
onTerminalFocus: refocusPrompt,
|
|
291213
|
+
debug: false
|
|
291214
|
+
});
|
|
291215
|
+
return cleanup;
|
|
291216
|
+
}, [renderer, refocusPrompt]);
|
|
291217
|
+
return null;
|
|
291218
|
+
}
|
|
291219
|
+
|
|
291112
291220
|
// src/tui/index.tsx
|
|
291113
291221
|
function App({ appConfig }) {
|
|
291114
|
-
const [focusIndex, setFocusIndex] =
|
|
291115
|
-
const [cwd, setCwd] =
|
|
291116
|
-
const [ctrlCPressTime, setCtrlCPressTime] =
|
|
291117
|
-
const [showExitWarning, setShowExitWarning] =
|
|
291118
|
-
const [inputKey, setInputKey] =
|
|
291119
|
-
const [showSessionsDialog, setShowSessionsDialog] =
|
|
291120
|
-
const [showShortcutsDialog, setShowShortcutsDialog] =
|
|
291121
|
-
const [showThemeDialog, setShowThemeDialog] =
|
|
291122
|
-
const [showAuthDialog, setShowAuthDialog] =
|
|
291123
|
-
const [showPentestDialog, setShowPentestDialog] =
|
|
291124
|
-
const [pendingPentestFlags, setPendingPentestFlags] =
|
|
291222
|
+
const [focusIndex, setFocusIndex] = import_react90.useState(0);
|
|
291223
|
+
const [cwd, setCwd] = import_react90.useState(process.cwd());
|
|
291224
|
+
const [ctrlCPressTime, setCtrlCPressTime] = import_react90.useState(null);
|
|
291225
|
+
const [showExitWarning, setShowExitWarning] = import_react90.useState(false);
|
|
291226
|
+
const [inputKey, setInputKey] = import_react90.useState(0);
|
|
291227
|
+
const [showSessionsDialog, setShowSessionsDialog] = import_react90.useState(false);
|
|
291228
|
+
const [showShortcutsDialog, setShowShortcutsDialog] = import_react90.useState(false);
|
|
291229
|
+
const [showThemeDialog, setShowThemeDialog] = import_react90.useState(false);
|
|
291230
|
+
const [showAuthDialog, setShowAuthDialog] = import_react90.useState(false);
|
|
291231
|
+
const [showPentestDialog, setShowPentestDialog] = import_react90.useState(false);
|
|
291232
|
+
const [pendingPentestFlags, setPendingPentestFlags] = import_react90.useState(undefined);
|
|
291125
291233
|
const navigableItems = ["command-input"];
|
|
291126
291234
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ConfigProvider, {
|
|
291127
291235
|
config: appConfig,
|
|
291128
291236
|
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(SessionProvider, {
|
|
291129
291237
|
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(RouteProvider, {
|
|
291130
291238
|
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(FocusProvider, {
|
|
291131
|
-
children:
|
|
291132
|
-
|
|
291133
|
-
|
|
291134
|
-
|
|
291135
|
-
|
|
291136
|
-
|
|
291137
|
-
|
|
291138
|
-
|
|
291139
|
-
|
|
291140
|
-
|
|
291141
|
-
|
|
291142
|
-
|
|
291143
|
-
deps: {
|
|
291144
|
-
ctrlCPressTime,
|
|
291145
|
-
setCtrlCPressTime,
|
|
291146
|
-
setShowExitWarning,
|
|
291147
|
-
setInputKey,
|
|
291148
|
-
setShowSessionsDialog,
|
|
291149
|
-
setShowShortcutsDialog,
|
|
291150
|
-
setFocusIndex,
|
|
291151
|
-
navigableItems
|
|
291239
|
+
children: [
|
|
291240
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(TerminalFocusHandler, {}, undefined, false, undefined, this),
|
|
291241
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(InputProvider, {
|
|
291242
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(DialogProvider, {
|
|
291243
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(AgentProvider, {
|
|
291244
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(CommandProvider, {
|
|
291245
|
+
onOpenSessionsDialog: () => setShowSessionsDialog(true),
|
|
291246
|
+
onOpenThemeDialog: () => setShowThemeDialog(true),
|
|
291247
|
+
onOpenAuthDialog: () => setShowAuthDialog(true),
|
|
291248
|
+
onOpenPentestDialog: (flags) => {
|
|
291249
|
+
setPendingPentestFlags(flags);
|
|
291250
|
+
setShowPentestDialog(true);
|
|
291152
291251
|
},
|
|
291153
|
-
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(
|
|
291154
|
-
|
|
291155
|
-
|
|
291156
|
-
|
|
291157
|
-
|
|
291158
|
-
|
|
291159
|
-
|
|
291160
|
-
|
|
291161
|
-
|
|
291162
|
-
|
|
291163
|
-
|
|
291164
|
-
|
|
291165
|
-
|
|
291166
|
-
|
|
291167
|
-
|
|
291168
|
-
|
|
291169
|
-
|
|
291170
|
-
|
|
291171
|
-
|
|
291172
|
-
|
|
291252
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(KeybindingProvider, {
|
|
291253
|
+
deps: {
|
|
291254
|
+
ctrlCPressTime,
|
|
291255
|
+
setCtrlCPressTime,
|
|
291256
|
+
setShowExitWarning,
|
|
291257
|
+
setInputKey,
|
|
291258
|
+
setShowSessionsDialog,
|
|
291259
|
+
setShowShortcutsDialog,
|
|
291260
|
+
setFocusIndex,
|
|
291261
|
+
navigableItems
|
|
291262
|
+
},
|
|
291263
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(AppContent, {
|
|
291264
|
+
focusIndex,
|
|
291265
|
+
showSessionsDialog,
|
|
291266
|
+
setShowSessionsDialog,
|
|
291267
|
+
showShortcutsDialog,
|
|
291268
|
+
setShowShortcutsDialog,
|
|
291269
|
+
showThemeDialog,
|
|
291270
|
+
setShowThemeDialog,
|
|
291271
|
+
showAuthDialog,
|
|
291272
|
+
setShowAuthDialog,
|
|
291273
|
+
showPentestDialog,
|
|
291274
|
+
setShowPentestDialog,
|
|
291275
|
+
pendingPentestFlags,
|
|
291276
|
+
setPendingPentestFlags,
|
|
291277
|
+
cwd,
|
|
291278
|
+
setCtrlCPressTime,
|
|
291279
|
+
showExitWarning,
|
|
291280
|
+
setShowExitWarning,
|
|
291281
|
+
inputKey,
|
|
291282
|
+
setInputKey
|
|
291283
|
+
}, undefined, false, undefined, this)
|
|
291173
291284
|
}, undefined, false, undefined, this)
|
|
291174
291285
|
}, undefined, false, undefined, this)
|
|
291175
291286
|
}, undefined, false, undefined, this)
|
|
291176
291287
|
}, undefined, false, undefined, this)
|
|
291177
291288
|
}, undefined, false, undefined, this)
|
|
291178
|
-
|
|
291179
|
-
}, undefined,
|
|
291289
|
+
]
|
|
291290
|
+
}, undefined, true, undefined, this)
|
|
291180
291291
|
}, undefined, false, undefined, this)
|
|
291181
291292
|
}, undefined, false, undefined, this)
|
|
291182
291293
|
}, undefined, false, undefined, this);
|
|
@@ -291208,14 +291319,14 @@ function AppContent({
|
|
|
291208
291319
|
const { toast } = useToast();
|
|
291209
291320
|
const { refocusPrompt } = useFocus();
|
|
291210
291321
|
const { setExternalDialogOpen } = useDialog();
|
|
291211
|
-
|
|
291322
|
+
import_react90.useEffect(() => {
|
|
291212
291323
|
checkForUpdate().then(({ updateAvailable, currentVersion, latestVersion }) => {
|
|
291213
291324
|
if (!updateAvailable)
|
|
291214
291325
|
return;
|
|
291215
291326
|
toast(`Update available: v${currentVersion} → v${latestVersion}. Run: pensar upgrade`, "warn", 8000);
|
|
291216
291327
|
});
|
|
291217
291328
|
}, []);
|
|
291218
|
-
|
|
291329
|
+
import_react90.useEffect(() => {
|
|
291219
291330
|
if (route.data.type !== "base")
|
|
291220
291331
|
return;
|
|
291221
291332
|
if (!config3.data.responsibleUseAccepted && route.data.path !== "disclosure") {
|
|
@@ -291224,12 +291335,12 @@ function AppContent({
|
|
|
291224
291335
|
route.navigate({ type: "base", path: "providers" });
|
|
291225
291336
|
}
|
|
291226
291337
|
}, [config3.data.responsibleUseAccepted, route.data]);
|
|
291227
|
-
|
|
291338
|
+
import_react90.useEffect(() => {
|
|
291228
291339
|
if (showThemeDialog || showAuthDialog || showPentestDialog) {
|
|
291229
291340
|
setExternalDialogOpen(true);
|
|
291230
291341
|
}
|
|
291231
291342
|
}, [showThemeDialog, showAuthDialog, showPentestDialog]);
|
|
291232
|
-
|
|
291343
|
+
import_react90.useEffect(() => {
|
|
291233
291344
|
if (showExitWarning) {
|
|
291234
291345
|
const timer = setTimeout(() => {
|
|
291235
291346
|
setShowExitWarning(false);
|
|
@@ -291461,18 +291572,21 @@ async function main2() {
|
|
|
291461
291572
|
const { copyToClipboard } = createClipboardManager(renderer);
|
|
291462
291573
|
setupAutoCopy(renderer, copyToClipboard);
|
|
291463
291574
|
const cleanup = () => {
|
|
291575
|
+
cleanupTerminalFocusMode();
|
|
291464
291576
|
renderer.destroy();
|
|
291465
291577
|
process.exit(0);
|
|
291466
291578
|
};
|
|
291467
291579
|
process.on("SIGINT", cleanup);
|
|
291468
291580
|
process.on("SIGTERM", cleanup);
|
|
291469
291581
|
process.on("uncaughtException", (err) => {
|
|
291582
|
+
cleanupTerminalFocusMode();
|
|
291470
291583
|
renderer.destroy();
|
|
291471
291584
|
console.error("Uncaught exception:", err);
|
|
291472
291585
|
writeErrorLog(err, "UNCAUGHT");
|
|
291473
291586
|
process.exit(1);
|
|
291474
291587
|
});
|
|
291475
291588
|
process.on("unhandledRejection", (reason) => {
|
|
291589
|
+
cleanupTerminalFocusMode();
|
|
291476
291590
|
renderer.destroy();
|
|
291477
291591
|
console.error("Unhandled rejection:", reason);
|
|
291478
291592
|
writeErrorLog(reason, "UNHANDLED_REJECTION");
|