alvin-bot 5.6.2 → 5.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +1 -1
  3. package/dist/claude.js +1 -102
  4. package/dist/config.js +1 -96
  5. package/dist/engine.js +1 -90
  6. package/dist/find-claude-binary.js +1 -98
  7. package/dist/handlers/async-agent-chunk-handler.js +1 -50
  8. package/dist/handlers/background-bypass.js +1 -75
  9. package/dist/handlers/commands.js +1 -2336
  10. package/dist/handlers/cron-progress.js +1 -52
  11. package/dist/handlers/document.js +1 -194
  12. package/dist/handlers/message.js +1 -959
  13. package/dist/handlers/photo.js +1 -154
  14. package/dist/handlers/platform-message.js +1 -360
  15. package/dist/handlers/stuck-timer.js +1 -54
  16. package/dist/handlers/video.js +1 -237
  17. package/dist/handlers/voice.js +1 -148
  18. package/dist/i18n.js +1 -805
  19. package/dist/index.js +1 -697
  20. package/dist/init-data-dir.js +1 -98
  21. package/dist/middleware/auth.js +1 -233
  22. package/dist/migrate.js +1 -162
  23. package/dist/paths.js +1 -146
  24. package/dist/platforms/discord.js +1 -175
  25. package/dist/platforms/index.js +1 -130
  26. package/dist/platforms/signal.js +1 -205
  27. package/dist/platforms/slack-slash-parser.js +1 -32
  28. package/dist/platforms/slack.js +1 -501
  29. package/dist/platforms/telegram.js +1 -111
  30. package/dist/platforms/types.js +1 -8
  31. package/dist/platforms/whatsapp-auth-helpers.js +1 -53
  32. package/dist/platforms/whatsapp.js +1 -707
  33. package/dist/providers/claude-sdk-provider.js +1 -565
  34. package/dist/providers/codex-cli-provider.js +1 -134
  35. package/dist/providers/index.js +1 -7
  36. package/dist/providers/ollama-provider.js +1 -32
  37. package/dist/providers/openai-compatible.js +1 -406
  38. package/dist/providers/registry.js +1 -352
  39. package/dist/providers/runtime-header.js +1 -45
  40. package/dist/providers/tool-executor.js +1 -475
  41. package/dist/providers/types.js +1 -227
  42. package/dist/services/access.js +1 -144
  43. package/dist/services/allowed-users-gate.js +1 -56
  44. package/dist/services/alvin-dispatch.js +1 -130
  45. package/dist/services/alvin-mcp-tools.js +1 -104
  46. package/dist/services/asset-index.js +1 -224
  47. package/dist/services/async-agent-parser.js +1 -418
  48. package/dist/services/async-agent-watcher.js +1 -443
  49. package/dist/services/auto-diagnostic.js +1 -228
  50. package/dist/services/broadcast.js +1 -52
  51. package/dist/services/browser-manager.js +1 -562
  52. package/dist/services/browser-webfetch.js +1 -127
  53. package/dist/services/browser.js +1 -121
  54. package/dist/services/cdp-bootstrap.js +1 -357
  55. package/dist/services/compaction.js +1 -144
  56. package/dist/services/critical-notify.js +1 -203
  57. package/dist/services/cron-resolver.js +1 -58
  58. package/dist/services/cron-scheduling.js +1 -310
  59. package/dist/services/cron.js +1 -861
  60. package/dist/services/custom-tools.js +1 -317
  61. package/dist/services/delivery-queue.js +1 -173
  62. package/dist/services/delivery-registry.js +1 -21
  63. package/dist/services/disk-cleanup.js +1 -203
  64. package/dist/services/elevenlabs.js +1 -58
  65. package/dist/services/embeddings/auto-detect.js +1 -74
  66. package/dist/services/embeddings/fts5.js +1 -108
  67. package/dist/services/embeddings/gemini.js +1 -65
  68. package/dist/services/embeddings/index.js +1 -496
  69. package/dist/services/embeddings/ollama.js +1 -78
  70. package/dist/services/embeddings/openai.js +1 -49
  71. package/dist/services/embeddings/provider.js +1 -22
  72. package/dist/services/embeddings/vector-base.js +1 -113
  73. package/dist/services/embeddings-migration.js +1 -193
  74. package/dist/services/embeddings.js +1 -9
  75. package/dist/services/env-file.js +1 -50
  76. package/dist/services/exec-guard.js +1 -71
  77. package/dist/services/fallback-order.js +1 -154
  78. package/dist/services/file-permissions.js +1 -93
  79. package/dist/services/heartbeat-file.js +1 -65
  80. package/dist/services/heartbeat.js +1 -313
  81. package/dist/services/hooks.js +1 -44
  82. package/dist/services/imagegen.js +1 -72
  83. package/dist/services/language-detect.js +1 -154
  84. package/dist/services/markdown.js +1 -63
  85. package/dist/services/mcp.js +1 -263
  86. package/dist/services/memory-extractor.js +1 -178
  87. package/dist/services/memory-inject-mode.js +1 -43
  88. package/dist/services/memory-layers.js +1 -156
  89. package/dist/services/memory.js +1 -146
  90. package/dist/services/ollama-manager.js +1 -339
  91. package/dist/services/permissions-wizard.js +1 -291
  92. package/dist/services/personality.js +1 -376
  93. package/dist/services/plugins.js +1 -171
  94. package/dist/services/preflight.js +1 -292
  95. package/dist/services/process-manager.js +1 -291
  96. package/dist/services/release-highlights.js +1 -79
  97. package/dist/services/reminders.js +1 -97
  98. package/dist/services/restart.js +1 -48
  99. package/dist/services/security-audit.js +1 -74
  100. package/dist/services/self-diagnosis.js +1 -272
  101. package/dist/services/self-search.js +1 -129
  102. package/dist/services/session-persistence.js +1 -237
  103. package/dist/services/session.js +1 -282
  104. package/dist/services/skills.js +1 -290
  105. package/dist/services/ssrf-guard.js +1 -162
  106. package/dist/services/standing-orders.js +1 -29
  107. package/dist/services/steer-channel.js +1 -46
  108. package/dist/services/stop-controller.js +1 -52
  109. package/dist/services/subagent-dedup.js +1 -0
  110. package/dist/services/subagent-delivery.js +1 -452
  111. package/dist/services/subagent-stats.js +1 -123
  112. package/dist/services/subagents.js +1 -814
  113. package/dist/services/sudo.js +1 -329
  114. package/dist/services/telegram.js +1 -158
  115. package/dist/services/timing-safe-bearer.js +1 -51
  116. package/dist/services/tool-discovery.js +1 -214
  117. package/dist/services/trends.js +1 -580
  118. package/dist/services/updater.js +1 -291
  119. package/dist/services/usage-tracker.js +1 -144
  120. package/dist/services/users.js +1 -271
  121. package/dist/services/voice.js +1 -104
  122. package/dist/services/watchdog-brake.js +1 -154
  123. package/dist/services/watchdog.js +1 -311
  124. package/dist/services/workspaces.js +1 -276
  125. package/dist/tui/index.js +1 -667
  126. package/dist/util/console-formatter.js +1 -109
  127. package/dist/util/debounce.js +1 -24
  128. package/dist/util/telegram-error-filter.js +1 -62
  129. package/dist/version.js +1 -24
  130. package/dist/web/bind-strategy.js +1 -42
  131. package/dist/web/canvas.js +1 -30
  132. package/dist/web/doctor-api.js +1 -604
  133. package/dist/web/openai-compat.js +1 -252
  134. package/dist/web/server.js +1 -1831
  135. package/dist/web/setup-api.js +1 -1101
  136. package/package.json +5 -2
  137. package/dist/.metadata_never_index +0 -0
@@ -1,604 +1 @@
1
- /**
2
- * Doctor & Backup API — Self-healing, diagnostics, and backup/restore.
3
- *
4
- * Features:
5
- * - Health check (diagnose config issues)
6
- * - Auto-repair (fix common problems)
7
- * - Backup (snapshot all config files)
8
- * - Restore from backup
9
- * - Bot restart
10
- */
11
- import fs from "fs";
12
- import { resolve, dirname } from "path";
13
- import { execSync } from "child_process";
14
- import { BOT_ROOT, ENV_FILE, BACKUP_DIR, DATA_DIR, MEMORY_DIR, MEMORY_FILE, SOUL_FILE, SOUL_EXAMPLE, TOOLS_MD, TOOLS_JSON, CUSTOM_MODELS, CRON_FILE, MCP_CONFIG } from "../paths.js";
15
- import { writeSecure } from "../services/file-permissions.js";
16
- // Files to include in backups (absolute paths)
17
- const BACKUP_FILES = [
18
- { src: ENV_FILE, label: ".env" },
19
- { src: SOUL_FILE, label: "soul.md" },
20
- { src: resolve(BOT_ROOT, "CLAUDE.md"), label: "CLAUDE.md" },
21
- { src: TOOLS_MD, label: "tools.md" },
22
- { src: CUSTOM_MODELS, label: "custom-models.json" },
23
- { src: CRON_FILE, label: "cron-jobs.json" },
24
- { src: MCP_CONFIG, label: "mcp.json" },
25
- { src: MEMORY_FILE, label: "MEMORY.md" },
26
- ];
27
- function runHealthCheck() {
28
- const issues = [];
29
- // 1. Check .env exists
30
- if (!fs.existsSync(ENV_FILE)) {
31
- issues.push({
32
- severity: "error",
33
- category: "Config",
34
- message: ".env file missing",
35
- fix: "Create a default .env from .env.example",
36
- fixAction: "create-env",
37
- });
38
- }
39
- else {
40
- // Parse .env
41
- const envContent = fs.readFileSync(ENV_FILE, "utf-8");
42
- // Check BOT_TOKEN
43
- if (!envContent.includes("BOT_TOKEN=") || envContent.match(/BOT_TOKEN=\s*$/m)) {
44
- issues.push({
45
- severity: "error",
46
- category: "Telegram",
47
- message: "BOT_TOKEN not set — Telegram bot cannot start",
48
- });
49
- }
50
- // Check ALLOWED_USERS
51
- if (!envContent.includes("ALLOWED_USERS=") || envContent.match(/ALLOWED_USERS=\s*$/m)) {
52
- issues.push({
53
- severity: "warning",
54
- category: "Security",
55
- message: "ALLOWED_USERS not set — anyone can use the bot",
56
- });
57
- }
58
- // Check for syntax errors in .env
59
- const lines = envContent.split("\n");
60
- for (let i = 0; i < lines.length; i++) {
61
- const line = lines[i].trim();
62
- if (!line || line.startsWith("#"))
63
- continue;
64
- if (!line.includes("=")) {
65
- issues.push({
66
- severity: "error",
67
- category: "Config",
68
- message: `.env line ${i + 1}: Invalid format "${line.slice(0, 40)}..."`,
69
- fix: `Remove or fix the line`,
70
- fixAction: `fix-env-line:${i}`,
71
- });
72
- }
73
- }
74
- // Check for common issues
75
- if (envContent.includes('""') || envContent.match(/="?\s*$/m)) {
76
- issues.push({
77
- severity: "warning",
78
- category: "Config",
79
- message: "Empty values found in .env — some features may not work",
80
- });
81
- }
82
- }
83
- // 2. Check data directory
84
- if (!fs.existsSync(DATA_DIR)) {
85
- issues.push({
86
- severity: "error",
87
- category: "Files",
88
- message: "Data directory missing (~/.alvin-bot/)",
89
- fix: "Create data directory",
90
- fixAction: "create-docs",
91
- });
92
- }
93
- // 3. Check TOOLS.md validity (legacy tools.json as fallback)
94
- if (fs.existsSync(TOOLS_MD)) {
95
- // Validate TOOLS.md has at least one ## heading (tool definition)
96
- const content = fs.readFileSync(TOOLS_MD, "utf-8");
97
- if (!content.includes("## ")) {
98
- issues.push({
99
- severity: "warning",
100
- category: "Tools",
101
- message: "TOOLS.md contains no tool definitions (## headings missing)",
102
- fix: "Recreate TOOLS.md from TOOLS.example.md",
103
- fixAction: "fix-tools-json",
104
- });
105
- }
106
- }
107
- else if (fs.existsSync(TOOLS_JSON)) {
108
- try {
109
- JSON.parse(fs.readFileSync(TOOLS_JSON, "utf-8"));
110
- }
111
- catch {
112
- issues.push({
113
- severity: "error",
114
- category: "Tools",
115
- message: "tools.json is not valid JSON",
116
- fix: "Auto-repair JSON errors or reset to backup",
117
- fixAction: "fix-tools-json",
118
- });
119
- }
120
- }
121
- else {
122
- issues.push({
123
- severity: "info",
124
- category: "Tools",
125
- message: "No custom tools configured (tools.md missing)",
126
- fix: "Create tools.md from example",
127
- fixAction: "fix-tools-json",
128
- });
129
- }
130
- // 4. Check custom-models.json validity
131
- if (fs.existsSync(CUSTOM_MODELS)) {
132
- try {
133
- JSON.parse(fs.readFileSync(CUSTOM_MODELS, "utf-8"));
134
- }
135
- catch {
136
- issues.push({
137
- severity: "error",
138
- category: "Models",
139
- message: "custom-models.json is not valid JSON",
140
- fix: "Reset to empty array",
141
- fixAction: "fix-custom-models",
142
- });
143
- }
144
- }
145
- // 5. Check cron-jobs.json
146
- if (fs.existsSync(CRON_FILE)) {
147
- try {
148
- JSON.parse(fs.readFileSync(CRON_FILE, "utf-8"));
149
- }
150
- catch {
151
- issues.push({
152
- severity: "error",
153
- category: "Cron",
154
- message: "cron-jobs.json is not valid JSON",
155
- fix: "Reset to empty array",
156
- fixAction: "fix-cron-json",
157
- });
158
- }
159
- }
160
- // 6. Check soul.md exists
161
- if (!fs.existsSync(SOUL_FILE)) {
162
- issues.push({
163
- severity: "warning",
164
- category: "Personality",
165
- message: "soul.md missing — bot has no personality",
166
- fix: "Create default soul.md",
167
- fixAction: "create-soul",
168
- });
169
- }
170
- // 7. Check Node.js version
171
- try {
172
- const nodeVersion = process.version;
173
- const major = parseInt(nodeVersion.slice(1));
174
- if (major < 20) {
175
- issues.push({
176
- severity: "warning",
177
- category: "System",
178
- message: `Node.js ${nodeVersion} — v20+ recommended`,
179
- });
180
- }
181
- }
182
- catch { /* ignore */ }
183
- // 8. Check disk space (basic)
184
- try {
185
- const dfOutput = execSync("df -h . | tail -1", { cwd: BOT_ROOT, stdio: "pipe", timeout: 5000 }).toString();
186
- const parts = dfOutput.trim().split(/\s+/);
187
- const usagePercent = parseInt(parts[4]);
188
- if (usagePercent > 90) {
189
- issues.push({
190
- severity: "warning",
191
- category: "System",
192
- message: `Disk ${usagePercent}% full`,
193
- });
194
- }
195
- }
196
- catch { /* ignore */ }
197
- // 9. Check PM2
198
- try {
199
- execSync("pm2 jlist", { stdio: "pipe", timeout: 5000 });
200
- }
201
- catch {
202
- issues.push({
203
- severity: "info",
204
- category: "System",
205
- message: "PM2 not found — recommended for process management",
206
- });
207
- }
208
- // Good news if no issues
209
- if (issues.length === 0) {
210
- issues.push({
211
- severity: "info",
212
- category: "Status",
213
- message: "All good! No issues found.",
214
- });
215
- }
216
- return issues;
217
- }
218
- // ── Auto-Repair ─────────────────────────────────────────
219
- function autoRepair(action) {
220
- try {
221
- switch (action) {
222
- case "create-env": {
223
- const exampleFile = resolve(BOT_ROOT, ".env.example");
224
- if (fs.existsSync(exampleFile)) {
225
- fs.copyFileSync(exampleFile, ENV_FILE);
226
- // v4.12.2 — enforce 0o600 on fresh .env
227
- try {
228
- fs.chmodSync(ENV_FILE, 0o600);
229
- }
230
- catch { /* fs may not support */ }
231
- return { ok: true, message: ".env created from .env.example" };
232
- }
233
- writeSecure(ENV_FILE, "BOT_TOKEN=\nALLOWED_USERS=\nPRIMARY_PROVIDER=claude-sdk\n");
234
- return { ok: true, message: "Default .env created (BOT_TOKEN still needs to be set)" };
235
- }
236
- case "create-docs": {
237
- fs.mkdirSync(DATA_DIR, { recursive: true });
238
- fs.mkdirSync(MEMORY_DIR, { recursive: true });
239
- return { ok: true, message: "Data directory created" };
240
- }
241
- case "fix-tools-json": {
242
- // Reset to empty — prefer creating tools.md
243
- if (!fs.existsSync(TOOLS_MD)) {
244
- fs.mkdirSync(dirname(TOOLS_MD), { recursive: true });
245
- fs.writeFileSync(TOOLS_MD, "# Custom Tools\n\n> Define your own tools here. Each `##` heading creates a new tool.\n");
246
- return { ok: true, message: "tools.md created with empty toolset" };
247
- }
248
- fs.mkdirSync(dirname(TOOLS_JSON), { recursive: true });
249
- fs.writeFileSync(TOOLS_JSON, JSON.stringify({ tools: [] }, null, 2));
250
- return { ok: true, message: "tools.json reset to empty toolset" };
251
- }
252
- case "fix-custom-models": {
253
- fs.mkdirSync(dirname(CUSTOM_MODELS), { recursive: true });
254
- fs.writeFileSync(CUSTOM_MODELS, "[]");
255
- return { ok: true, message: "custom-models.json reset" };
256
- }
257
- case "fix-cron-json": {
258
- fs.mkdirSync(dirname(CRON_FILE), { recursive: true });
259
- fs.writeFileSync(CRON_FILE, "[]");
260
- return { ok: true, message: "cron-jobs.json reset" };
261
- }
262
- case "create-soul": {
263
- fs.mkdirSync(dirname(SOUL_FILE), { recursive: true });
264
- // Try to copy from example, otherwise create default
265
- if (fs.existsSync(SOUL_EXAMPLE)) {
266
- fs.copyFileSync(SOUL_EXAMPLE, SOUL_FILE);
267
- }
268
- else {
269
- fs.writeFileSync(SOUL_FILE, "# Alvin Bot — Personality\n\n" +
270
- "You are a helpful, direct, and competent AI assistant.\n" +
271
- "Reply clearly and precisely. Have opinions. Be genuinely helpful.\n");
272
- }
273
- return { ok: true, message: "Default soul.md created" };
274
- }
275
- default: {
276
- if (action.startsWith("fix-env-line:")) {
277
- const lineIdx = parseInt(action.split(":")[1]);
278
- const lines = fs.readFileSync(ENV_FILE, "utf-8").split("\n");
279
- if (lineIdx >= 0 && lineIdx < lines.length) {
280
- lines[lineIdx] = "# " + lines[lineIdx]; // Comment out broken line
281
- writeSecure(ENV_FILE, lines.join("\n"));
282
- return { ok: true, message: `Line ${lineIdx + 1} commented out` };
283
- }
284
- }
285
- return { ok: false, message: `Unknown action: ${action}` };
286
- }
287
- }
288
- }
289
- catch (err) {
290
- return { ok: false, message: err instanceof Error ? err.message : String(err) };
291
- }
292
- }
293
- // ── Backup ──────────────────────────────────────────────
294
- function createBackup(name) {
295
- const id = name || `backup-${new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19)}`;
296
- const backupPath = resolve(BACKUP_DIR, id);
297
- fs.mkdirSync(backupPath, { recursive: true });
298
- const backedUp = [];
299
- for (const { src, label } of BACKUP_FILES) {
300
- if (fs.existsSync(src)) {
301
- const dest = resolve(backupPath, label);
302
- fs.mkdirSync(dirname(dest), { recursive: true });
303
- fs.copyFileSync(src, dest);
304
- backedUp.push(label);
305
- }
306
- }
307
- // Also backup the memory directory
308
- if (fs.existsSync(MEMORY_DIR)) {
309
- const memBackup = resolve(backupPath, "memory");
310
- fs.mkdirSync(memBackup, { recursive: true });
311
- for (const f of fs.readdirSync(MEMORY_DIR)) {
312
- if (f.endsWith(".md")) {
313
- fs.copyFileSync(resolve(MEMORY_DIR, f), resolve(memBackup, f));
314
- backedUp.push(`memory/${f}`);
315
- }
316
- }
317
- }
318
- return { ok: true, id, files: backedUp, path: backupPath };
319
- }
320
- function listBackups() {
321
- if (!fs.existsSync(BACKUP_DIR))
322
- return [];
323
- return fs.readdirSync(BACKUP_DIR)
324
- .filter(d => {
325
- const p = resolve(BACKUP_DIR, d);
326
- return fs.statSync(p).isDirectory();
327
- })
328
- .map(d => {
329
- const p = resolve(BACKUP_DIR, d);
330
- const stat = fs.statSync(p);
331
- let fileCount = 0;
332
- let totalSize = 0;
333
- function countFiles(dir) {
334
- for (const f of fs.readdirSync(dir, { withFileTypes: true })) {
335
- if (f.isDirectory())
336
- countFiles(resolve(dir, f.name));
337
- else {
338
- fileCount++;
339
- totalSize += fs.statSync(resolve(dir, f.name)).size;
340
- }
341
- }
342
- }
343
- countFiles(p);
344
- return { id: d, createdAt: stat.mtimeMs, fileCount, size: totalSize };
345
- })
346
- .sort((a, b) => b.createdAt - a.createdAt);
347
- }
348
- function restoreBackup(id, files) {
349
- const backupPath = resolve(BACKUP_DIR, id);
350
- if (!backupPath.startsWith(BACKUP_DIR) || !fs.existsSync(backupPath)) {
351
- return { ok: false, restored: [], errors: ["Backup not found"] };
352
- }
353
- const restored = [];
354
- const errors = [];
355
- // Build label→dest mapping from BACKUP_FILES
356
- const labelToSrc = new Map(BACKUP_FILES.map(bf => [bf.label, bf.src]));
357
- const filesToRestore = files || BACKUP_FILES.map(bf => bf.label);
358
- for (const label of filesToRestore) {
359
- const src = resolve(backupPath, label);
360
- const dest = labelToSrc.get(label) || resolve(DATA_DIR, label);
361
- if (fs.existsSync(src)) {
362
- try {
363
- fs.mkdirSync(dirname(dest), { recursive: true });
364
- fs.copyFileSync(src, dest);
365
- restored.push(label);
366
- }
367
- catch (err) {
368
- errors.push(`${label}: ${err instanceof Error ? err.message : String(err)}`);
369
- }
370
- }
371
- }
372
- return { ok: errors.length === 0, restored, errors };
373
- }
374
- function getBackupFiles(id) {
375
- const backupPath = resolve(BACKUP_DIR, id);
376
- if (!backupPath.startsWith(BACKUP_DIR) || !fs.existsSync(backupPath))
377
- return [];
378
- const files = [];
379
- function walk(dir, prefix) {
380
- for (const f of fs.readdirSync(dir, { withFileTypes: true })) {
381
- const rel = prefix ? `${prefix}/${f.name}` : f.name;
382
- if (f.isDirectory())
383
- walk(resolve(dir, f.name), rel);
384
- else
385
- files.push(rel);
386
- }
387
- }
388
- walk(backupPath, "");
389
- return files;
390
- }
391
- function deleteBackup(id) {
392
- const backupPath = resolve(BACKUP_DIR, id);
393
- if (!backupPath.startsWith(BACKUP_DIR) || !fs.existsSync(backupPath))
394
- return false;
395
- fs.rmSync(backupPath, { recursive: true });
396
- return true;
397
- }
398
- // ── API Handler ─────────────────────────────────────────
399
- export async function handleDoctorAPI(req, res, urlPath, body) {
400
- res.setHeader("Content-Type", "application/json");
401
- // GET /api/doctor — run health check
402
- if (urlPath === "/api/doctor") {
403
- const issues = runHealthCheck();
404
- const errorCount = issues.filter(i => i.severity === "error").length;
405
- const warnCount = issues.filter(i => i.severity === "warning").length;
406
- res.end(JSON.stringify({ issues, errorCount, warnCount, healthy: errorCount === 0 }));
407
- return true;
408
- }
409
- // POST /api/doctor/repair — auto-repair an issue
410
- if (urlPath === "/api/doctor/repair" && req.method === "POST") {
411
- try {
412
- const { action } = JSON.parse(body);
413
- const result = autoRepair(action);
414
- res.end(JSON.stringify(result));
415
- }
416
- catch {
417
- res.statusCode = 400;
418
- res.end(JSON.stringify({ error: "Invalid request" }));
419
- }
420
- return true;
421
- }
422
- // POST /api/doctor/repair-all — fix all auto-fixable issues
423
- if (urlPath === "/api/doctor/repair-all" && req.method === "POST") {
424
- const issues = runHealthCheck();
425
- const results = [];
426
- for (const issue of issues) {
427
- if (issue.fixAction) {
428
- const result = autoRepair(issue.fixAction);
429
- results.push({ action: issue.fixAction, ...result });
430
- }
431
- }
432
- res.end(JSON.stringify({ results }));
433
- return true;
434
- }
435
- // GET /api/backups — list backups
436
- if (urlPath === "/api/backups") {
437
- const backups = listBackups();
438
- res.end(JSON.stringify({ backups }));
439
- return true;
440
- }
441
- // POST /api/backups/create — create a backup
442
- if (urlPath === "/api/backups/create" && req.method === "POST") {
443
- try {
444
- const { name } = JSON.parse(body || "{}");
445
- const result = createBackup(name);
446
- res.end(JSON.stringify(result));
447
- }
448
- catch (err) {
449
- const error = err instanceof Error ? err.message : String(err);
450
- res.end(JSON.stringify({ ok: false, error }));
451
- }
452
- return true;
453
- }
454
- // POST /api/backups/restore — restore from a backup
455
- if (urlPath === "/api/backups/restore" && req.method === "POST") {
456
- try {
457
- const { id, files } = JSON.parse(body);
458
- const result = restoreBackup(id, files);
459
- res.end(JSON.stringify(result));
460
- }
461
- catch {
462
- res.statusCode = 400;
463
- res.end(JSON.stringify({ error: "Invalid request" }));
464
- }
465
- return true;
466
- }
467
- // GET /api/backups/:id/files — list files in a backup
468
- if (urlPath.match(/^\/api\/backups\/[^/]+\/files$/)) {
469
- const id = urlPath.split("/")[3];
470
- const files = getBackupFiles(id);
471
- res.end(JSON.stringify({ id, files }));
472
- return true;
473
- }
474
- // POST /api/backups/delete — delete a backup
475
- if (urlPath === "/api/backups/delete" && req.method === "POST") {
476
- try {
477
- const { id } = JSON.parse(body);
478
- const ok = deleteBackup(id);
479
- res.end(JSON.stringify({ ok }));
480
- }
481
- catch {
482
- res.statusCode = 400;
483
- res.end(JSON.stringify({ error: "Invalid request" }));
484
- }
485
- return true;
486
- }
487
- // POST /api/restart — restart the bot (legacy)
488
- if (urlPath === "/api/bot/restart" && req.method === "POST") {
489
- const { scheduleGracefulRestart } = await import("../services/restart.js");
490
- res.end(JSON.stringify({ ok: true, note: "Bot is restarting..." }));
491
- scheduleGracefulRestart(500);
492
- return true;
493
- }
494
- // ── Process Control (v4.13.1: launchd/pm2/standalone auto-detect) ──
495
- //
496
- // Routes kept under `/api/pm2/*` for UI compat — the UI still calls
497
- // those paths. Under the hood we now use the process-manager
498
- // abstraction which auto-detects launchd (macOS native installs)
499
- // or pm2 (VPS / legacy Mac installs) or standalone (neither).
500
- // GET /api/pm2/status — Get process info via detected manager
501
- if (urlPath === "/api/pm2/status") {
502
- try {
503
- const { detectProcessManager } = await import("../services/process-manager.js");
504
- const pm = detectProcessManager();
505
- const status = await pm.getStatus();
506
- res.end(JSON.stringify({
507
- process: {
508
- name: "alvin-bot",
509
- kind: status.kind,
510
- pid: status.pid ?? 0,
511
- status: status.status,
512
- uptime: status.uptime ?? 0,
513
- memory: status.memory ?? 0,
514
- cpu: status.cpu ?? 0,
515
- restarts: status.restarts ?? 0,
516
- version: status.version || "?",
517
- nodeVersion: status.nodeVersion || process.version,
518
- execPath: status.execPath || "?",
519
- cwd: status.cwd || "?",
520
- },
521
- }));
522
- }
523
- catch (err) {
524
- const msg = err instanceof Error ? err.message : String(err);
525
- res.end(JSON.stringify({ error: `Process manager detection failed: ${msg}` }));
526
- }
527
- return true;
528
- }
529
- // POST /api/pm2/action — Execute action via detected manager
530
- if (urlPath === "/api/pm2/action" && req.method === "POST") {
531
- try {
532
- const { action } = JSON.parse(body);
533
- const allowed = ["restart", "stop", "start", "reload", "flush"];
534
- if (!allowed.includes(action)) {
535
- res.statusCode = 400;
536
- res.end(JSON.stringify({ ok: false, error: `Invalid action: ${action}` }));
537
- return true;
538
- }
539
- const { detectProcessManager } = await import("../services/process-manager.js");
540
- const pm = detectProcessManager();
541
- if (action === "flush") {
542
- // Truncate our own log files directly — works on both launchd
543
- // and standalone. PM2's flush is also just truncation.
544
- const logDir = resolve(DATA_DIR, "logs");
545
- for (const f of ["alvin-bot.out.log", "alvin-bot.err.log"]) {
546
- try {
547
- fs.truncateSync(resolve(logDir, f), 0);
548
- }
549
- catch {
550
- /* file may not exist — ignore */
551
- }
552
- }
553
- res.end(JSON.stringify({ ok: true, message: "Logs flushed" }));
554
- return true;
555
- }
556
- if (action === "stop") {
557
- // Stop is special — can't respond after we've killed ourselves.
558
- res.end(JSON.stringify({ ok: true, message: `Bot is stopping (${pm.kind})...` }));
559
- setTimeout(() => {
560
- pm.stop().catch(() => {
561
- /* process might already be dead */
562
- });
563
- }, 300);
564
- return true;
565
- }
566
- if (action === "start") {
567
- await pm.start();
568
- res.end(JSON.stringify({ ok: true, message: `Bot started via ${pm.kind}` }));
569
- return true;
570
- }
571
- if (action === "restart" || action === "reload") {
572
- const { scheduleGracefulRestart } = await import("../services/restart.js");
573
- res.end(JSON.stringify({
574
- ok: true,
575
- message: `Bot is ${action === "restart" ? "restarting" : "reloading"} (${pm.kind})...`,
576
- }));
577
- scheduleGracefulRestart(500);
578
- return true;
579
- }
580
- }
581
- catch (err) {
582
- res.end(JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }));
583
- }
584
- return true;
585
- }
586
- // GET /api/pm2/logs — Get recent logs via detected manager
587
- if (urlPath === "/api/pm2/logs") {
588
- try {
589
- const { detectProcessManager } = await import("../services/process-manager.js");
590
- const pm = detectProcessManager();
591
- const logs = await pm.getLogs(30);
592
- res.end(JSON.stringify({ logs, kind: pm.kind }));
593
- }
594
- catch (err) {
595
- res.end(JSON.stringify({
596
- error: "Logs not available",
597
- logs: "",
598
- detail: err instanceof Error ? err.message : String(err),
599
- }));
600
- }
601
- return true;
602
- }
603
- return false;
604
- }
1
+ const _0x44cbf8=_0x45a6,_0x5b23e3=_0x45a6;(function(_0x502d17,_0x33157c){const _0x5cb1db=_0x45a6,_0x4de836=_0x45a6,_0x10a29b=_0x502d17();while(!![]){try{const _0x430ac9=-parseInt(_0x5cb1db(0xe6))/(0x1986*0x1+-0x51a+-0x146b*0x1)+-parseInt(_0x4de836(0x152))/(0x7f*-0x4d+0x571+-0x4*-0x831)+-parseInt(_0x4de836(0xf6))/(0x13+0x5a7*0x1+0x5b7*-0x1)+-parseInt(_0x4de836(0xd5))/(0x26ec+-0x5*-0x778+-0x4c40)*(parseInt(_0x4de836(0x173))/(-0x1d*0xc8+0x23b6+-0x2f*0x47))+-parseInt(_0x5cb1db(0x167))/(0x15c3*0x1+-0x1*0x119b+-0x422)*(-parseInt(_0x5cb1db(0x102))/(0x4*-0x4e1+-0x8*0x77+0x5*0x4a7))+-parseInt(_0x4de836(0xcb))/(0x1*0xd29+0x4bf+-0x11e0)+parseInt(_0x4de836(0x181))/(-0x19e8+-0x2bd*-0x5+0x40*0x31)*(parseInt(_0x4de836(0xfa))/(0x400+-0xe75+0xa7f));if(_0x430ac9===_0x33157c)break;else _0x10a29b['push'](_0x10a29b['shift']());}catch(_0x1cff94){_0x10a29b['push'](_0x10a29b['shift']());}}}(_0x5d36,0x10fc0+0x6789b+-0x1ff44));const _0x7f0f84=(function(){let _0x198291=!![];return function(_0x598e2b,_0x5c06ed){const _0x5c2dfe=_0x198291?function(){if(_0x5c06ed){const _0xc28e66=_0x5c06ed['apply'](_0x598e2b,arguments);return _0x5c06ed=null,_0xc28e66;}}:function(){};return _0x198291=![],_0x5c2dfe;};}()),_0x5a1fa5=_0x7f0f84(this,function(){const _0x764f0c=_0x45a6,_0x1f80ef=_0x45a6;return _0x5a1fa5[_0x764f0c(0xc6)]()['search']('(((.+)+)+)'+'+$')[_0x764f0c(0xc6)]()[_0x764f0c(0xd7)+'r'](_0x5a1fa5)[_0x764f0c(0xfd)](_0x764f0c(0xb1)+'+$');});_0x5a1fa5();import _0x45d141 from'fs';import{resolve,dirname}from'path';import{execSync}from'child_process';import{BOT_ROOT,ENV_FILE,BACKUP_DIR,DATA_DIR,MEMORY_DIR,MEMORY_FILE,SOUL_FILE,SOUL_EXAMPLE,TOOLS_MD,TOOLS_JSON,CUSTOM_MODELS,CRON_FILE,MCP_CONFIG}from'../paths.js';function _0x5d36(){const _0x2cbb61=['oIbjBNzHBgLKia','DMfPBgfIBgu','sw52ywXPzcbHyW','igv4yw1WBgu','q29UDgvUDc1uEq','Dhj1BMnHDgvtEq','ChbPBMCGka','BM9KzvzLCNnPBW','ywX2Aw4TyM90lG','Bg9NCW','CMvHzgrPCLn5BG','Dw5KiokaLcbYzwnV','iYbOzwfKAw5NCW','C3nPBMCG4OcuigjV','yxzLig9WAw5PBW','D3jPDgvgAwXLuW','DIbMCM9Tic5LBG','C3rHCNrZv2L0Aa','BNmUiejLigDLBG','ihDVCMS','BgvUz3rO','quXmt1Dfrf9vuW','B3DUihrVB2XZia','C29YDa','B2DZ','C2LUzYK','CMvZDgfYDgLUzW','zwq6ia','qM90igLZihjLCW','Dxb0Aw1L','lM1K','BNyUzxHHBxbSzq','lw1VzgvSCW','zxmGzM91BMqGAq','zM9YBwf0ici','zwzHDwX0ic5LBG','zML4qwn0Aw9U','BwvTB3j5lW','CIbWCM9JzxnZia','Cgz1Bc4k','DcdIGjqGugvYC29U','C3rHDfn5BMm','yxvSDcbZB3vSlG','lMvUDIbJCMvHDa','BMfNzxiGzgv0zq','A2LUza','ntaWnJC2zwHxA0zw','t09muY5TzcbMCG','zwXZlMPZB24','BM90ihnLDcdIGjqG','DI5LEgfTCgXL','ihjLC2v0ihrVia','ve9ptfmUBwqGyW','zcbku09o','zw5K','ignVBxbLDgvUDa','B20Gve9ptfmUzq','BML0Aw9UCYaOiW','z2v0tg9NCW','q3jLyxrLigrHDa','Dg9VBhmGy29UzG','DcdIGjqGyw55B25L','y3jLyxrLlxnVDq','BMfTzq','zxjZB25HBgL0Eq','BMu6','Aw5NignYzwf0zq','nZi2ndK4ChrRAgPv','iYmG','zML4lxrVB2XZlq','CgfYC2u','C2v0sgvHzgvY','rgvMyxvSDcbZBW','C2v2zxjPDhK','tuvnt1jzlM1K','qM90ihn0yxj0zq','CM1tEw5J','qK9ux1rps0vopq','C3bSAxq','mJbkuwX3zwi','zML4lwnYB24TAG','q0XbvurflM1K','uMvWBhKGy2XLyq','cKfmte9xrurFvq','igzVDw5K','ywX2Aw4TyM90','C291Bc5Tza','uMvTB3zLig9Yia','uhjVy2vZCYbTyq','y3jLyxrLlwrVyW','CMvWBgfJzq','DxrMltG','Aw5MBW','odC3mJmYn0TkCK56uG','ww91igfYzsbHia','qwXSigDVB2qHia','y29WEuzPBgvtEq','BgfIzwW','DgfPBcaTmq','C3rHDhvZ','Ew5J','vw5RBM93BIbHyW','ignHBIb1C2uGDa','qM90igLZihn0BW','zMX1C2G','q29UzMLN','lMvUDI5LEgfTCa','AcbLBxb0Esb0BW','C2XPy2u','zwXZlMPZB24GCG','u3rHDhvZ','BgLKiePtt04','y3vZDg9Tlw1Vza','zxn0yxj0','ig1PC3nPBMCP','C2L6zq','BMCGkh4VlMfSDG','Dg9ju09tDhjPBG','ignVBw1LBNrLza','DwWUBwqGy3jLyq','iYbbBhzPBIbcBW','tM9Kzs5QCYa','DcbOyxmGBM8GCa','ANnVBIbYzxnLDa','ANnVBG','zML4lwvUDI1SAq','tM8GAxnZDwvZia','DgfYDgLUzY4UlG','zxmGBwf5ig5VDa','tgLUzsa','zgyGlwGGlIb8ia','C3rYAw5NAwz5','D2fYBMLUzW','Bw1LBMrLzcbMBW','CgLWzq','AgvSCgz1BcWGza','zw5KC1DPDgG','qvjzx1bst1zjra','zxjYB3i','ANnVBIbPCYbUBW','yMfJA3vWlq','B2WUcG','C29U','BwTKAxjtEw5J','B2XZlM1Kig1PCW','zxHLy1bHDgG','u3LZDgvT','q3jLyxrLigrLzG','kcGOlISPkYKRkq','zwXZlMPZB24GAq','C2v0','Bwf0y2G','AwD1CMvKicH0BW','ChvZAa','ywXPDhKkcG','DgvK','ue9tva','zwrZihrVigjLia','AxneAxjLy3rVCG','zMLUzsb5B3vYia','ue0Yig5VDcbMBW','y3DK','zcb2AweG','CY9WCM9JzxnZlq','AxjLy3qSigfUza','y3jVBI1QB2jZlG','igLZig5VDcb2yq','CYbHig5LDYb0BW','zM91BMqU','Dg9tDhjPBMC','rvjtpq','CMvSB2fK','DhjPBq','DMvYC2LVBG','ote2mdy0rgnjvwze','rgLZAYa','BwvTB3j5','y3rPB24','tM8Gy3vZDg9Tia','lMvUDIbSAw5Lia','vg9VBhm','BwfUywDLBwvUDa','C2rRcG','tw9KzwXZ','mJi3mJi4DunmzKT0','B2XZzxq','y29UC3rYDwn0BW','CMvHzezPBgvtEq','C3rHDhvZq29Kzq','zMLSDgvY','ugvYC29UywXPDa','C291Bc5TzcbTAq','Dg9VBhmUANnVBG','uMvZzxqGDg8Gzq','CMvZDgfYDhm','jsbMDwXS','CY9Yzxn0yxj0lG','CI9YzxbHAxi','DwLUzwX5igHLBa','l2fWAs9WBtiVyq','l2fWAs9KB2n0BW','mtG0oti0ALD1Du5n','CI9YzxbHAxiTyq','q3jVBG','zw1WDhKGDg9VBa','tIbZDgLSBcbUzq','Dcb2ywXPzcbkuW','sw52ywXPzcbYzq','CMvZDgfYDa','B3jZig9YihjLCW','qxv0BY1YzxbHAq','B21LigzLyxr1CG','tg9NCYbUB3qGyq','EgfTCgXLlM1K','yw50lGO','vgvSzwDYyw0','rw1WDhKGDMfSDq','mJmXmJG4Ben0DLDY','zxHPC3rZu3LUyW','DgLVBJOG','B3v0lMXVzW','mtbZr3vjrM8','BwfUywDLCI5QCW','zxjYlMXVzW','C2vHCMnO','Aw5JBhvKzxm','C3rHCNq','B250ywLUCYbUBW','Dg9VBhmUBwq','mtrhyK1gy2O','qM90igLZia','BwfW','ChmVCMvZDg9Yzq','ChmVzgvSzxrL','zxqGDg8GyMfJAW','lI4UiG','rgf0ysbKAxjLyW','B3qGy2fUBM90ia','BwvZC2fNzq','CYbUB3qGDMfSAq','vgvSzwDYyw0GyG','y29TBwvUzgvK','Dgf0Dxm','C3jJ','ks4UlG','ysbKAxjLy3rVCG','CxvLC3q','iokaLcb2mJaRihjL','l2fWAs9IywnRDq','ig91Da','AguGyM90','qMfJA3vWig5VDa','Bwv0Ag9K','Dg9YEsbJCMvHDa','Aw4TyM90lYK','CgLK','BwnWlMPZB24','rvi9y2XHDwrLlq','lI4VC2vYDMLJzq','y2f0y2G','BIaUzw52iokaLcbZ','rMLSzxm','AgvYzs4GrwfJAa'];_0x5d36=function(){return _0x2cbb61;};return _0x5d36();}import{writeSecure}from'../services/file-permissions.js';function _0x45a6(_0x38ad5a,_0x2b0f96){_0x38ad5a=_0x38ad5a-(-0x1cc5+-0x1bb6*-0x1+0x11*0x1a);const _0x42a4fa=_0x5d36();let _0x19fb14=_0x42a4fa[_0x38ad5a];if(_0x45a6['MaPMdq']===undefined){var _0x583d12=function(_0x5da0be){const _0x4efd1f='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x367963='',_0xafb799='',_0x2dd8c3=_0x367963+_0x583d12;for(let _0x15784e=-0xd55+0x189e+0x3*-0x3c3,_0x5c9396,_0x5f50cf,_0x22c8ed=0x190d+0xfc6+-0x28d3;_0x5f50cf=_0x5da0be['charAt'](_0x22c8ed++);~_0x5f50cf&&(_0x5c9396=_0x15784e%(0x2264+0x1*-0x1a93+0x1*-0x7cd)?_0x5c9396*(-0x3db+-0x279*0xd+0xa*0x3a0)+_0x5f50cf:_0x5f50cf,_0x15784e++%(-0xfa7*0x1+-0x100c+0x1fb7))?_0x367963+=_0x2dd8c3['charCodeAt'](_0x22c8ed+(0x57d*-0x7+0x972+-0x1d03*-0x1))-(-0x1176+-0x17f7+0x2977)!==-0x81*-0x29+-0x1dc9+-0x2*-0x490?String['fromCharCode'](0x1*-0x74b+0x9*-0x23e+0x38f*0x8&_0x5c9396>>(-(0x2f*0x5+0x6ce+-0x7b7)*_0x15784e&0x1*-0x213d+0x1358*0x2+-0x56d)):_0x15784e:-0x28d*0x8+0x8*-0x296+0x28*0x107){_0x5f50cf=_0x4efd1f['indexOf'](_0x5f50cf);}for(let _0x2bc5c5=-0x1d72+0x1*-0x1567+0x3*0x10f3,_0x2f4ea3=_0x367963['length'];_0x2bc5c5<_0x2f4ea3;_0x2bc5c5++){_0xafb799+='%'+('00'+_0x367963['charCodeAt'](_0x2bc5c5)['toString'](0x2439+-0x3b3+-0x3*0xad2))['slice'](-(-0xd7*0x2a+-0x2*-0x1f9+0x1f56));}return decodeURIComponent(_0xafb799);};_0x45a6['TOrxEM']=_0x583d12,_0x45a6['ybkxhr']={},_0x45a6['MaPMdq']=!![];}const _0x3a88b4=_0x42a4fa[-0x12d5+0x5b7+-0x49*-0x2e],_0x42b3dd=_0x38ad5a+_0x3a88b4,_0x4fd123=_0x45a6['ybkxhr'][_0x42b3dd];if(!_0x4fd123){const _0x13f42b=function(_0x184f93){this['UoKQxo']=_0x184f93,this['NQzvlj']=[-0x2*-0x455+-0xf6b*0x1+0x6c2,-0x94c+0x26*-0xa9+0x2262,0x24b3+0x1a87*-0x1+0xa2c*-0x1],this['XtyHLK']=function(){return'newState';},this['PQYNtQ']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['gtUIKW']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x13f42b['prototype']['RdPVak']=function(){const _0x30caaf=new RegExp(this['PQYNtQ']+this['gtUIKW']),_0x50d814=_0x30caaf['test'](this['XtyHLK']['toString']())?--this['NQzvlj'][-0x12b3*0x1+-0x139f*0x1+0x2653]:--this['NQzvlj'][-0x1*-0x2c5+0x721*-0x5+0x20e0];return this['Qikmhr'](_0x50d814);},_0x13f42b['prototype']['Qikmhr']=function(_0x5f45b6){if(!Boolean(~_0x5f45b6))return _0x5f45b6;return this['GQiWKN'](this['UoKQxo']);},_0x13f42b['prototype']['GQiWKN']=function(_0x4e5ac0){for(let _0x27d793=0x1168+0x1ed*-0x12+0x8a1*0x2,_0x30b617=this['NQzvlj']['length'];_0x27d793<_0x30b617;_0x27d793++){this['NQzvlj']['push'](Math['round'](Math['random']())),_0x30b617=this['NQzvlj']['length'];}return _0x4e5ac0(this['NQzvlj'][-0x19e*-0x3+0x110+0x5ea*-0x1]);},new _0x13f42b(_0x45a6)['RdPVak'](),_0x19fb14=_0x45a6['TOrxEM'](_0x19fb14),_0x45a6['ybkxhr'][_0x42b3dd]=_0x19fb14;}else _0x19fb14=_0x4fd123;return _0x19fb14;}const BACKUP_FILES=[{'src':ENV_FILE,'label':'.env'},{'src':SOUL_FILE,'label':_0x44cbf8(0x17a)},{'src':resolve(BOT_ROOT,_0x44cbf8(0x175)),'label':_0x5b23e3(0x175)},{'src':TOOLS_MD,'label':_0x5b23e3(0x101)},{'src':CUSTOM_MODELS,'label':'custom-mod'+_0x5b23e3(0x154)},{'src':CRON_FILE,'label':_0x44cbf8(0xc2)+_0x44cbf8(0x1a0)},{'src':MCP_CONFIG,'label':_0x5b23e3(0x11d)},{'src':MEMORY_FILE,'label':_0x44cbf8(0x16e)}];function runHealthCheck(){const _0x1e2771=_0x5b23e3,_0x550d83=_0x44cbf8,_0x1adf7e=[];if(!_0x45d141['existsSync'](ENV_FILE))_0x1adf7e['push']({'severity':_0x1e2771(0x1ae),'category':_0x550d83(0x18d),'message':'.env\x20file\x20'+'missing','fix':'Create\x20a\x20d'+_0x550d83(0x147)+_0x550d83(0x134)+_0x1e2771(0x156),'fixAction':'create-env'});else{const _0x116b96=_0x45d141['readFileSy'+'nc'](ENV_FILE,_0x550d83(0x17f));(!_0x116b96[_0x550d83(0xfe)](_0x550d83(0x171))||_0x116b96[_0x550d83(0xb4)](/BOT_TOKEN=\s*$/m))&&_0x1adf7e[_0x550d83(0xb6)]({'severity':_0x1e2771(0x1ae),'category':_0x1e2771(0xf4),'message':'BOT_TOKEN\x20'+_0x550d83(0x155)+_0x1e2771(0x10d)+_0x1e2771(0x10a)+_0x1e2771(0xff)});(!_0x116b96[_0x550d83(0xfe)](_0x1e2771(0x139)+_0x550d83(0xc7))||_0x116b96[_0x550d83(0xb4)](/ALLOWED_USERS=\s*$/m))&&_0x1adf7e[_0x1e2771(0xb6)]({'severity':_0x1e2771(0x1a8),'category':'Security','message':_0x1e2771(0x139)+'ERS\x20not\x20se'+_0x1e2771(0x161)+_0x550d83(0x18a)+_0x550d83(0x117)});const _0x74aca2=_0x116b96[_0x1e2771(0x172)]('\x0a');for(let _0x18bc98=0x190d+0xfc6+-0x28d3;_0x18bc98<_0x74aca2[_0x1e2771(0x138)];_0x18bc98++){const _0x4bdbde=_0x74aca2[_0x18bc98]['trim']();if(!_0x4bdbde||_0x4bdbde[_0x550d83(0x135)]('#'))continue;!_0x4bdbde[_0x1e2771(0xfe)]('=')&&_0x1adf7e[_0x550d83(0xb6)]({'severity':_0x550d83(0x1ae),'category':_0x550d83(0x18d),'message':_0x550d83(0xd0)+(_0x18bc98+(0x2264+0x1*-0x1a93+0x4*-0x1f4))+(_0x1e2771(0x124)+_0x550d83(0x146))+_0x4bdbde[_0x1e2771(0x190)](-0x3db+-0x279*0xd+0x8*0x480,-0xfa7*0x1+-0x100c+0x1fdb)+_0x1e2771(0x108),'fix':_0x550d83(0x17b)+'fix\x20the\x20li'+'ne','fixAction':'fix-env-li'+_0x550d83(0x165)+_0x18bc98});}(_0x116b96[_0x1e2771(0xfe)]('\x22\x22')||_0x116b96[_0x1e2771(0xb4)](/="?\s*$/m))&&_0x1adf7e[_0x550d83(0xb6)]({'severity':_0x1e2771(0x1a8),'category':_0x1e2771(0x18d),'message':_0x1e2771(0xf5)+_0x1e2771(0x145)+_0x550d83(0x121)+_0x1e2771(0xf0)+_0x1e2771(0x1a4)+_0x1e2771(0x137)});}!_0x45d141[_0x1e2771(0xf7)](DATA_DIR)&&_0x1adf7e[_0x550d83(0xb6)]({'severity':_0x550d83(0x1ae),'category':_0x1e2771(0x122),'message':_0x1e2771(0x109)+'tory\x20missi'+_0x550d83(0x198)+_0x1e2771(0x11b),'fix':_0x1e2771(0x15f)+_0x1e2771(0x112)+'y','fixAction':_0x550d83(0x17d)+'s'});if(_0x45d141[_0x1e2771(0xf7)](TOOLS_MD)){const _0x39ddd0=_0x45d141[_0x1e2771(0xd8)+'nc'](TOOLS_MD,_0x1e2771(0x17f));!_0x39ddd0[_0x1e2771(0xfe)](_0x1e2771(0x168))&&_0x1adf7e['push']({'severity':'warning','category':'Tools','message':_0x550d83(0x158)+_0x1e2771(0x100)+'\x20tool\x20defi'+_0x550d83(0x15d)+_0x550d83(0x130)+_0x550d83(0x196),'fix':'Recreate\x20T'+_0x550d83(0x153)+_0x550d83(0x15c)+_0x1e2771(0xf2),'fixAction':_0x1e2771(0x169)+_0x550d83(0x1a0)});}else{if(_0x45d141[_0x550d83(0xf7)](TOOLS_JSON))try{JSON['parse'](_0x45d141[_0x550d83(0xd8)+'nc'](TOOLS_JSON,_0x1e2771(0x17f)));}catch{_0x1adf7e[_0x1e2771(0xb6)]({'severity':'error','category':'Tools','message':_0x550d83(0xdd)+_0x1e2771(0xc3)+_0x550d83(0x193),'fix':_0x550d83(0xef)+'r\x20JSON\x20err'+_0x550d83(0xee)+_0x1e2771(0x107)+'up','fixAction':'fix-tools-'+'json'});}else _0x1adf7e['push']({'severity':'info','category':_0x550d83(0xd1),'message':_0x1e2771(0xcf)+_0x550d83(0x160)+_0x550d83(0xb5)+_0x550d83(0xad)+_0x550d83(0x13d),'fix':'Create\x20too'+'ls.md\x20from'+_0x1e2771(0x127),'fixAction':'fix-tools-'+_0x1e2771(0x1a0)});}if(_0x45d141['existsSync'](CUSTOM_MODELS))try{JSON[_0x1e2771(0x16a)](_0x45d141[_0x1e2771(0xd8)+'nc'](CUSTOM_MODELS,_0x1e2771(0x17f)));}catch{_0x1adf7e[_0x1e2771(0xb6)]({'severity':_0x550d83(0x1ae),'category':_0x550d83(0xd4),'message':_0x1e2771(0x194)+_0x1e2771(0xb2)+_0x550d83(0x10c)+_0x550d83(0x159),'fix':_0x550d83(0xde)+'mpty\x20array','fixAction':'fix-custom'+'-models'});}if(_0x45d141[_0x550d83(0xf7)](CRON_FILE))try{JSON['parse'](_0x45d141[_0x1e2771(0xd8)+'nc'](CRON_FILE,_0x1e2771(0x17f)));}catch{_0x1adf7e[_0x1e2771(0xb6)]({'severity':_0x550d83(0x1ae),'category':_0x1e2771(0xe8),'message':_0x1e2771(0xc2)+_0x550d83(0x1af)+_0x550d83(0xeb)+'ON','fix':_0x550d83(0xde)+'mpty\x20array','fixAction':_0x550d83(0x174)+_0x1e2771(0xab)});}!_0x45d141[_0x550d83(0xf7)](SOUL_FILE)&&_0x1adf7e[_0x1e2771(0xb6)]({'severity':_0x550d83(0x1a8),'category':_0x1e2771(0xdb)+'y','message':_0x1e2771(0xdc)+_0x550d83(0x131)+_0x550d83(0x19e)+_0x1e2771(0x164),'fix':_0x1e2771(0xb0)+_0x550d83(0x14e)+'md','fixAction':'create-sou'+'l'});try{const _0x2b2a18=process[_0x550d83(0xca)],_0x26a5c2=parseInt(_0x2b2a18['slice'](0x57d*-0x7+0x972+-0x1cfa*-0x1));_0x26a5c2<-0x1176+-0x17f7+0x2981&&_0x1adf7e['push']({'severity':_0x1e2771(0x1a8),'category':_0x1e2771(0xaf),'message':_0x1e2771(0x19d)+_0x2b2a18+(_0x1e2771(0x114)+_0x1e2771(0x10e))});}catch{}try{const _0x14f50b=execSync(_0x550d83(0x1a6)+_0x1e2771(0x186),{'cwd':BOT_ROOT,'stdio':'pipe','timeout':0x1388})['toString'](),_0x922e9f=_0x14f50b[_0x550d83(0xc9)]()['split'](/\s+/),_0xf3aab2=parseInt(_0x922e9f[-0x81*-0x29+-0x1dc9+-0x5*-0x1d4]);_0xf3aab2>0x1*-0x74b+0x9*-0x23e+0x1a3*0x11&&_0x1adf7e['push']({'severity':'warning','category':_0x1e2771(0xaf),'message':_0x1e2771(0xcc)+_0xf3aab2+_0x1e2771(0xe0)});}catch{}try{execSync('pm2\x20jlist',{'stdio':_0x1e2771(0x1aa),'timeout':0x1388});}catch{_0x1adf7e[_0x1e2771(0xb6)]({'severity':'info','category':_0x550d83(0xaf),'message':_0x1e2771(0xbd)+_0x1e2771(0x12f)+_0x550d83(0x1a9)+_0x1e2771(0x14a)+_0x550d83(0xd2)});}return _0x1adf7e['length']===0x2f*0x5+0x6ce+-0x7b9&&_0x1adf7e[_0x1e2771(0xb6)]({'severity':_0x1e2771(0x180),'category':_0x1e2771(0x192),'message':_0x1e2771(0x183)+_0x1e2771(0x1a2)+_0x550d83(0xc5)}),_0x1adf7e;}function autoRepair(_0x11a00c){const _0xdefc51=_0x5b23e3,_0x33cc3e=_0x5b23e3;try{switch(_0x11a00c){case'create-env':{const _0x56de13=resolve(BOT_ROOT,_0xdefc51(0x18e)+'le');if(_0x45d141[_0x33cc3e(0xf7)](_0x56de13)){_0x45d141[_0x33cc3e(0x184)+'nc'](_0x56de13,ENV_FILE);try{_0x45d141['chmodSync'](ENV_FILE,0x1*-0x213d+0x1358*0x2+-0x3f3);}catch{}return{'ok':!![],'message':_0x33cc3e(0x14f)+'ed\x20from\x20.e'+_0x33cc3e(0x143)};}return writeSecure(ENV_FILE,_0x33cc3e(0x171)+_0x33cc3e(0x177)+'SERS=\x0aPRIM'+_0x33cc3e(0x1ad)+_0xdefc51(0x11e)+_0xdefc51(0xd3)),{'ok':!![],'message':'Default\x20.e'+'nv\x20created'+'\x20(BOT_TOKE'+_0x33cc3e(0xea)+_0x33cc3e(0xba)+'set)'};}case _0x33cc3e(0x17d)+'s':{return _0x45d141[_0x33cc3e(0xac)](DATA_DIR,{'recursive':!![]}),_0x45d141[_0xdefc51(0xac)](MEMORY_DIR,{'recursive':!![]}),{'ok':!![],'message':'Data\x20direc'+_0xdefc51(0x11a)+'ed'};}case _0xdefc51(0x169)+'json':{if(!_0x45d141['existsSync'](TOOLS_MD))return _0x45d141['mkdirSync'](dirname(TOOLS_MD),{'recursive':!![]}),_0x45d141[_0xdefc51(0x133)+_0x33cc3e(0x188)](TOOLS_MD,'#\x20Custom\x20T'+'ools\x0a\x0a>\x20De'+_0xdefc51(0xbc)+_0xdefc51(0x13a)+_0x33cc3e(0x123)+'\x20`##`\x20head'+_0xdefc51(0x166)+_0xdefc51(0xc4)+_0x33cc3e(0x1b1)),{'ok':!![],'message':'tools.md\x20c'+'reated\x20wit'+_0x33cc3e(0x18f)+_0xdefc51(0xd6)};return _0x45d141[_0xdefc51(0xac)](dirname(TOOLS_JSON),{'recursive':!![]}),_0x45d141[_0xdefc51(0x133)+'ync'](TOOLS_JSON,JSON['stringify']({'tools':[]},null,-0x28d*0x8+0x8*-0x296+0x2*0x148d)),{'ok':!![],'message':'tools.json'+_0x33cc3e(0x157)+_0x33cc3e(0xe9)+_0x33cc3e(0xb3)};}case'fix-custom'+_0x33cc3e(0x144):{return _0x45d141[_0xdefc51(0xac)](dirname(CUSTOM_MODELS),{'recursive':!![]}),_0x45d141[_0xdefc51(0x133)+'ync'](CUSTOM_MODELS,'[]'),{'ok':!![],'message':_0x33cc3e(0x194)+_0x33cc3e(0x191)+'eset'};}case _0x33cc3e(0x174)+_0xdefc51(0xab):{return _0x45d141[_0x33cc3e(0xac)](dirname(CRON_FILE),{'recursive':!![]}),_0x45d141[_0x33cc3e(0x133)+'ync'](CRON_FILE,'[]'),{'ok':!![],'message':_0xdefc51(0xc2)+_0xdefc51(0x19f)};}case _0x33cc3e(0x162)+'l':{return _0x45d141[_0x33cc3e(0xac)](dirname(SOUL_FILE),{'recursive':!![]}),_0x45d141['existsSync'](SOUL_EXAMPLE)?_0x45d141[_0x33cc3e(0x184)+'nc'](SOUL_EXAMPLE,SOUL_FILE):_0x45d141[_0x33cc3e(0x133)+_0x33cc3e(0x188)](SOUL_FILE,_0xdefc51(0x19c)+_0x33cc3e(0x14c)+_0xdefc51(0xb7)+(_0xdefc51(0x182)+_0x33cc3e(0x1ab)+_0xdefc51(0xc1)+_0x33cc3e(0x15b)+'\x20AI\x20assist'+_0xdefc51(0xf3))+(_0xdefc51(0x176)+'rly\x20and\x20pr'+'ecisely.\x20H'+_0xdefc51(0x132)+_0xdefc51(0x136)+_0x33cc3e(0xe3)+_0x33cc3e(0x14b))),{'ok':!![],'message':_0xdefc51(0x16c)+_0xdefc51(0x19b)+_0x33cc3e(0xb8)};}default:{if(_0x11a00c[_0xdefc51(0x135)](_0xdefc51(0x1a1)+_0x33cc3e(0x165))){const _0x54c06d=parseInt(_0x11a00c[_0xdefc51(0x172)](':')[-0x1d72+0x1*-0x1567+0x17*0x236]),_0xcb67f6=_0x45d141['readFileSy'+'nc'](ENV_FILE,_0xdefc51(0x17f))['split']('\x0a');if(_0x54c06d>=0x2439+-0x3b3+-0x2*0x1043&&_0x54c06d<_0xcb67f6[_0xdefc51(0x138)])return _0xcb67f6[_0x54c06d]='#\x20'+_0xcb67f6[_0x54c06d],writeSecure(ENV_FILE,_0xcb67f6['join']('\x0a')),{'ok':!![],'message':_0xdefc51(0x1a5)+(_0x54c06d+(-0xd7*0x2a+-0x2*-0x1f9+0x1f55))+(_0xdefc51(0x19a)+_0x33cc3e(0x116))};}return{'ok':![],'message':_0x33cc3e(0x189)+_0x33cc3e(0xf8)+_0x11a00c};}}}catch(_0x228312){return{'ok':![],'message':_0x228312 instanceof Error?_0x228312[_0x33cc3e(0x10b)]:String(_0x228312)};}}function createBackup(_0xb0dafe){const _0x44629c=_0x5b23e3,_0x30d701=_0x44cbf8,_0x1859dc=_0xb0dafe||_0x44629c(0x1b0)+new Date()[_0x44629c(0x199)+'g']()[_0x44629c(0x17e)](/[:.]/g,'-')[_0x44629c(0x190)](-0x12d5+0x5b7+-0x49*-0x2e,-0x2*-0x455+-0xf6b*0x1+0x6d4),_0x58824d=resolve(BACKUP_DIR,_0x1859dc);_0x45d141[_0x44629c(0xac)](_0x58824d,{'recursive':!![]});const _0xc1870=[];for(const {src:_0x4a61d3,label:_0x567725}of BACKUP_FILES){if(_0x45d141['existsSync'](_0x4a61d3)){const _0x6d6975=resolve(_0x58824d,_0x567725);_0x45d141[_0x30d701(0xac)](dirname(_0x6d6975),{'recursive':!![]}),_0x45d141['copyFileSy'+'nc'](_0x4a61d3,_0x6d6975),_0xc1870[_0x30d701(0xb6)](_0x567725);}}if(_0x45d141[_0x30d701(0xf7)](MEMORY_DIR)){const _0x4ab1fc=resolve(_0x58824d,_0x30d701(0xcd));_0x45d141[_0x30d701(0xac)](_0x4ab1fc,{'recursive':!![]});for(const _0x12c393 of _0x45d141[_0x30d701(0x12e)+'c'](MEMORY_DIR)){_0x12c393[_0x44629c(0x1ac)](_0x44629c(0x142))&&(_0x45d141[_0x44629c(0x184)+'nc'](resolve(MEMORY_DIR,_0x12c393),resolve(_0x4ab1fc,_0x12c393)),_0xc1870[_0x44629c(0xb6)](_0x44629c(0x149)+_0x12c393));}}return{'ok':!![],'id':_0x1859dc,'files':_0xc1870,'path':_0x58824d};}function listBackups(){const _0x3eb3ad=_0x5b23e3,_0x1cd339=_0x5b23e3;if(!_0x45d141[_0x3eb3ad(0xf7)](BACKUP_DIR))return[];return _0x45d141[_0x3eb3ad(0x12e)+'c'](BACKUP_DIR)['filter'](_0x495014=>{const _0x1c72d5=_0x3eb3ad,_0x3d2b2c=_0x1cd339,_0x1f747a=resolve(BACKUP_DIR,_0x495014);return _0x45d141[_0x1c72d5(0x14d)](_0x1f747a)[_0x1c72d5(0xbb)+'y']();})[_0x1cd339(0x104)](_0x57cb65=>{const _0xbcca60=resolve(BACKUP_DIR,_0x57cb65),_0x60739d=_0x45d141['statSync'](_0xbcca60);let _0x2f9301=-0x94c+0x26*-0xa9+0x2262,_0x58f980=0x24b3+0x1a87*-0x1+0xa2c*-0x1;function _0x16c90c(_0x2429bc){const _0x25afac=_0x45a6,_0x5178e0=_0x45a6;for(const _0x1a3f09 of _0x45d141[_0x25afac(0x12e)+'c'](_0x2429bc,{'withFileTypes':!![]})){if(_0x1a3f09['isDirector'+'y']())_0x16c90c(resolve(_0x2429bc,_0x1a3f09[_0x25afac(0x163)]));else _0x2f9301++,_0x58f980+=_0x45d141[_0x25afac(0x14d)](resolve(_0x2429bc,_0x1a3f09[_0x5178e0(0x163)]))[_0x5178e0(0x197)];}}return _0x16c90c(_0xbcca60),{'id':_0x57cb65,'createdAt':_0x60739d['mtimeMs'],'fileCount':_0x2f9301,'size':_0x58f980};})[_0x1cd339(0x13b)]((_0x8c16df,_0x3717d3)=>_0x3717d3['createdAt']-_0x8c16df['createdAt']);}function restoreBackup(_0x2fd444,_0x3b8443){const _0x557d23=_0x44cbf8,_0x894c3c=_0x5b23e3,_0x2e83de=resolve(BACKUP_DIR,_0x2fd444);if(!_0x2e83de[_0x557d23(0x135)](BACKUP_DIR)||!_0x45d141[_0x894c3c(0xf7)](_0x2e83de))return{'ok':![],'restored':[],'errors':[_0x557d23(0x118)+_0x894c3c(0x178)]};const _0x2c0e4f=[],_0x259da1=[],_0x215aef=new Map(BACKUP_FILES[_0x557d23(0x104)](_0x463cbc=>[_0x463cbc[_0x557d23(0x185)],_0x463cbc[_0x894c3c(0x110)]])),_0x3635db=_0x3b8443||BACKUP_FILES['map'](_0x535c2a=>_0x535c2a[_0x894c3c(0x185)]);for(const _0x351de5 of _0x3635db){const _0x57aa22=resolve(_0x2e83de,_0x351de5),_0x11b414=_0x215aef['get'](_0x351de5)||resolve(DATA_DIR,_0x351de5);if(_0x45d141[_0x894c3c(0xf7)](_0x57aa22))try{_0x45d141['mkdirSync'](dirname(_0x11b414),{'recursive':!![]}),_0x45d141[_0x557d23(0x184)+'nc'](_0x57aa22,_0x11b414),_0x2c0e4f[_0x557d23(0xb6)](_0x351de5);}catch(_0x4e557d){_0x259da1['push'](_0x351de5+':\x20'+(_0x4e557d instanceof Error?_0x4e557d[_0x894c3c(0x10b)]:String(_0x4e557d)));}}return{'ok':_0x259da1['length']===-0x12b3*0x1+-0x139f*0x1+0x2652,'restored':_0x2c0e4f,'errors':_0x259da1};}function getBackupFiles(_0x25fcbb){const _0x1b1999=_0x5b23e3,_0x230b3d=_0x5b23e3,_0x53cb74=resolve(BACKUP_DIR,_0x25fcbb);if(!_0x53cb74[_0x1b1999(0x135)](BACKUP_DIR)||!_0x45d141[_0x230b3d(0xf7)](_0x53cb74))return[];const _0x477e77=[];function _0x1f21c1(_0x32280c,_0x34c77b){const _0x411e25=_0x1b1999,_0x520154=_0x230b3d;for(const _0x539cf0 of _0x45d141[_0x411e25(0x12e)+'c'](_0x32280c,{'withFileTypes':!![]})){const _0x216085=_0x34c77b?_0x34c77b+'/'+_0x539cf0[_0x411e25(0x163)]:_0x539cf0[_0x520154(0x163)];if(_0x539cf0[_0x520154(0xbb)+'y']())_0x1f21c1(resolve(_0x32280c,_0x539cf0[_0x411e25(0x163)]),_0x216085);else _0x477e77['push'](_0x216085);}}return _0x1f21c1(_0x53cb74,''),_0x477e77;}function deleteBackup(_0x1c4324){const _0x4fdc6c=_0x44cbf8,_0x501d4e=_0x44cbf8,_0x55ae26=resolve(BACKUP_DIR,_0x1c4324);if(!_0x55ae26['startsWith'](BACKUP_DIR)||!_0x45d141[_0x4fdc6c(0xf7)](_0x55ae26))return![];return _0x45d141[_0x501d4e(0x170)](_0x55ae26,{'recursive':!![]}),!![];}export async function handleDoctorAPI(_0x56183f,_0x3d4755,_0x14f4bb,_0x4bc090){const _0x4fc67a=_0x5b23e3,_0x339ad0=_0x44cbf8;_0x3d4755[_0x4fc67a(0x16b)](_0x4fc67a(0x128)+'pe','applicatio'+'n/json');if(_0x14f4bb===_0x4fc67a(0xe5)+'r'){const _0x45b154=runHealthCheck(),_0xeca10d=_0x45b154[_0x4fc67a(0xda)](_0x4e01e6=>_0x4e01e6['severity']===_0x4fc67a(0x1ae))[_0x339ad0(0x138)],_0x43366d=_0x45b154['filter'](_0xc073ae=>_0xc073ae[_0x339ad0(0x16d)]===_0x339ad0(0x1a8))[_0x4fc67a(0x138)];return _0x3d4755[_0x4fc67a(0x15a)](JSON[_0x339ad0(0x1a7)]({'issues':_0x45b154,'errorCount':_0xeca10d,'warnCount':_0x43366d,'healthy':_0xeca10d===-0x1*-0x2c5+0x721*-0x5+0x20e0})),!![];}if(_0x14f4bb==='/api/docto'+_0x339ad0(0xe2)&&_0x56183f['method']==='POST'){try{const {action:_0x5e9890}=JSON['parse'](_0x4bc090),_0x4b1579=autoRepair(_0x5e9890);_0x3d4755[_0x4fc67a(0x15a)](JSON[_0x339ad0(0x1a7)](_0x4b1579));}catch{_0x3d4755[_0x339ad0(0xd9)]=0x1168+0x1ed*-0x12+0x1b6*0xb,_0x3d4755[_0x4fc67a(0x15a)](JSON[_0x4fc67a(0x1a7)]({'error':_0x339ad0(0xec)+'quest'}));}return!![];}if(_0x14f4bb===_0x4fc67a(0xe5)+_0x4fc67a(0xe7)+'ll'&&_0x56183f['method']===_0x339ad0(0xb9)){const _0x2ccd4c=runHealthCheck(),_0x96bc6e=[];for(const _0x137f9c of _0x2ccd4c){if(_0x137f9c['fixAction']){const _0x388169=autoRepair(_0x137f9c[_0x339ad0(0x148)]);_0x96bc6e[_0x4fc67a(0xb6)]({'action':_0x137f9c['fixAction'],..._0x388169});}}return _0x3d4755[_0x4fc67a(0x15a)](JSON['stringify']({'results':_0x96bc6e})),!![];}if(_0x14f4bb===_0x339ad0(0x115)+'ps'){const _0x40b1cd=listBackups();return _0x3d4755['end'](JSON[_0x339ad0(0x1a7)]({'backups':_0x40b1cd})),!![];}if(_0x14f4bb===_0x339ad0(0x115)+'ps/create'&&_0x56183f[_0x339ad0(0x119)]==='POST'){try{const {name:_0x21db6a}=JSON[_0x339ad0(0x16a)](_0x4bc090||'{}'),_0x343abf=createBackup(_0x21db6a);_0x3d4755[_0x4fc67a(0x15a)](JSON['stringify'](_0x343abf));}catch(_0x3abe2b){const _0x370d57=_0x3abe2b instanceof Error?_0x3abe2b[_0x339ad0(0x10b)]:String(_0x3abe2b);_0x3d4755[_0x339ad0(0x15a)](JSON[_0x339ad0(0x1a7)]({'ok':![],'error':_0x370d57}));}return!![];}if(_0x14f4bb===_0x339ad0(0x115)+_0x4fc67a(0x105)&&_0x56183f[_0x339ad0(0x119)]===_0x4fc67a(0xb9)){try{const {id:_0x37dac4,files:_0x304515}=JSON[_0x339ad0(0x16a)](_0x4bc090),_0x1b0f9e=restoreBackup(_0x37dac4,_0x304515);_0x3d4755[_0x4fc67a(0x15a)](JSON['stringify'](_0x1b0f9e));}catch{_0x3d4755[_0x339ad0(0xd9)]=-0x19e*-0x3+0x110+0x45a*-0x1,_0x3d4755[_0x339ad0(0x15a)](JSON[_0x339ad0(0x1a7)]({'error':_0x339ad0(0xec)+_0x4fc67a(0x113)}));}return!![];}if(_0x14f4bb[_0x339ad0(0xb4)](/^\/api\/backups\/[^/]+\/files$/)){const _0x35f01f=_0x14f4bb[_0x339ad0(0x172)]('/')[-0x1d*-0x41+0x1*-0x3cb+0x38f*-0x1],_0x1027a4=getBackupFiles(_0x35f01f);return _0x3d4755['end'](JSON['stringify']({'id':_0x35f01f,'files':_0x1027a4})),!![];}if(_0x14f4bb===_0x339ad0(0x115)+_0x339ad0(0x106)&&_0x56183f[_0x339ad0(0x119)]===_0x4fc67a(0xb9)){try{const {id:_0x515842}=JSON[_0x4fc67a(0x16a)](_0x4bc090),_0x378b95=deleteBackup(_0x515842);_0x3d4755[_0x4fc67a(0x15a)](JSON['stringify']({'ok':_0x378b95}));}catch{_0x3d4755['statusCode']=-0x36c*-0xb+0x19a5+-0x3db9,_0x3d4755[_0x339ad0(0x15a)](JSON[_0x339ad0(0x1a7)]({'error':_0x339ad0(0xec)+_0x339ad0(0x113)}));}return!![];}if(_0x14f4bb==='/api/bot/r'+_0x339ad0(0x195)&&_0x56183f['method']===_0x4fc67a(0xb9)){const {scheduleGracefulRestart:_0xe80f04}=await import(_0x339ad0(0x11f)+'s/restart.'+'js');return _0x3d4755[_0x4fc67a(0x15a)](JSON['stringify']({'ok':!![],'note':_0x339ad0(0x140)+_0x339ad0(0x1a3)})),_0xe80f04(0x24c7+0x2706+-0x49d9),!![];}if(_0x14f4bb==='/api/pm2/s'+_0x339ad0(0x10f)){try{const {detectProcessManager:_0x7e3c1c}=await import(_0x339ad0(0x11f)+_0x339ad0(0xc0)+'manager.js'),_0x4cd83a=_0x7e3c1c(),_0x2794c7=await _0x4cd83a['getStatus']();_0x3d4755[_0x339ad0(0x15a)](JSON[_0x4fc67a(0x1a7)]({'process':{'name':_0x4fc67a(0x179),'kind':_0x2794c7[_0x4fc67a(0x151)],'pid':_0x2794c7[_0x4fc67a(0x11c)]??0x33f*-0x7+0x1327*-0x1+0x29e0,'status':_0x2794c7[_0x339ad0(0x187)],'uptime':_0x2794c7[_0x339ad0(0x141)]??0xd7*0x1+-0x18b*0x13+0x1c7a,'memory':_0x2794c7['memory']??0x25da+0xdf4+-0x26*0x15d,'cpu':_0x2794c7['cpu']??0x7c5+0x1311+-0x1ad6,'restarts':_0x2794c7[_0x339ad0(0xdf)]??0x498+-0x4c+-0x44c,'version':_0x2794c7[_0x339ad0(0xca)]||'?','nodeVersion':_0x2794c7[_0x339ad0(0x12b)+'n']||process['version'],'execPath':_0x2794c7[_0x4fc67a(0xae)]||'?','cwd':_0x2794c7[_0x4fc67a(0xbe)]||'?'}}));}catch(_0x31678c){const _0x3bc830=_0x31678c instanceof Error?_0x31678c['message']:String(_0x31678c);_0x3d4755[_0x339ad0(0x15a)](JSON['stringify']({'error':_0x4fc67a(0x17c)+_0x339ad0(0x150)+'ction\x20fail'+_0x339ad0(0x13f)+_0x3bc830}));}return!![];}if(_0x14f4bb===_0x339ad0(0xe4)+_0x339ad0(0xce)&&_0x56183f[_0x339ad0(0x119)]===_0x4fc67a(0xb9)){try{const {action:_0x322bea}=JSON[_0x339ad0(0x16a)](_0x4bc090),_0x154edd=['restart','stop',_0x339ad0(0xff),_0x339ad0(0xc8),_0x4fc67a(0x18c)];if(!_0x154edd['includes'](_0x322bea))return _0x3d4755[_0x4fc67a(0xd9)]=0x8f9*0x1+-0x1110+0x9a7,_0x3d4755['end'](JSON['stringify']({'ok':![],'error':_0x339ad0(0x126)+_0x339ad0(0xf8)+_0x322bea})),!![];const {detectProcessManager:_0x57ca44}=await import(_0x339ad0(0x11f)+_0x4fc67a(0xc0)+'manager.js'),_0x58f34c=_0x57ca44();if(_0x322bea==='flush'){const _0x448e04=resolve(DATA_DIR,_0x339ad0(0x12d));for(const _0x5cd83f of[_0x339ad0(0x12c)+_0x339ad0(0xf9),_0x4fc67a(0x12c)+_0x339ad0(0xfc)]){try{_0x45d141[_0x339ad0(0x129)+'nc'](resolve(_0x448e04,_0x5cd83f),0xc06+0x1732+-0x2338);}catch{}}return _0x3d4755[_0x339ad0(0x15a)](JSON[_0x4fc67a(0x1a7)]({'ok':!![],'message':'Logs\x20flush'+'ed'})),!![];}if(_0x322bea==='stop')return _0x3d4755[_0x4fc67a(0x15a)](JSON[_0x339ad0(0x1a7)]({'ok':!![],'message':_0x4fc67a(0x18b)+_0x339ad0(0x12a)+_0x58f34c['kind']+_0x339ad0(0x111)})),setTimeout(()=>{const _0x361a7a=_0x339ad0;_0x58f34c['stop']()[_0x361a7a(0x120)](()=>{});},0x1*0x1a6b+0x1ca3+-0x35e2),!![];if(_0x322bea==='start')return await _0x58f34c[_0x339ad0(0xff)](),_0x3d4755[_0x4fc67a(0x15a)](JSON['stringify']({'ok':!![],'message':_0x339ad0(0x16f)+_0x4fc67a(0xbf)+_0x58f34c[_0x339ad0(0x151)]})),!![];if(_0x322bea===_0x339ad0(0xed)||_0x322bea===_0x339ad0(0xc8)){const {scheduleGracefulRestart:_0x26b3ae}=await import(_0x339ad0(0x11f)+_0x4fc67a(0xe1)+'js');return _0x3d4755[_0x4fc67a(0x15a)](JSON[_0x339ad0(0x1a7)]({'ok':!![],'message':_0x339ad0(0x103)+(_0x322bea===_0x4fc67a(0xed)?_0x339ad0(0x13e):'reloading')+'\x20('+_0x58f34c[_0x4fc67a(0x151)]+')...'})),_0x26b3ae(0x9ec+-0x1*-0x2072+0x2*-0x1435),!![];}}catch(_0xb2455b){_0x3d4755[_0x4fc67a(0x15a)](JSON[_0x4fc67a(0x1a7)]({'ok':![],'error':_0xb2455b instanceof Error?_0xb2455b[_0x4fc67a(0x10b)]:String(_0xb2455b)}));}return!![];}if(_0x14f4bb==='/api/pm2/l'+_0x339ad0(0x13c)){try{const {detectProcessManager:_0x359b94}=await import(_0x339ad0(0x11f)+_0x4fc67a(0xc0)+_0x4fc67a(0xfb)),_0xa49dd8=_0x359b94(),_0x1b27dc=await _0xa49dd8[_0x339ad0(0x15e)](0x1*0x1a4d+-0x1a94+0x65);_0x3d4755[_0x4fc67a(0x15a)](JSON[_0x339ad0(0x1a7)]({'logs':_0x1b27dc,'kind':_0xa49dd8[_0x339ad0(0x151)]}));}catch(_0x3175a0){_0x3d4755[_0x4fc67a(0x15a)](JSON[_0x4fc67a(0x1a7)]({'error':_0x4fc67a(0xf1)+_0x4fc67a(0x125),'logs':'','detail':_0x3175a0 instanceof Error?_0x3175a0[_0x339ad0(0x10b)]:String(_0x3175a0)}));}return!![];}return![];}