alvin-bot 5.7.0 → 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 (136) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/claude.js +1 -102
  3. package/dist/config.js +1 -96
  4. package/dist/engine.js +1 -90
  5. package/dist/find-claude-binary.js +1 -98
  6. package/dist/handlers/async-agent-chunk-handler.js +1 -50
  7. package/dist/handlers/background-bypass.js +1 -75
  8. package/dist/handlers/commands.js +1 -2336
  9. package/dist/handlers/cron-progress.js +1 -52
  10. package/dist/handlers/document.js +1 -194
  11. package/dist/handlers/message.js +1 -959
  12. package/dist/handlers/photo.js +1 -154
  13. package/dist/handlers/platform-message.js +1 -360
  14. package/dist/handlers/stuck-timer.js +1 -54
  15. package/dist/handlers/video.js +1 -237
  16. package/dist/handlers/voice.js +1 -148
  17. package/dist/i18n.js +1 -805
  18. package/dist/index.js +1 -697
  19. package/dist/init-data-dir.js +1 -98
  20. package/dist/middleware/auth.js +1 -233
  21. package/dist/migrate.js +1 -162
  22. package/dist/paths.js +1 -146
  23. package/dist/platforms/discord.js +1 -175
  24. package/dist/platforms/index.js +1 -130
  25. package/dist/platforms/signal.js +1 -205
  26. package/dist/platforms/slack-slash-parser.js +1 -32
  27. package/dist/platforms/slack.js +1 -501
  28. package/dist/platforms/telegram.js +1 -111
  29. package/dist/platforms/types.js +1 -8
  30. package/dist/platforms/whatsapp-auth-helpers.js +1 -53
  31. package/dist/platforms/whatsapp.js +1 -707
  32. package/dist/providers/claude-sdk-provider.js +1 -565
  33. package/dist/providers/codex-cli-provider.js +1 -134
  34. package/dist/providers/index.js +1 -7
  35. package/dist/providers/ollama-provider.js +1 -32
  36. package/dist/providers/openai-compatible.js +1 -406
  37. package/dist/providers/registry.js +1 -352
  38. package/dist/providers/runtime-header.js +1 -45
  39. package/dist/providers/tool-executor.js +1 -475
  40. package/dist/providers/types.js +1 -227
  41. package/dist/services/access.js +1 -144
  42. package/dist/services/allowed-users-gate.js +1 -56
  43. package/dist/services/alvin-dispatch.js +1 -174
  44. package/dist/services/alvin-mcp-tools.js +1 -104
  45. package/dist/services/asset-index.js +1 -224
  46. package/dist/services/async-agent-parser.js +1 -418
  47. package/dist/services/async-agent-watcher.js +1 -583
  48. package/dist/services/auto-diagnostic.js +1 -228
  49. package/dist/services/broadcast.js +1 -52
  50. package/dist/services/browser-manager.js +1 -562
  51. package/dist/services/browser-webfetch.js +1 -127
  52. package/dist/services/browser.js +1 -121
  53. package/dist/services/cdp-bootstrap.js +1 -357
  54. package/dist/services/compaction.js +1 -144
  55. package/dist/services/critical-notify.js +1 -203
  56. package/dist/services/cron-resolver.js +1 -58
  57. package/dist/services/cron-scheduling.js +1 -310
  58. package/dist/services/cron.js +1 -861
  59. package/dist/services/custom-tools.js +1 -317
  60. package/dist/services/delivery-queue.js +1 -173
  61. package/dist/services/delivery-registry.js +1 -21
  62. package/dist/services/disk-cleanup.js +1 -203
  63. package/dist/services/elevenlabs.js +1 -58
  64. package/dist/services/embeddings/auto-detect.js +1 -74
  65. package/dist/services/embeddings/fts5.js +1 -108
  66. package/dist/services/embeddings/gemini.js +1 -65
  67. package/dist/services/embeddings/index.js +1 -496
  68. package/dist/services/embeddings/ollama.js +1 -78
  69. package/dist/services/embeddings/openai.js +1 -49
  70. package/dist/services/embeddings/provider.js +1 -22
  71. package/dist/services/embeddings/vector-base.js +1 -113
  72. package/dist/services/embeddings-migration.js +1 -193
  73. package/dist/services/embeddings.js +1 -9
  74. package/dist/services/env-file.js +1 -50
  75. package/dist/services/exec-guard.js +1 -71
  76. package/dist/services/fallback-order.js +1 -154
  77. package/dist/services/file-permissions.js +1 -93
  78. package/dist/services/heartbeat-file.js +1 -65
  79. package/dist/services/heartbeat.js +1 -313
  80. package/dist/services/hooks.js +1 -44
  81. package/dist/services/imagegen.js +1 -72
  82. package/dist/services/language-detect.js +1 -154
  83. package/dist/services/markdown.js +1 -63
  84. package/dist/services/mcp.js +1 -263
  85. package/dist/services/memory-extractor.js +1 -178
  86. package/dist/services/memory-inject-mode.js +1 -43
  87. package/dist/services/memory-layers.js +1 -156
  88. package/dist/services/memory.js +1 -146
  89. package/dist/services/ollama-manager.js +1 -339
  90. package/dist/services/permissions-wizard.js +1 -291
  91. package/dist/services/personality.js +1 -376
  92. package/dist/services/plugins.js +1 -171
  93. package/dist/services/preflight.js +1 -292
  94. package/dist/services/process-manager.js +1 -291
  95. package/dist/services/release-highlights.js +1 -79
  96. package/dist/services/reminders.js +1 -97
  97. package/dist/services/restart.js +1 -48
  98. package/dist/services/security-audit.js +1 -74
  99. package/dist/services/self-diagnosis.js +1 -272
  100. package/dist/services/self-search.js +1 -129
  101. package/dist/services/session-persistence.js +1 -237
  102. package/dist/services/session.js +1 -282
  103. package/dist/services/skills.js +1 -290
  104. package/dist/services/ssrf-guard.js +1 -162
  105. package/dist/services/standing-orders.js +1 -29
  106. package/dist/services/steer-channel.js +1 -46
  107. package/dist/services/stop-controller.js +1 -52
  108. package/dist/services/subagent-dedup.js +1 -86
  109. package/dist/services/subagent-delivery.js +1 -452
  110. package/dist/services/subagent-stats.js +1 -123
  111. package/dist/services/subagents.js +1 -814
  112. package/dist/services/sudo.js +1 -329
  113. package/dist/services/telegram.js +1 -158
  114. package/dist/services/timing-safe-bearer.js +1 -51
  115. package/dist/services/tool-discovery.js +1 -214
  116. package/dist/services/trends.js +1 -580
  117. package/dist/services/updater.js +1 -291
  118. package/dist/services/usage-tracker.js +1 -144
  119. package/dist/services/users.js +1 -271
  120. package/dist/services/voice.js +1 -104
  121. package/dist/services/watchdog-brake.js +1 -154
  122. package/dist/services/watchdog.js +1 -311
  123. package/dist/services/workspaces.js +1 -276
  124. package/dist/tui/index.js +1 -667
  125. package/dist/util/console-formatter.js +1 -109
  126. package/dist/util/debounce.js +1 -24
  127. package/dist/util/telegram-error-filter.js +1 -62
  128. package/dist/version.js +1 -24
  129. package/dist/web/bind-strategy.js +1 -42
  130. package/dist/web/canvas.js +1 -30
  131. package/dist/web/doctor-api.js +1 -604
  132. package/dist/web/openai-compat.js +1 -252
  133. package/dist/web/server.js +1 -1902
  134. package/dist/web/setup-api.js +1 -1101
  135. package/package.json +5 -2
  136. 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![];}