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.
- package/CHANGELOG.md +13 -0
- package/dist/claude.js +1 -102
- package/dist/config.js +1 -96
- package/dist/engine.js +1 -90
- package/dist/find-claude-binary.js +1 -98
- package/dist/handlers/async-agent-chunk-handler.js +1 -50
- package/dist/handlers/background-bypass.js +1 -75
- package/dist/handlers/commands.js +1 -2336
- package/dist/handlers/cron-progress.js +1 -52
- package/dist/handlers/document.js +1 -194
- package/dist/handlers/message.js +1 -959
- package/dist/handlers/photo.js +1 -154
- package/dist/handlers/platform-message.js +1 -360
- package/dist/handlers/stuck-timer.js +1 -54
- package/dist/handlers/video.js +1 -237
- package/dist/handlers/voice.js +1 -148
- package/dist/i18n.js +1 -805
- package/dist/index.js +1 -697
- package/dist/init-data-dir.js +1 -98
- package/dist/middleware/auth.js +1 -233
- package/dist/migrate.js +1 -162
- package/dist/paths.js +1 -146
- package/dist/platforms/discord.js +1 -175
- package/dist/platforms/index.js +1 -130
- package/dist/platforms/signal.js +1 -205
- package/dist/platforms/slack-slash-parser.js +1 -32
- package/dist/platforms/slack.js +1 -501
- package/dist/platforms/telegram.js +1 -111
- package/dist/platforms/types.js +1 -8
- package/dist/platforms/whatsapp-auth-helpers.js +1 -53
- package/dist/platforms/whatsapp.js +1 -707
- package/dist/providers/claude-sdk-provider.js +1 -565
- package/dist/providers/codex-cli-provider.js +1 -134
- package/dist/providers/index.js +1 -7
- package/dist/providers/ollama-provider.js +1 -32
- package/dist/providers/openai-compatible.js +1 -406
- package/dist/providers/registry.js +1 -352
- package/dist/providers/runtime-header.js +1 -45
- package/dist/providers/tool-executor.js +1 -475
- package/dist/providers/types.js +1 -227
- package/dist/services/access.js +1 -144
- package/dist/services/allowed-users-gate.js +1 -56
- package/dist/services/alvin-dispatch.js +1 -174
- package/dist/services/alvin-mcp-tools.js +1 -104
- package/dist/services/asset-index.js +1 -224
- package/dist/services/async-agent-parser.js +1 -418
- package/dist/services/async-agent-watcher.js +1 -583
- package/dist/services/auto-diagnostic.js +1 -228
- package/dist/services/broadcast.js +1 -52
- package/dist/services/browser-manager.js +1 -562
- package/dist/services/browser-webfetch.js +1 -127
- package/dist/services/browser.js +1 -121
- package/dist/services/cdp-bootstrap.js +1 -357
- package/dist/services/compaction.js +1 -144
- package/dist/services/critical-notify.js +1 -203
- package/dist/services/cron-resolver.js +1 -58
- package/dist/services/cron-scheduling.js +1 -310
- package/dist/services/cron.js +1 -861
- package/dist/services/custom-tools.js +1 -317
- package/dist/services/delivery-queue.js +1 -173
- package/dist/services/delivery-registry.js +1 -21
- package/dist/services/disk-cleanup.js +1 -203
- package/dist/services/elevenlabs.js +1 -58
- package/dist/services/embeddings/auto-detect.js +1 -74
- package/dist/services/embeddings/fts5.js +1 -108
- package/dist/services/embeddings/gemini.js +1 -65
- package/dist/services/embeddings/index.js +1 -496
- package/dist/services/embeddings/ollama.js +1 -78
- package/dist/services/embeddings/openai.js +1 -49
- package/dist/services/embeddings/provider.js +1 -22
- package/dist/services/embeddings/vector-base.js +1 -113
- package/dist/services/embeddings-migration.js +1 -193
- package/dist/services/embeddings.js +1 -9
- package/dist/services/env-file.js +1 -50
- package/dist/services/exec-guard.js +1 -71
- package/dist/services/fallback-order.js +1 -154
- package/dist/services/file-permissions.js +1 -93
- package/dist/services/heartbeat-file.js +1 -65
- package/dist/services/heartbeat.js +1 -313
- package/dist/services/hooks.js +1 -44
- package/dist/services/imagegen.js +1 -72
- package/dist/services/language-detect.js +1 -154
- package/dist/services/markdown.js +1 -63
- package/dist/services/mcp.js +1 -263
- package/dist/services/memory-extractor.js +1 -178
- package/dist/services/memory-inject-mode.js +1 -43
- package/dist/services/memory-layers.js +1 -156
- package/dist/services/memory.js +1 -146
- package/dist/services/ollama-manager.js +1 -339
- package/dist/services/permissions-wizard.js +1 -291
- package/dist/services/personality.js +1 -376
- package/dist/services/plugins.js +1 -171
- package/dist/services/preflight.js +1 -292
- package/dist/services/process-manager.js +1 -291
- package/dist/services/release-highlights.js +1 -79
- package/dist/services/reminders.js +1 -97
- package/dist/services/restart.js +1 -48
- package/dist/services/security-audit.js +1 -74
- package/dist/services/self-diagnosis.js +1 -272
- package/dist/services/self-search.js +1 -129
- package/dist/services/session-persistence.js +1 -237
- package/dist/services/session.js +1 -282
- package/dist/services/skills.js +1 -290
- package/dist/services/ssrf-guard.js +1 -162
- package/dist/services/standing-orders.js +1 -29
- package/dist/services/steer-channel.js +1 -46
- package/dist/services/stop-controller.js +1 -52
- package/dist/services/subagent-dedup.js +1 -86
- package/dist/services/subagent-delivery.js +1 -452
- package/dist/services/subagent-stats.js +1 -123
- package/dist/services/subagents.js +1 -814
- package/dist/services/sudo.js +1 -329
- package/dist/services/telegram.js +1 -158
- package/dist/services/timing-safe-bearer.js +1 -51
- package/dist/services/tool-discovery.js +1 -214
- package/dist/services/trends.js +1 -580
- package/dist/services/updater.js +1 -291
- package/dist/services/usage-tracker.js +1 -144
- package/dist/services/users.js +1 -271
- package/dist/services/voice.js +1 -104
- package/dist/services/watchdog-brake.js +1 -154
- package/dist/services/watchdog.js +1 -311
- package/dist/services/workspaces.js +1 -276
- package/dist/tui/index.js +1 -667
- package/dist/util/console-formatter.js +1 -109
- package/dist/util/debounce.js +1 -24
- package/dist/util/telegram-error-filter.js +1 -62
- package/dist/version.js +1 -24
- package/dist/web/bind-strategy.js +1 -42
- package/dist/web/canvas.js +1 -30
- package/dist/web/doctor-api.js +1 -604
- package/dist/web/openai-compat.js +1 -252
- package/dist/web/server.js +1 -1902
- package/dist/web/setup-api.js +1 -1101
- package/package.json +5 -2
- package/dist/.metadata_never_index +0 -0
|
@@ -1,71 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { config } from "../config.js";
|
|
3
|
-
import { EXEC_ALLOWLIST_FILE } from "../paths.js";
|
|
4
|
-
const SAFE_BINS = [
|
|
5
|
-
"ls", "cat", "head", "tail", "grep", "rg", "find", "wc", "sort", "uniq",
|
|
6
|
-
"echo", "printf", "date", "which", "whoami", "hostname", "uname",
|
|
7
|
-
"curl", "wget", "git", "node", "npm", "npx", "python3", "pip3",
|
|
8
|
-
"jq", "ffmpeg", "ffprobe", "ffplay",
|
|
9
|
-
"mkdir", "touch", "cp", "mv", "ln", "chmod",
|
|
10
|
-
"tar", "zip", "unzip", "gzip", "gunzip",
|
|
11
|
-
"ssh", "scp", "rsync",
|
|
12
|
-
"docker", "docker-compose",
|
|
13
|
-
"brew", "open", "pbcopy", "pbpaste",
|
|
14
|
-
"osascript", "defaults", "launchctl",
|
|
15
|
-
];
|
|
16
|
-
function loadUserAllowlist() {
|
|
17
|
-
if (!existsSync(EXEC_ALLOWLIST_FILE))
|
|
18
|
-
return [];
|
|
19
|
-
try {
|
|
20
|
-
return JSON.parse(readFileSync(EXEC_ALLOWLIST_FILE, "utf-8"));
|
|
21
|
-
}
|
|
22
|
-
catch {
|
|
23
|
-
return [];
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
function extractBinary(command) {
|
|
27
|
-
// Get first word, strip env vars, handle pipes
|
|
28
|
-
const cleaned = command.replace(/^(env\s+\w+=\S+\s+)+/, "").trim();
|
|
29
|
-
const first = cleaned.split(/[\s|;&]/)[0];
|
|
30
|
-
// Strip path: /usr/bin/curl -> curl
|
|
31
|
-
return first.split("/").pop() || first;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* v4.12.2 — Reject shell metacharacters in allowlist mode.
|
|
35
|
-
*
|
|
36
|
-
* The pre-v4.12.2 allowlist check only inspected the first word of the
|
|
37
|
-
* command. That was trivially bypassable via:
|
|
38
|
-
* - ";" chaining: "echo safe; rm -rf /"
|
|
39
|
-
* - "&&" / "||" chains: "echo hi && cat /etc/passwd"
|
|
40
|
-
* - pipe: "cat /etc/passwd | head"
|
|
41
|
-
* - substitution: "echo $(whoami)" or "`whoami`"
|
|
42
|
-
* - redirect: "echo hi > /etc/passwd"
|
|
43
|
-
* - backgrounding: "... &"
|
|
44
|
-
*
|
|
45
|
-
* Strategy: in allowlist mode, any command containing any of these
|
|
46
|
-
* metachars is rejected outright. Users who need shell pipelines opt in
|
|
47
|
-
* explicitly via EXEC_SECURITY=full.
|
|
48
|
-
*/
|
|
49
|
-
const SHELL_METACHAR_PATTERN = /[;&|`$(){}<>]/;
|
|
50
|
-
export function checkExecAllowed(command) {
|
|
51
|
-
if (config.execSecurity === "full")
|
|
52
|
-
return { allowed: true };
|
|
53
|
-
if (config.execSecurity === "deny")
|
|
54
|
-
return { allowed: false, reason: "Shell execution is disabled" };
|
|
55
|
-
// allowlist mode — v4.12.2 metachar guard
|
|
56
|
-
if (SHELL_METACHAR_PATTERN.test(command)) {
|
|
57
|
-
return {
|
|
58
|
-
allowed: false,
|
|
59
|
-
reason: `Command contains shell metacharacters (pipes, redirects, substitution, chaining). ` +
|
|
60
|
-
`Allowlist mode only permits simple binary invocations. ` +
|
|
61
|
-
`Set EXEC_SECURITY=full if you need shell pipelines.`,
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
const binary = extractBinary(command);
|
|
65
|
-
if (SAFE_BINS.includes(binary))
|
|
66
|
-
return { allowed: true };
|
|
67
|
-
const userList = loadUserAllowlist();
|
|
68
|
-
if (userList.includes(binary))
|
|
69
|
-
return { allowed: true };
|
|
70
|
-
return { allowed: false, reason: `Binary "${binary}" not in allowlist. Add to ${EXEC_ALLOWLIST_FILE} or set EXEC_SECURITY=full` };
|
|
71
|
-
}
|
|
1
|
+
const _0x3d8ff0=_0x29bb,_0x3e8fdf=_0x29bb;(function(_0x2586d7,_0x35119a){const _0x56eef1=_0x29bb,_0x38036d=_0x29bb,_0x2b7f4b=_0x2586d7();while(!![]){try{const _0x409b1d=parseInt(_0x56eef1(0xb0))/(-0xad*-0x5+0x3d*-0x4f+-0x317*-0x5)+-parseInt(_0x38036d(0xbd))/(0x1*-0xe03+0xd69+0x9c)+-parseInt(_0x56eef1(0xbc))/(0x12cc+0x607*0x1+0x1*-0x18d0)+-parseInt(_0x38036d(0x91))/(-0x1*0x1f75+-0x661+0x3c9*0xa)+parseInt(_0x38036d(0x97))/(0x2b2+-0x2122+0x1e75)*(parseInt(_0x56eef1(0xa4))/(-0x7a2+-0x14bf+0x1c67))+-parseInt(_0x56eef1(0x7e))/(0x1ab6+0xcc+-0x3*0x929)+parseInt(_0x56eef1(0xaf))/(0xe*-0xf+-0x292+-0x4*-0xdb);if(_0x409b1d===_0x35119a)break;else _0x2b7f4b['push'](_0x2b7f4b['shift']());}catch(_0x155ea2){_0x2b7f4b['push'](_0x2b7f4b['shift']());}}}(_0x15e3,0x2*0x4227b+-0x1*0x730fe+-0x665*-0x91));const _0x282c7b=(function(){let _0x15bc31=!![];return function(_0x40b3ea,_0x24f67a){const _0x29c879=_0x15bc31?function(){const _0x2de65a=_0x29bb;if(_0x24f67a){const _0x270ac7=_0x24f67a[_0x2de65a(0x8e)](_0x40b3ea,arguments);return _0x24f67a=null,_0x270ac7;}}:function(){};return _0x15bc31=![],_0x29c879;};}()),_0x3e9742=_0x282c7b(this,function(){const _0x30cc5e=_0x29bb,_0x5a5bf2=_0x29bb;return _0x3e9742[_0x30cc5e(0xa1)]()[_0x5a5bf2(0x94)](_0x30cc5e(0x95)+'+$')[_0x5a5bf2(0xa1)]()['constructo'+'r'](_0x3e9742)[_0x5a5bf2(0x94)]('(((.+)+)+)'+'+$');});_0x3e9742();function _0x29bb(_0x2586d7,_0x35119a){_0x2586d7=_0x2586d7-(0xdec+-0x5*-0x632+-0x2c69);const _0x2b7f4b=_0x15e3();let _0x409b1d=_0x2b7f4b[_0x2586d7];if(_0x29bb['chDuRr']===undefined){var _0x155ea2=function(_0x5ac502){const _0x310e6e='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x1360aa='',_0x302a7d='',_0x3b25e2=_0x1360aa+_0x155ea2;for(let _0x42db98=0x5*-0xfa+-0x1770+-0x32*-0x91,_0x840a88,_0x3f1366,_0x21ee82=0x655*-0x2+-0x3*-0xc9c+-0xc95*0x2;_0x3f1366=_0x5ac502['charAt'](_0x21ee82++);~_0x3f1366&&(_0x840a88=_0x42db98%(-0x1544+0xdf1+0x757)?_0x840a88*(-0x151c+0x1*0x1d4b+-0x7ef)+_0x3f1366:_0x3f1366,_0x42db98++%(-0x1502+0x15a+0x13ac))?_0x1360aa+=_0x3b25e2['charCodeAt'](_0x21ee82+(0x11c1+-0x34d+-0xe6a))-(-0x4e7*0x5+0x1354+-0xbf*-0x7)!==-0x386*0x2+0x1e82+-0x1776?String['fromCharCode'](0xe7c+-0x21a6*0x1+0x1429&_0x840a88>>(-(-0x2309*-0x1+-0x1*0x1525+-0xde2*0x1)*_0x42db98&0x5b3+0x136d*0x1+0x11*-0x17a)):_0x42db98:-0xeae+-0x2*0xa0a+0x22c2){_0x3f1366=_0x310e6e['indexOf'](_0x3f1366);}for(let _0x196987=-0x1*-0xf0b+0x1*-0x1e2f+0xf24,_0xb5e9fb=_0x1360aa['length'];_0x196987<_0xb5e9fb;_0x196987++){_0x302a7d+='%'+('00'+_0x1360aa['charCodeAt'](_0x196987)['toString'](0x1073*0x1+-0x24b1+0x144e))['slice'](-(-0xad*-0x5+0x3d*-0x4f+-0x7ba*-0x2));}return decodeURIComponent(_0x302a7d);};_0x29bb['rLfuzd']=_0x155ea2,_0x29bb['DxrCHy']={},_0x29bb['chDuRr']=!![];}const _0xbe45a5=_0x2b7f4b[0x1*-0xe03+0xd69+0x9a],_0x366946=_0x2586d7+_0xbe45a5,_0x45ca4e=_0x29bb['DxrCHy'][_0x366946];if(!_0x45ca4e){const _0x189000=function(_0x1c21ca){this['awDHvy']=_0x1c21ca,this['wWziFW']=[0x12cc+0x607*0x1+0x1*-0x18d2,-0x1*0x1f75+-0x661+0x12eb*0x2,0x2b2+-0x2122+0x1e70],this['YFZpgs']=function(){return'newState';},this['WpWixw']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['uaxeZQ']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x189000['prototype']['bkcxoN']=function(){const _0x3037f7=new RegExp(this['WpWixw']+this['uaxeZQ']),_0x5c73d6=_0x3037f7['test'](this['YFZpgs']['toString']())?--this['wWziFW'][-0x7a2+-0x14bf+0x1c62]:--this['wWziFW'][0x1ab6+0xcc+-0x1*0x1b82];return this['vORxih'](_0x5c73d6);},_0x189000['prototype']['vORxih']=function(_0x1af87f){if(!Boolean(~_0x1af87f))return _0x1af87f;return this['AJhPpA'](this['awDHvy']);},_0x189000['prototype']['AJhPpA']=function(_0x487d1d){for(let _0x4c2cd5=0xe*-0xf+-0x292+-0x7*-0x7c,_0x507297=this['wWziFW']['length'];_0x4c2cd5<_0x507297;_0x4c2cd5++){this['wWziFW']['push'](Math['round'](Math['random']())),_0x507297=this['wWziFW']['length'];}return _0x487d1d(this['wWziFW'][0x2*0x112f+-0x1*0x1de3+-0x25*0x1f]);},new _0x189000(_0x29bb)['bkcxoN'](),_0x409b1d=_0x29bb['rLfuzd'](_0x409b1d),_0x29bb['DxrCHy'][_0x366946]=_0x409b1d;}else _0x409b1d=_0x45ca4e;return _0x409b1d;}import{readFileSync,existsSync}from'fs';function _0x15e3(){const _0x1a011a=['CgjJB3b5','C2nW','z3vUEMLW','zgvUEq','y2HTB2q','zMzWBgf5','C3rPDhv0Aw9Ula','Dw56Axa','wt1MDwXS','BNb4','yxbWBhK','qMLUyxj5ici','CgjWyxn0zq','mJa0nZm0meD2rwfetq','DgfY','zMzWCM9Izq','C2vHCMnO','kcGOlISPkYKRkq','DgfPBa','nwjbwLjhCq','zgvMyxvSDhm','BNrHAw5ZihnOzq','EsbPBNzVy2f0Aq','z3jLCa','zgf0zq','zMLUza','BwTKAxi','u2HLBgWGzxHLyW','runvuKLuwt1MDq','Dg9tDhjPBMC','CMvWBgfJzq','z3PPCa','mty3otCXog1SwxHHsW','AgvHza','ignOywLUAw5Nkq','Dg91y2G','Cg9W','BxbSzsbIAw5HCG','ChjPBNrM','zg9JA2vYlwnVBq','BNbT','zxHLy1nLy3vYAq','zNvSBa','odq2nJi4meTIvvLOAa','mJeZmJbuAxzvugm','CgvYBwL0CYbZAq','EMLW','CMfJDgvYCYaOCa','D2HVyw1P','yNjLDW','DhjPBq','C3nO','CMvJDhmSihn1yG','Ag9ZDg5HBwu','Aw5JBhvKzxm','DxrMltG','mte2ntuXogjWwgXlyW','mtK4mZy0yxDkzgfc','D2HPy2G','DgvZDa','u2v0ievyrunFuW','BM9Kzq','qwrKihrVia','DxrPB24GAxmGza','mZy0mtu0zKrYreL1','Bgf1BMnOy3rS','y2f0','qwXSB3DSAxn0ia','Dw5HBwu','Bw9KzsbVBMX5ia'];_0x15e3=function(){return _0x1a011a;};return _0x15e3();}import{config}from'../config.js';import{EXEC_ALLOWLIST_FILE}from'../paths.js';const SAFE_BINS=['ls',_0x3d8ff0(0x80),_0x3e8fdf(0xa5),_0x3d8ff0(0x96),_0x3d8ff0(0x9b),'rg',_0x3d8ff0(0x9d),'wc','sort','uniq','echo',_0x3d8ff0(0xaa),_0x3d8ff0(0x9c),_0x3d8ff0(0xbe),_0x3d8ff0(0xb4),_0x3e8fdf(0xb9),_0x3e8fdf(0x82),'curl','wget','git',_0x3d8ff0(0xc1),_0x3e8fdf(0xac),_0x3e8fdf(0x8d),'python3','pip3','jq','ffmpeg',_0x3d8ff0(0x93),_0x3d8ff0(0x89),_0x3d8ff0(0x9e),_0x3d8ff0(0xa7),'cp','mv','ln',_0x3e8fdf(0x88),_0x3d8ff0(0x92),_0x3e8fdf(0xb2),_0x3e8fdf(0x8b),_0x3d8ff0(0xa3),_0x3e8fdf(0x86),_0x3e8fdf(0xb7),_0x3d8ff0(0x85),'rsync','docker',_0x3d8ff0(0xab)+'pose',_0x3d8ff0(0xb5),'open',_0x3e8fdf(0x84),_0x3e8fdf(0x90),'osascript',_0x3e8fdf(0x98),_0x3e8fdf(0x7f)];function loadUserAllowlist(){const _0x212d33=_0x3e8fdf;if(!existsSync(EXEC_ALLOWLIST_FILE))return[];try{return JSON['parse'](readFileSync(EXEC_ALLOWLIST_FILE,_0x212d33(0xbb)));}catch{return[];}}function extractBinary(_0x15ec64){const _0x4452f4=_0x3d8ff0,_0x488f3a=_0x3d8ff0,_0x5370dc=_0x15ec64[_0x4452f4(0xa2)](/^(env\s+\w+=\S+\s+)+/,'')[_0x488f3a(0xb6)](),_0x2c3af4=_0x5370dc['split'](/[\s|;&]/)[0x655*-0x2+-0x3*-0xc9c+-0xc95*0x2];return _0x2c3af4['split']('/')[_0x4452f4(0xa8)]()||_0x2c3af4;}const SHELL_METACHAR_PATTERN=/[;&|`$(){}<>]/;export function checkExecAllowed(_0x5ebc82){const _0x249a08=_0x3e8fdf,_0x19ff30=_0x3e8fdf;if(config['execSecuri'+'ty']===_0x249a08(0xae))return{'allowed':!![]};if(config[_0x19ff30(0xad)+'ty']===_0x249a08(0x87))return{'allowed':![],'reason':_0x249a08(0x9f)+_0x249a08(0x7d)+'isabled'};if(SHELL_METACHAR_PATTERN[_0x19ff30(0xbf)](_0x5ebc82))return{'allowed':![],'reason':'Command\x20co'+_0x19ff30(0x99)+'ll\x20metacha'+_0x19ff30(0xb3)+'ipes,\x20redi'+_0x249a08(0xb8)+_0x249a08(0x8a)+_0x19ff30(0xa6)+'.\x20'+(_0x249a08(0x81)+_0x249a08(0x83)+_0x19ff30(0xb1)+_0x19ff30(0xa9)+_0x19ff30(0x9a)+'ons.\x20')+(_0x249a08(0xc0)+_0x249a08(0xa0)+'ll\x20if\x20you\x20'+'need\x20shell'+'\x20pipelines'+'.')};const _0x3c35f7=extractBinary(_0x5ebc82);if(SAFE_BINS[_0x19ff30(0xba)](_0x3c35f7))return{'allowed':!![]};const _0x1a68a2=loadUserAllowlist();if(_0x1a68a2['includes'](_0x3c35f7))return{'allowed':!![]};return{'allowed':![],'reason':_0x19ff30(0x8f)+_0x3c35f7+('\x22\x20not\x20in\x20a'+'llowlist.\x20'+_0x19ff30(0xc2))+EXEC_ALLOWLIST_FILE+('\x20or\x20set\x20EX'+'EC_SECURIT'+_0x19ff30(0x8c))};}
|
|
@@ -1,154 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Fallback Order Manager — Persistent, user-configurable provider fallback chain.
|
|
3
|
-
*
|
|
4
|
-
* Supports reading/writing the fallback order from:
|
|
5
|
-
* - Telegram (/fallback command)
|
|
6
|
-
* - Web UI (API endpoint)
|
|
7
|
-
* - CLI/Terminal
|
|
8
|
-
*
|
|
9
|
-
* Persists to docs/fallback-order.json and syncs with .env FALLBACK_PROVIDERS.
|
|
10
|
-
*/
|
|
11
|
-
import fs from "fs";
|
|
12
|
-
import { FALLBACK_FILE, ENV_FILE, DATA_DIR } from "../paths.js";
|
|
13
|
-
import { writeSecure } from "./file-permissions.js";
|
|
14
|
-
// ── Public API ──────────────────────────────────────────────────────────────
|
|
15
|
-
/**
|
|
16
|
-
* Get the current fallback order.
|
|
17
|
-
*/
|
|
18
|
-
export function getFallbackOrder() {
|
|
19
|
-
try {
|
|
20
|
-
if (fs.existsSync(FALLBACK_FILE)) {
|
|
21
|
-
return JSON.parse(fs.readFileSync(FALLBACK_FILE, "utf-8"));
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
catch { /* ignore */ }
|
|
25
|
-
// Default from env
|
|
26
|
-
return {
|
|
27
|
-
primary: process.env.PRIMARY_PROVIDER || "groq",
|
|
28
|
-
fallbacks: (process.env.FALLBACK_PROVIDERS || "")
|
|
29
|
-
.split(",")
|
|
30
|
-
.map(s => s.trim())
|
|
31
|
-
.filter(Boolean),
|
|
32
|
-
updatedAt: new Date().toISOString(),
|
|
33
|
-
updatedBy: "env",
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Set the fallback order.
|
|
38
|
-
* Updates both docs/fallback-order.json and .env file.
|
|
39
|
-
*/
|
|
40
|
-
export function setFallbackOrder(primary, fallbacks, updatedBy = "unknown") {
|
|
41
|
-
const config = {
|
|
42
|
-
primary,
|
|
43
|
-
fallbacks,
|
|
44
|
-
updatedAt: new Date().toISOString(),
|
|
45
|
-
updatedBy,
|
|
46
|
-
};
|
|
47
|
-
// Ensure data dir exists
|
|
48
|
-
if (!fs.existsSync(DATA_DIR)) {
|
|
49
|
-
fs.mkdirSync(DATA_DIR, { recursive: true });
|
|
50
|
-
}
|
|
51
|
-
// Write JSON
|
|
52
|
-
fs.writeFileSync(FALLBACK_FILE, JSON.stringify(config, null, 2));
|
|
53
|
-
// Sync to .env
|
|
54
|
-
syncToEnv(primary, fallbacks);
|
|
55
|
-
return config;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Move a provider up in the fallback order.
|
|
59
|
-
*/
|
|
60
|
-
export function moveUp(providerKey, updatedBy = "unknown") {
|
|
61
|
-
const current = getFallbackOrder();
|
|
62
|
-
const idx = current.fallbacks.indexOf(providerKey);
|
|
63
|
-
if (idx > 0) {
|
|
64
|
-
// Swap with previous
|
|
65
|
-
[current.fallbacks[idx - 1], current.fallbacks[idx]] =
|
|
66
|
-
[current.fallbacks[idx], current.fallbacks[idx - 1]];
|
|
67
|
-
}
|
|
68
|
-
else if (idx === 0) {
|
|
69
|
-
// Move to primary, old primary becomes first fallback
|
|
70
|
-
const oldPrimary = current.primary;
|
|
71
|
-
current.primary = providerKey;
|
|
72
|
-
current.fallbacks[0] = oldPrimary;
|
|
73
|
-
}
|
|
74
|
-
return setFallbackOrder(current.primary, current.fallbacks, updatedBy);
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Move a provider down in the fallback order.
|
|
78
|
-
*/
|
|
79
|
-
export function moveDown(providerKey, updatedBy = "unknown") {
|
|
80
|
-
const current = getFallbackOrder();
|
|
81
|
-
if (providerKey === current.primary && current.fallbacks.length > 0) {
|
|
82
|
-
// Move primary to first fallback, first fallback becomes primary
|
|
83
|
-
const newPrimary = current.fallbacks[0];
|
|
84
|
-
current.fallbacks[0] = providerKey;
|
|
85
|
-
current.primary = newPrimary;
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
const idx = current.fallbacks.indexOf(providerKey);
|
|
89
|
-
if (idx >= 0 && idx < current.fallbacks.length - 1) {
|
|
90
|
-
[current.fallbacks[idx], current.fallbacks[idx + 1]] =
|
|
91
|
-
[current.fallbacks[idx + 1], current.fallbacks[idx]];
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
return setFallbackOrder(current.primary, current.fallbacks, updatedBy);
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Add a provider to the fallback chain (at the end).
|
|
98
|
-
*/
|
|
99
|
-
export function addFallback(providerKey, updatedBy = "unknown") {
|
|
100
|
-
const current = getFallbackOrder();
|
|
101
|
-
if (!current.fallbacks.includes(providerKey) && providerKey !== current.primary) {
|
|
102
|
-
current.fallbacks.push(providerKey);
|
|
103
|
-
}
|
|
104
|
-
return setFallbackOrder(current.primary, current.fallbacks, updatedBy);
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Remove a provider from the fallback chain.
|
|
108
|
-
*/
|
|
109
|
-
export function removeFallback(providerKey, updatedBy = "unknown") {
|
|
110
|
-
const current = getFallbackOrder();
|
|
111
|
-
current.fallbacks = current.fallbacks.filter(k => k !== providerKey);
|
|
112
|
-
return setFallbackOrder(current.primary, current.fallbacks, updatedBy);
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Format the current order as a human-readable string.
|
|
116
|
-
*/
|
|
117
|
-
export function formatOrder() {
|
|
118
|
-
const config = getFallbackOrder();
|
|
119
|
-
const lines = [];
|
|
120
|
-
lines.push(`1. 🥇 ${config.primary} (Primary)`);
|
|
121
|
-
config.fallbacks.forEach((fb, i) => {
|
|
122
|
-
lines.push(`${i + 2}. ${i === 0 ? "🥈" : i === 1 ? "🥉" : " "} ${fb}`);
|
|
123
|
-
});
|
|
124
|
-
return lines.join("\n");
|
|
125
|
-
}
|
|
126
|
-
// ── Internal ────────────────────────────────────────────────────────────────
|
|
127
|
-
function syncToEnv(primary, fallbacks) {
|
|
128
|
-
try {
|
|
129
|
-
if (!fs.existsSync(ENV_FILE))
|
|
130
|
-
return;
|
|
131
|
-
let env = fs.readFileSync(ENV_FILE, "utf-8");
|
|
132
|
-
// Update PRIMARY_PROVIDER
|
|
133
|
-
if (env.match(/^PRIMARY_PROVIDER=.*/m)) {
|
|
134
|
-
env = env.replace(/^PRIMARY_PROVIDER=.*/m, `PRIMARY_PROVIDER=${primary}`);
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
env += `\nPRIMARY_PROVIDER=${primary}`;
|
|
138
|
-
}
|
|
139
|
-
// Update FALLBACK_PROVIDERS
|
|
140
|
-
const fallbackStr = fallbacks.join(",");
|
|
141
|
-
if (env.match(/^FALLBACK_PROVIDERS=.*/m)) {
|
|
142
|
-
env = env.replace(/^FALLBACK_PROVIDERS=.*/m, `FALLBACK_PROVIDERS=${fallbackStr}`);
|
|
143
|
-
}
|
|
144
|
-
else {
|
|
145
|
-
env += `\nFALLBACK_PROVIDERS=${fallbackStr}`;
|
|
146
|
-
}
|
|
147
|
-
// v4.12.2 — writeSecure enforces 0o600 on .env so other users on the
|
|
148
|
-
// machine can't read tokens/API keys.
|
|
149
|
-
writeSecure(ENV_FILE, env);
|
|
150
|
-
}
|
|
151
|
-
catch (err) {
|
|
152
|
-
console.error("Failed to sync fallback order to .env:", err);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
1
|
+
function _0x3b75(){const _0x224cdb=['nte0nJu2nNjQu2DgCa','odyZmtjrB0nYy2W','yxbWBhK','Ew5J','zMLSDgvY','icHqCMLTyxj5kq','BgvUz3rO','CMvWBgfJzq','zxjYB3i','ChjPBwfYEq','y29UC3rYDwn0BW','z3jVCq','ywnRig9YzgvYia','ChvZAa','C3bSAxq','ufjjtufswv9quG','Dg9tDhjPBMC','BwTKAxjtEw5J','ms4G8j+LHYa','mJqYody5mNzts016vG','uK9wsurfuJ0','C3rYAw5NAwz5','zMfSBgjHy2TZ','mZu4ody2neTMtwnhDq','ndG2mJyYBfHwq1f2','Dw5RBM93BG','Bwf0y2G','cKzbteXcqunlxW','CgfYC2u','ogLKqwrgsq','zxHPC3rZu3LUyW','zM9YrwfJAa','Dg9ju09tDhjPBG','AM9PBG','zw52','kcGOlISPkYKRkq','t1zjrevs','D3jPDgvgAwXLuW','C2vHCMnO','mtu2mJq5mvfwu09uyW','Aw5KzxHpzG','rKfmtejbq0TFua','ntmYnde0nxPusvnAwq','CMvHzezPBgvtEq'];_0x3b75=function(){return _0x224cdb;};return _0x3b75();}const _0x6425ba=_0x5e9c,_0x2fd42f=_0x5e9c;(function(_0x1659d5,_0x48f395){const _0xcb9e41=_0x5e9c,_0x258cfc=_0x5e9c,_0x285ecc=_0x1659d5();while(!![]){try{const _0x4029c8=parseInt(_0xcb9e41(0xd4))/(-0x13*-0x1e9+0x22f7+0x431*-0x11)+parseInt(_0x258cfc(0xe9))/(-0xa*-0x204+-0x15c2+0x19c)+parseInt(_0xcb9e41(0xcf))/(0xd3b+-0x5*-0x521+-0x26dd)+-parseInt(_0x258cfc(0xd3))/(-0x2*0xc6e+0x133e*0x1+0x1*0x5a2)+parseInt(_0xcb9e41(0xe6))/(0x175f*0x1+0x1863*0x1+-0x79*0x65)+-parseInt(_0x258cfc(0xe8))/(0x308*-0x5+-0xb*-0x146+0x4*0x4b)+-parseInt(_0x258cfc(0xe3))/(0xe*-0x123+-0x223*-0x1+0x5d*0x26)*(-parseInt(_0xcb9e41(0xd9))/(-0xc2c+-0x4*-0x826+-0x1464));if(_0x4029c8===_0x48f395)break;else _0x285ecc['push'](_0x285ecc['shift']());}catch(_0x3f568e){_0x285ecc['push'](_0x285ecc['shift']());}}}(_0x3b75,0x1*0x88990+-0x1898d6+0x1d5de7));const _0x3f8a28=(function(){let _0x442a41=!![];return function(_0x5103d5,_0x59335a){const _0x378199=_0x442a41?function(){const _0x5c0c7d=_0x5e9c;if(_0x59335a){const _0x5e6d5d=_0x59335a[_0x5c0c7d(0xea)](_0x5103d5,arguments);return _0x59335a=null,_0x5e6d5d;}}:function(){};return _0x442a41=![],_0x378199;};}()),_0x4276c7=_0x3f8a28(this,function(){const _0x347d3b=_0x5e9c,_0x3fafc5=_0x5e9c;return _0x4276c7['toString']()[_0x347d3b(0xe2)](_0x347d3b(0xdf)+'+$')[_0x347d3b(0xcc)]()[_0x3fafc5(0xc6)+'r'](_0x4276c7)[_0x347d3b(0xe2)](_0x3fafc5(0xdf)+'+$');});_0x4276c7();import _0x19e285 from'fs';import{FALLBACK_FILE,ENV_FILE,DATA_DIR}from'../paths.js';import{writeSecure}from'./file-permissions.js';export function getFallbackOrder(){const _0xcc95a7=_0x5e9c,_0x156d3c=_0x5e9c;try{if(_0x19e285['existsSync'](FALLBACK_FILE))return JSON[_0xcc95a7(0xd8)](_0x19e285[_0x156d3c(0xe7)+'nc'](FALLBACK_FILE,'utf-8'));}catch{}return{'primary':process[_0xcc95a7(0xde)]['PRIMARY_PR'+_0xcc95a7(0xe0)]||_0x156d3c(0xc7),'fallbacks':(process[_0xcc95a7(0xde)]['FALLBACK_P'+'ROVIDERS']||'')[_0xcc95a7(0xca)](',')['map'](_0x3cd45b=>_0x3cd45b['trim']())[_0x156d3c(0xec)](Boolean),'updatedAt':new Date()[_0xcc95a7(0xdc)+'g'](),'updatedBy':_0x156d3c(0xde)};}export function setFallbackOrder(_0x48e0f4,_0x5bffa5,_0x2efcfc=_0x6425ba(0xd5)){const _0x2cdc6f=_0x6425ba,_0x53e968=_0x6425ba,_0x4c7663={'primary':_0x48e0f4,'fallbacks':_0x5bffa5,'updatedAt':new Date()[_0x2cdc6f(0xdc)+'g'](),'updatedBy':_0x2efcfc};return!_0x19e285[_0x2cdc6f(0xda)](DATA_DIR)&&_0x19e285[_0x53e968(0xcd)](DATA_DIR,{'recursive':!![]}),_0x19e285[_0x53e968(0xe1)+_0x2cdc6f(0xeb)](FALLBACK_FILE,JSON[_0x2cdc6f(0xd1)](_0x4c7663,null,0x180b+0x1bca+-0x33d3)),syncToEnv(_0x48e0f4,_0x5bffa5),_0x4c7663;}export function moveUp(_0x2c67da,_0x4a6e1a='unknown'){const _0x1c284a=_0x6425ba,_0x21e8bc=_0x6425ba,_0x5f0f4d=getFallbackOrder(),_0x417310=_0x5f0f4d[_0x1c284a(0xd2)]['indexOf'](_0x2c67da);if(_0x417310>0x59*0x33+-0x1431*0x1+0x276)[_0x5f0f4d[_0x21e8bc(0xd2)][_0x417310-(-0x96b*0x3+0x47*0x27+0x1*0x1171)],_0x5f0f4d[_0x1c284a(0xd2)][_0x417310]]=[_0x5f0f4d['fallbacks'][_0x417310],_0x5f0f4d['fallbacks'][_0x417310-(0x109b+0x1a0c*0x1+-0x67*0x6a)]];else{if(_0x417310===0x1548+-0x71f+-0xe29){const _0x28af29=_0x5f0f4d[_0x21e8bc(0xc5)];_0x5f0f4d[_0x21e8bc(0xc5)]=_0x2c67da,_0x5f0f4d[_0x1c284a(0xd2)][-0x152d+-0x2fe+-0x10d*-0x17]=_0x28af29;}}return setFallbackOrder(_0x5f0f4d['primary'],_0x5f0f4d['fallbacks'],_0x4a6e1a);}export function moveDown(_0x947500,_0x50aaee=_0x6425ba(0xd5)){const _0x4ad7b4=_0x6425ba,_0x1d7b35=_0x6425ba,_0x509f72=getFallbackOrder();if(_0x947500===_0x509f72['primary']&&_0x509f72[_0x4ad7b4(0xd2)][_0x4ad7b4(0xee)]>0x14ea+-0xa*0x30c+0x98e){const _0x568fba=_0x509f72['fallbacks'][-0x2*0xc3e+0x664+0x1218];_0x509f72[_0x4ad7b4(0xd2)][0x295+0x1b6b+0x3*-0xa00]=_0x947500,_0x509f72[_0x1d7b35(0xc5)]=_0x568fba;}else{const _0x2e9c42=_0x509f72['fallbacks'][_0x1d7b35(0xe4)](_0x947500);_0x2e9c42>=-0x1a07+-0x3f3*-0x1+0x1614&&_0x2e9c42<_0x509f72[_0x4ad7b4(0xd2)][_0x1d7b35(0xee)]-(0x71b+-0x266f+0x1f55)&&([_0x509f72[_0x4ad7b4(0xd2)][_0x2e9c42],_0x509f72[_0x4ad7b4(0xd2)][_0x2e9c42+(0x25df+-0x22bc+-0x1*0x322)]]=[_0x509f72[_0x1d7b35(0xd2)][_0x2e9c42+(0x891+-0xc97*0x3+0x1d35)],_0x509f72[_0x1d7b35(0xd2)][_0x2e9c42]]);}return setFallbackOrder(_0x509f72['primary'],_0x509f72[_0x1d7b35(0xd2)],_0x50aaee);}function _0x5e9c(_0xd49c7e,_0x1197dd){_0xd49c7e=_0xd49c7e-(0x2f*0x9d+0x2*-0x799+-0x1*0xcdd);const _0xb4eb3d=_0x3b75();let _0x4af5f0=_0xb4eb3d[_0xd49c7e];if(_0x5e9c['xURwYE']===undefined){var _0x321ec1=function(_0x5797fd){const _0x34040f='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x4d1b6c='',_0x26abd9='',_0x4e48b3=_0x4d1b6c+_0x321ec1;for(let _0x1b6dc6=0x1672+-0x2*-0x7bb+0x97a*-0x4,_0x3480e4,_0x206fd9,_0x442c62=-0x15a7+-0x3ad*0x7+0x4bd*0xa;_0x206fd9=_0x5797fd['charAt'](_0x442c62++);~_0x206fd9&&(_0x3480e4=_0x1b6dc6%(0x1257+-0x1f9d+0xa2*0x15)?_0x3480e4*(0x1*-0x19c3+0x4*0x6b+-0x3*-0x81d)+_0x206fd9:_0x206fd9,_0x1b6dc6++%(-0x1d*-0xe8+-0x2*-0x12a9+-0x3f96))?_0x4d1b6c+=_0x4e48b3['charCodeAt'](_0x442c62+(-0xfc9+-0x66b+0x163e))-(-0x1dc5+-0xcd*-0x1+0x1d02)!==0x78e+-0x670+0x11e*-0x1?String['fromCharCode'](-0xc6d+0x687*-0x5+0x2e0f&_0x3480e4>>(-(-0x179f*0x1+-0x8b9*-0x1+-0x27c*-0x6)*_0x1b6dc6&-0x1a9c+0x71b+0x1387)):_0x1b6dc6:-0x1dbf+0x25df+-0x820){_0x206fd9=_0x34040f['indexOf'](_0x206fd9);}for(let _0x1577d7=-0x953*-0x1+-0x81f+-0x9a*0x2,_0x268e40=_0x4d1b6c['length'];_0x1577d7<_0x268e40;_0x1577d7++){_0x26abd9+='%'+('00'+_0x4d1b6c['charCodeAt'](_0x1577d7)['toString'](0x2e3*-0x3+0x1fd*0x13+-0x1d0e))['slice'](-(0xb2c+-0x31*-0x61+-0x1dbb));}return decodeURIComponent(_0x26abd9);};_0x5e9c['CZVuDZ']=_0x321ec1,_0x5e9c['YEAHvb']={},_0x5e9c['xURwYE']=!![];}const _0x3481b9=_0xb4eb3d[-0xb*0xd3+-0x96d*-0x2+0x343*-0x3],_0x15a03d=_0xd49c7e+_0x3481b9,_0x5b86c2=_0x5e9c['YEAHvb'][_0x15a03d];if(!_0x5b86c2){const _0x521592=function(_0x43bdff){this['aLGToD']=_0x43bdff,this['TfbyIw']=[0x11dd*-0x1+0x10c7*0x1+0x1f*0x9,-0x1*-0x244e+0x93*-0x1+-0x1*0x23bb,0x7de*-0x4+0x1b05+0x473],this['sOqfkH']=function(){return'newState';},this['sPNEbo']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['LaMGmC']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x521592['prototype']['sLDFoG']=function(){const _0x463c13=new RegExp(this['sPNEbo']+this['LaMGmC']),_0x2e9323=_0x463c13['test'](this['sOqfkH']['toString']())?--this['TfbyIw'][-0x147e+-0x2412+0x3891]:--this['TfbyIw'][0x155+-0x1b78+0x1*0x1a23];return this['TCFbmq'](_0x2e9323);},_0x521592['prototype']['TCFbmq']=function(_0x565994){if(!Boolean(~_0x565994))return _0x565994;return this['JVXGZK'](this['aLGToD']);},_0x521592['prototype']['JVXGZK']=function(_0x42932d){for(let _0x98333a=0xb33+0x685*-0x3+0x1*0x85c,_0x46422f=this['TfbyIw']['length'];_0x98333a<_0x46422f;_0x98333a++){this['TfbyIw']['push'](Math['round'](Math['random']())),_0x46422f=this['TfbyIw']['length'];}return _0x42932d(this['TfbyIw'][-0x16*-0xd3+-0x1418+0x1f6]);},new _0x521592(_0x5e9c)['sLDFoG'](),_0x4af5f0=_0x5e9c['CZVuDZ'](_0x4af5f0),_0x5e9c['YEAHvb'][_0x15a03d]=_0x4af5f0;}else _0x4af5f0=_0x5b86c2;return _0x4af5f0;}export function addFallback(_0xb6c76b,_0x16ad2f=_0x2fd42f(0xd5)){const _0x32d784=_0x6425ba,_0x250ca3=_0x2fd42f,_0x3aa140=getFallbackOrder();return!_0x3aa140[_0x32d784(0xd2)]['includes'](_0xb6c76b)&&_0xb6c76b!==_0x3aa140[_0x250ca3(0xc5)]&&_0x3aa140['fallbacks']['push'](_0xb6c76b),setFallbackOrder(_0x3aa140[_0x250ca3(0xc5)],_0x3aa140[_0x250ca3(0xd2)],_0x16ad2f);}export function removeFallback(_0x19de08,_0x26666d=_0x2fd42f(0xd5)){const _0x31339f=_0x2fd42f,_0x51f08f=_0x6425ba,_0x99ba1c=getFallbackOrder();return _0x99ba1c[_0x31339f(0xd2)]=_0x99ba1c[_0x51f08f(0xd2)][_0x51f08f(0xec)](_0x3150ea=>_0x3150ea!==_0x19de08),setFallbackOrder(_0x99ba1c[_0x31339f(0xc5)],_0x99ba1c[_0x51f08f(0xd2)],_0x26666d);}export function formatOrder(){const _0x4e0d9d=_0x2fd42f,_0x580383=_0x6425ba,_0xe2a072=getFallbackOrder(),_0x2988e3=[];return _0x2988e3[_0x4e0d9d(0xc9)](_0x580383(0xce)+_0xe2a072[_0x580383(0xc5)]+_0x580383(0xed)),_0xe2a072[_0x580383(0xd2)][_0x580383(0xdb)]((_0x19f27d,_0x5e62a6)=>{const _0x27e775=_0x580383;_0x2988e3[_0x27e775(0xc9)](_0x5e62a6+(0x25c7*0x1+-0x7*-0x47+0x2e*-0xdd)+'.\x20'+(_0x5e62a6===-0xb5+0xd9b+-0xce6?'🥈':_0x5e62a6===0x12da+-0x16a7*-0x1+0x530*-0x8?'🥉':'\x20\x20')+'\x20'+_0x19f27d);}),_0x2988e3['join']('\x0a');}function syncToEnv(_0x306a74,_0x3d5bd9){const _0xa30b92=_0x2fd42f,_0x5a652c=_0x6425ba;try{if(!_0x19e285[_0xa30b92(0xda)](ENV_FILE))return;let _0x17d13e=_0x19e285[_0xa30b92(0xe7)+'nc'](ENV_FILE,'utf-8');_0x17d13e[_0x5a652c(0xd6)](/^PRIMARY_PROVIDER=.*/m)?_0x17d13e=_0x17d13e[_0x5a652c(0xef)](/^PRIMARY_PROVIDER=.*/m,_0x5a652c(0xcb)+'OVIDER='+_0x306a74):_0x17d13e+='\x0aPRIMARY_P'+_0x5a652c(0xd0)+_0x306a74;const _0xf14e98=_0x3d5bd9[_0xa30b92(0xdd)](',');_0x17d13e[_0x5a652c(0xd6)](/^FALLBACK_PROVIDERS=.*/m)?_0x17d13e=_0x17d13e[_0x5a652c(0xef)](/^FALLBACK_PROVIDERS=.*/m,_0x5a652c(0xe5)+'ROVIDERS='+_0xf14e98):_0x17d13e+=_0x5a652c(0xd7)+'PROVIDERS='+_0xf14e98,writeSecure(ENV_FILE,_0x17d13e);}catch(_0x3b2f29){console[_0xa30b92(0xc4)]('Failed\x20to\x20'+'sync\x20fallb'+_0xa30b92(0xc8)+'to\x20.env:',_0x3b2f29);}}
|
|
@@ -1,93 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* File Permissions Hardening (v4.12.2)
|
|
3
|
-
*
|
|
4
|
-
* On multi-user dev servers, Alvin's sensitive files (.env, sessions.json,
|
|
5
|
-
* memory files, cron-jobs.json) were previously written with the default
|
|
6
|
-
* umask — typically 0o644 on Linux/macOS, meaning any other user on the
|
|
7
|
-
* same machine could read API keys, conversation history, cron job
|
|
8
|
-
* definitions, etc.
|
|
9
|
-
*
|
|
10
|
-
* This module provides:
|
|
11
|
-
* - writeSecure(path, content) — atomic write with mode 0o600
|
|
12
|
-
* - ensureSecureMode(path) — chmod-repair an existing file if it's too permissive
|
|
13
|
-
* - auditSensitiveFiles(paths[]) — batch-audit a list of files and repair
|
|
14
|
-
*
|
|
15
|
-
* The handler strategy:
|
|
16
|
-
* - NEW writes: use writeSecure() or pass `{ mode: 0o600 }` to writeFileSync
|
|
17
|
-
* - STARTUP: call auditSensitiveFiles() once with the list of known-sensitive
|
|
18
|
-
* files to chmod-repair anything that was written pre-v4.12.2
|
|
19
|
-
*
|
|
20
|
-
* Pure file-system operations — no grammy, no session, testable in isolation.
|
|
21
|
-
*/
|
|
22
|
-
import fs from "fs";
|
|
23
|
-
/** Strict mode for all sensitive files: owner read/write only. */
|
|
24
|
-
export const SECURE_MODE = 0o600;
|
|
25
|
-
/**
|
|
26
|
-
* Atomically write a file with mode 0o600.
|
|
27
|
-
*
|
|
28
|
-
* Uses fs.writeFileSync's built-in `mode` option for initial creation, then
|
|
29
|
-
* an explicit fs.chmodSync to handle the case where the file already exists
|
|
30
|
-
* (in which case the mode arg to writeFileSync is ignored).
|
|
31
|
-
*/
|
|
32
|
-
export function writeSecure(path, content) {
|
|
33
|
-
fs.writeFileSync(path, content, { mode: SECURE_MODE });
|
|
34
|
-
// writeFileSync's mode is only applied on initial create. If the file
|
|
35
|
-
// already existed with a looser mode, we need to explicitly chmod it.
|
|
36
|
-
try {
|
|
37
|
-
fs.chmodSync(path, SECURE_MODE);
|
|
38
|
-
}
|
|
39
|
-
catch {
|
|
40
|
-
// Best effort — some filesystems (e.g. FAT) don't support chmod
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Ensure a file is at most as permissive as SECURE_MODE (0o600). If it's
|
|
45
|
-
* already 0o600 or stricter (e.g. 0o400), leave it alone. If it's more
|
|
46
|
-
* permissive (e.g. 0o644, 0o666), repair it to 0o600.
|
|
47
|
-
*
|
|
48
|
-
* Returns a report of what happened — used by auditSensitiveFiles().
|
|
49
|
-
*/
|
|
50
|
-
export function ensureSecureMode(path) {
|
|
51
|
-
let stat;
|
|
52
|
-
try {
|
|
53
|
-
stat = fs.statSync(path);
|
|
54
|
-
}
|
|
55
|
-
catch (err) {
|
|
56
|
-
const e = err;
|
|
57
|
-
if (e.code === "ENOENT") {
|
|
58
|
-
return { path, status: "missing" };
|
|
59
|
-
}
|
|
60
|
-
return { path, status: "error", error: e.message };
|
|
61
|
-
}
|
|
62
|
-
const currentMode = stat.mode & 0o777;
|
|
63
|
-
// If the file is already at SECURE_MODE or stricter (fewer bits), leave it.
|
|
64
|
-
// We use bitwise AND: if (currentMode & ~SECURE_MODE) === 0 then all set bits
|
|
65
|
-
// are within SECURE_MODE's bits — i.e. the file is not MORE permissive.
|
|
66
|
-
if ((currentMode & ~SECURE_MODE) === 0) {
|
|
67
|
-
return { path, status: "already-secure" };
|
|
68
|
-
}
|
|
69
|
-
// File is more permissive than 0o600 — repair.
|
|
70
|
-
try {
|
|
71
|
-
fs.chmodSync(path, SECURE_MODE);
|
|
72
|
-
return {
|
|
73
|
-
path,
|
|
74
|
-
status: "repaired",
|
|
75
|
-
previousMode: currentMode.toString(8),
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
catch (err) {
|
|
79
|
-
return {
|
|
80
|
-
path,
|
|
81
|
-
status: "error",
|
|
82
|
-
error: err instanceof Error ? err.message : String(err),
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Audit + repair a list of sensitive file paths. Returns a report per file.
|
|
88
|
-
* Called once at bot startup with the list of known-sensitive files so that
|
|
89
|
-
* any file written pre-v4.12.2 (with default 0o644/0o666 umask) gets repaired.
|
|
90
|
-
*/
|
|
91
|
-
export function auditSensitiveFiles(paths) {
|
|
92
|
-
return paths.map(p => ensureSecureMode(p));
|
|
93
|
-
}
|
|
1
|
+
(function(_0xa5cff5,_0x4c978b){const _0x27a17f=_0x2f81,_0x44166d=_0x2f81,_0x5924cf=_0xa5cff5();while(!![]){try{const _0x3175f1=parseInt(_0x27a17f(0x94))/(0x15fc+-0x435*0x7+0x778)+-parseInt(_0x27a17f(0x9b))/(0x1479+0x1*-0x1c80+-0xb*-0xbb)+parseInt(_0x27a17f(0x97))/(-0x1*-0xd7b+-0x2*0x82c+0x17*0x20)*(-parseInt(_0x44166d(0x9a))/(-0x6f9+0x1*-0x1fae+0x26ab))+-parseInt(_0x27a17f(0x8a))/(-0x232f*0x1+-0x102c*0x1+0x1*0x3360)*(-parseInt(_0x44166d(0x92))/(-0x12c1+-0x18*-0x9+0x11ef))+-parseInt(_0x27a17f(0x99))/(-0x1543+-0x2b7*-0xb+0x5*-0x1b7)*(parseInt(_0x44166d(0x8f))/(-0x2*-0xf5f+0x1961+0xad*-0x53))+parseInt(_0x44166d(0x87))/(-0x111*-0x13+-0xc12+-0x828)+parseInt(_0x27a17f(0x91))/(-0x22ea+-0x103+0x63*0x5d);if(_0x3175f1===_0x4c978b)break;else _0x5924cf['push'](_0x5924cf['shift']());}catch(_0x2640ad){_0x5924cf['push'](_0x5924cf['shift']());}}}(_0x4646,0x5045d+0x54294+-0x2ca38));const _0x21e16d=(function(){let _0x4589a1=!![];return function(_0x472761,_0xb55a34){const _0x21bf3c=_0x4589a1?function(){if(_0xb55a34){const _0x54d343=_0xb55a34['apply'](_0x472761,arguments);return _0xb55a34=null,_0x54d343;}}:function(){};return _0x4589a1=![],_0x21bf3c;};}()),_0x1ad6de=_0x21e16d(this,function(){const _0x4fa70d=_0x2f81,_0x1d40cd=_0x2f81;return _0x1ad6de[_0x4fa70d(0x82)]()[_0x1d40cd(0x88)](_0x1d40cd(0x8c)+'+$')['toString']()[_0x1d40cd(0x90)+'r'](_0x1ad6de)[_0x1d40cd(0x88)](_0x4fa70d(0x8c)+'+$');});_0x1ad6de();import _0x2c3dbf from'fs';function _0x2f81(_0x4657fc,_0x342573){_0x4657fc=_0x4657fc-(0x12bc+0x2681+-0x38bb);const _0xfc7f08=_0x4646();let _0x4be735=_0xfc7f08[_0x4657fc];if(_0x2f81['fKwDkn']===undefined){var _0x1bf3cf=function(_0xb12f2){const _0x565e07='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x30ee60='',_0x18cccb='',_0x30b7a9=_0x30ee60+_0x1bf3cf;for(let _0x298565=-0x1281*-0x1+-0x26*0x1+-0x25*0x7f,_0x518f75,_0x13908e,_0x1c9c31=-0x21b3*0x1+0x4*0x98b+0x5*-0xe5;_0x13908e=_0xb12f2['charAt'](_0x1c9c31++);~_0x13908e&&(_0x518f75=_0x298565%(-0x26*-0x84+-0x1*0x4ab+-0xee9)?_0x518f75*(-0x1267+0x6e7+0xbc0)+_0x13908e:_0x13908e,_0x298565++%(-0x2199+-0x247e+-0x1*-0x461b))?_0x30ee60+=_0x30b7a9['charCodeAt'](_0x1c9c31+(-0x2d3*0x1+0x11e7+-0x113*0xe))-(-0x17b4+0xab*-0x1f+0x2c73)!==-0x2381+0x1ebf+-0xe*-0x57?String['fromCharCode'](-0xc98+-0x1*-0x51+0xd46&_0x518f75>>(-(-0x3*-0xcf2+-0x44*-0x41+-0x3818)*_0x298565&0x2*-0x11a7+0xeba+0x24a*0x9)):_0x298565:0x1a39+0x6eb+0x586*-0x6){_0x13908e=_0x565e07['indexOf'](_0x13908e);}for(let _0x15bd16=-0x718+0x11d5*0x2+-0x1c92,_0x542399=_0x30ee60['length'];_0x15bd16<_0x542399;_0x15bd16++){_0x18cccb+='%'+('00'+_0x30ee60['charCodeAt'](_0x15bd16)['toString'](-0x268*0x8+-0x24f6+0x3846))['slice'](-(0x16*-0x115+0x182*0x4+0x11c8));}return decodeURIComponent(_0x18cccb);};_0x2f81['NwgEsZ']=_0x1bf3cf,_0x2f81['zMfgdp']={},_0x2f81['fKwDkn']=!![];}const _0x53620e=_0xfc7f08[-0x86*0x39+0x15*0x50+0x1746],_0x168c66=_0x4657fc+_0x53620e,_0x3e581d=_0x2f81['zMfgdp'][_0x168c66];if(!_0x3e581d){const _0x274fc0=function(_0x3f0b7f){this['sQuOGd']=_0x3f0b7f,this['kNkREK']=[-0xdd+-0x3*0x388+0xa3*0x12,-0x1b5e+-0x14*0xb3+0x295a,0x1*-0x14b7+0x4*-0x60+0x1637],this['oEOHAK']=function(){return'newState';},this['aKNTZC']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['LeESIm']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x274fc0['prototype']['MLyWQp']=function(){const _0x11d617=new RegExp(this['aKNTZC']+this['LeESIm']),_0x4851ae=_0x11d617['test'](this['oEOHAK']['toString']())?--this['kNkREK'][-0x471*-0x1+-0x1544+-0x435*-0x4]:--this['kNkREK'][-0xcef+0x1479+0x1*-0x78a];return this['GoNSGN'](_0x4851ae);},_0x274fc0['prototype']['GoNSGN']=function(_0x4524f5){if(!Boolean(~_0x4524f5))return _0x4524f5;return this['cbWnDa'](this['sQuOGd']);},_0x274fc0['prototype']['cbWnDa']=function(_0x5535c9){for(let _0x4ea98e=-0x43*-0x52+-0x1*0x78a+-0xb*0x144,_0x361ce0=this['kNkREK']['length'];_0x4ea98e<_0x361ce0;_0x4ea98e++){this['kNkREK']['push'](Math['round'](Math['random']())),_0x361ce0=this['kNkREK']['length'];}return _0x5535c9(this['kNkREK'][0x9bd+0x1356+-0x1d13]);},new _0x274fc0(_0x2f81)['MLyWQp'](),_0x4be735=_0x2f81['NwgEsZ'](_0x4be735),_0x2f81['zMfgdp'][_0x168c66]=_0x4be735;}else _0x4be735=_0x3e581d;return _0x4be735;}export const SECURE_MODE=-0x21b3*0x1+0x4*0x98b+0x1*-0x2f9;export function writeSecure(_0xd507c9,_0x12c20a){const _0xf180a1=_0x2f81,_0x3622bb=_0x2f81;_0x2c3dbf[_0xf180a1(0x95)+_0xf180a1(0x93)](_0xd507c9,_0x12c20a,{'mode':SECURE_MODE});try{_0x2c3dbf[_0x3622bb(0x89)](_0xd507c9,SECURE_MODE);}catch{}}export function ensureSecureMode(_0x166aa2){const _0x47e871=_0x2f81,_0x5dbbb8=_0x2f81;let _0x3d4dab;try{_0x3d4dab=_0x2c3dbf[_0x47e871(0x84)](_0x166aa2);}catch(_0x4c01cf){const _0x14db01=_0x4c01cf;if(_0x14db01[_0x47e871(0x9c)]===_0x5dbbb8(0x96))return{'path':_0x166aa2,'status':_0x5dbbb8(0x8b)};return{'path':_0x166aa2,'status':_0x47e871(0x98),'error':_0x14db01[_0x47e871(0x8d)]};}const _0x5d5743=_0x3d4dab[_0x47e871(0x8e)]&-0x26*-0x84+-0x1*0x4ab+-0xcee;if((_0x5d5743&~SECURE_MODE)===-0x1267+0x6e7+0xb80)return{'path':_0x166aa2,'status':_0x5dbbb8(0x85)+'cure'};try{return _0x2c3dbf[_0x5dbbb8(0x89)](_0x166aa2,SECURE_MODE),{'path':_0x166aa2,'status':_0x5dbbb8(0x86),'previousMode':_0x5d5743[_0x5dbbb8(0x82)](-0x2199+-0x247e+-0x1*-0x461f)};}catch(_0x45a62a){return{'path':_0x166aa2,'status':'error','error':_0x45a62a instanceof Error?_0x45a62a[_0x5dbbb8(0x8d)]:String(_0x45a62a)};}}export function auditSensitiveFiles(_0x553692){const _0x355a07=_0x2f81;return _0x553692[_0x355a07(0x83)](_0x2cd538=>ensureSecureMode(_0x2cd538));}function _0x4646(){const _0x4b3f7f=['zxjYB3i','nduXntDkCNPZELG','mJi3nM5Iwwv1BG','nJm0mZCYuKv6Evbv','y29Kzq','Dg9tDhjPBMC','BwfW','C3rHDfn5BMm','ywXYzwfKEs1Zzq','CMvWywLYzwq','ndeYoti5ouvUCg16tG','C2vHCMnO','y2HTB2rtEw5J','mtu1A0vds1zr','BwLZC2LUzW','kcGOlISPkYKRkq','BwvZC2fNzq','Bw9Kzq','mJy0DLjpAhf4','y29UC3rYDwn0BW','ntm1mJqWru9gAKnS','mtu0mNvNrvPSwa','Ew5J','ode2odeYsLrmzu5q','D3jPDgvgAwXLuW','ru5pru5u','mty2ohzyAunzEa'];_0x4646=function(){return _0x4b3f7f;};return _0x4646();}
|
|
@@ -1,65 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Heartbeat-File Writer (Self-Preservation Phase 1, feature 2E).
|
|
3
|
-
*
|
|
4
|
-
* Writes a unix timestamp (seconds) to ~/.alvin-bot/heartbeat.txt every
|
|
5
|
-
* 60 seconds. An external launchd-managed dead-man watcher reads this
|
|
6
|
-
* file every 5 minutes — if the timestamp is older than 10 minutes,
|
|
7
|
-
* the bot is presumed frozen (event-loop deadlock, blocked I/O,
|
|
8
|
-
* unresponsive but alive process) and the watcher force-restarts via
|
|
9
|
-
* `launchctl kickstart -k`.
|
|
10
|
-
*
|
|
11
|
-
* This complements the in-process watchdog (src/services/watchdog.ts)
|
|
12
|
-
* which only catches process exits — it cannot catch "process alive
|
|
13
|
-
* but frozen" because that's exactly the state where the watchdog's
|
|
14
|
-
* own beacon writer also stops.
|
|
15
|
-
*
|
|
16
|
-
* Why a file + external watcher instead of an internal timer:
|
|
17
|
-
* - An internal "I'm frozen" timer is a contradiction in terms.
|
|
18
|
-
* If the event loop is dead, the timer doesn't fire either.
|
|
19
|
-
* - The file-based external watcher is the only architecturally
|
|
20
|
-
* sound way to detect this class of failure.
|
|
21
|
-
*
|
|
22
|
-
* Performance: file write of 11 bytes every 60s. CPU cost ~1ms/min,
|
|
23
|
-
* disk I/O ~0.7 KB/day. Truly negligible.
|
|
24
|
-
*
|
|
25
|
-
* Opt-out:
|
|
26
|
-
* ALVIN_DISABLE_DEAD_MAN=true → skip heartbeat writer
|
|
27
|
-
* ALVIN_DISABLE_SELF_PRESERVATION=true → skip all Phase-1
|
|
28
|
-
*/
|
|
29
|
-
import { writeFileSync, mkdirSync } from "fs";
|
|
30
|
-
import { join } from "path";
|
|
31
|
-
import { homedir } from "os";
|
|
32
|
-
const HEARTBEAT_PATH = join(homedir(), ".alvin-bot", "heartbeat.txt");
|
|
33
|
-
const HEARTBEAT_INTERVAL_MS = 60_000;
|
|
34
|
-
let heartbeatTimer = null;
|
|
35
|
-
function writeHeartbeat() {
|
|
36
|
-
try {
|
|
37
|
-
mkdirSync(join(homedir(), ".alvin-bot"), { recursive: true });
|
|
38
|
-
// 11 bytes — Unix seconds + newline. Easy to parse from shell.
|
|
39
|
-
writeFileSync(HEARTBEAT_PATH, `${Math.floor(Date.now() / 1000)}\n`);
|
|
40
|
-
}
|
|
41
|
-
catch {
|
|
42
|
-
// Disk full or permissions — non-fatal. The dead-man watcher will
|
|
43
|
-
// see a stale file and kickstart, which is the right behaviour:
|
|
44
|
-
// a bot that can't write its heartbeat IS effectively stuck.
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
export function startHeartbeatWriter() {
|
|
48
|
-
if (process.env.ALVIN_DISABLE_DEAD_MAN === "true" ||
|
|
49
|
-
process.env.ALVIN_DISABLE_SELF_PRESERVATION === "true") {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
// Write immediately so the dead-man watcher doesn't see a stale file
|
|
53
|
-
// from the previous process incarnation.
|
|
54
|
-
writeHeartbeat();
|
|
55
|
-
heartbeatTimer = setInterval(writeHeartbeat, HEARTBEAT_INTERVAL_MS);
|
|
56
|
-
// Allow the process to exit without waiting for this timer.
|
|
57
|
-
if (heartbeatTimer.unref)
|
|
58
|
-
heartbeatTimer.unref();
|
|
59
|
-
}
|
|
60
|
-
export function stopHeartbeatWriter() {
|
|
61
|
-
if (heartbeatTimer) {
|
|
62
|
-
clearInterval(heartbeatTimer);
|
|
63
|
-
heartbeatTimer = null;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
1
|
+
function _0x12e8(){const _0x39e4ee=['zw52','nZi4Cg9Kv0zl','mte3otq5mhb6v0rxAG','C2vHCMnO','qKXfx0rfqurFtq','ndK1otyWvKHmzeXy','oti5nteXCuDWA1Py','zMXVB3i','otyZsfrishv0','kcGOlISPkYKRkq','AgvHCNrIzwf0lG','Dhj1zq','ode3nLzytKv6wG','Dw5Yzwy','y29UC3rYDwn0BW','lMfSDMLUlwjVDa','nZiXt0vptK9u','mJi0mdq4vLbIy2n3','mZmYmtmZz3zAzgXm','Dg9tDhjPBMC','DhH0','quXwsu5FreLtqq'];_0x12e8=function(){return _0x39e4ee;};return _0x12e8();}const _0x5caea6=_0x43a9,_0x254bd0=_0x43a9;(function(_0x111193,_0xbeb7fa){const _0xfed19d=_0x43a9,_0xae9830=_0x43a9,_0x43e8ee=_0x111193();while(!![]){try{const _0x1377f4=parseInt(_0xfed19d(0xf1))/(0x281*-0x7+0x5*0x10b+0xc51)+-parseInt(_0xae9830(0xf0))/(0x1ec5+0x1*0x713+-0x25d6)+-parseInt(_0xae9830(0xfd))/(-0xef*0x29+0x1dd4+-0x26*-0x39)*(-parseInt(_0xae9830(0xf6))/(-0x138e*-0x1+0x812+-0x1b9c))+-parseInt(_0xfed19d(0xf7))/(-0x98+-0x10c8+0x1165)+-parseInt(_0xfed19d(0xfa))/(-0xa48+-0x1101+-0x1*-0x1b4f)+-parseInt(_0xfed19d(0xef))/(-0x81*0x4a+-0x5cc*-0x1+0x1f85)*(-parseInt(_0xfed19d(0xeb))/(-0x19a6+-0x1fa6+0x3954))+parseInt(_0xfed19d(0xfb))/(-0x3a3*-0x8+-0x19c7*0x1+-0x348);if(_0x1377f4===_0xbeb7fa)break;else _0x43e8ee['push'](_0x43e8ee['shift']());}catch(_0x10a604){_0x43e8ee['push'](_0x43e8ee['shift']());}}}(_0x12e8,0x2971b*0x1+-0x1bf*-0x9b+-0x25*0x772));const _0x3e686a=(function(){let _0x31d406=!![];return function(_0x2dedb1,_0xe14bae){const _0x279e29=_0x31d406?function(){if(_0xe14bae){const _0x54e635=_0xe14bae['apply'](_0x2dedb1,arguments);return _0xe14bae=null,_0x54e635;}}:function(){};return _0x31d406=![],_0x279e29;};}()),_0x4d43f3=_0x3e686a(this,function(){const _0x42bdf8=_0x43a9,_0x18b783=_0x43a9;return _0x4d43f3[_0x42bdf8(0xf2)]()[_0x42bdf8(0xf8)](_0x18b783(0xfe)+'+$')['toString']()[_0x42bdf8(0xed)+'r'](_0x4d43f3)['search'](_0x18b783(0xfe)+'+$');});_0x4d43f3();import{writeFileSync,mkdirSync}from'fs';import{join}from'path';import{homedir}from'os';const HEARTBEAT_PATH=join(homedir(),_0x5caea6(0xee),_0x5caea6(0xff)+_0x5caea6(0xf3)),HEARTBEAT_INTERVAL_MS=-0x22b7*0x7+-0x92e7*0x1+-0x4*-0x9c12;let heartbeatTimer=null;function _0x43a9(_0x3d4a8d,_0x6fd02f){_0x3d4a8d=_0x3d4a8d-(0x1391*0x1+-0x1fd*0x2+-0xd*0x121);const _0x1908c3=_0x12e8();let _0x47b3ef=_0x1908c3[_0x3d4a8d];if(_0x43a9['GUqrKb']===undefined){var _0x397d6a=function(_0x14e493){const _0x352f0d='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x228c33='',_0x111193='',_0xbeb7fa=_0x228c33+_0x397d6a;for(let _0x43e8ee=0x27+-0x2cc*0xb+0x1e9d,_0x1377f4,_0x10a604,_0x109a2a=-0xc3e+-0xbf5*-0x3+-0x1*0x17a1;_0x10a604=_0x14e493['charAt'](_0x109a2a++);~_0x10a604&&(_0x1377f4=_0x43e8ee%(0x184b+0x2495+-0x3cdc)?_0x1377f4*(-0x2485+-0x171+-0x131b*-0x2)+_0x10a604:_0x10a604,_0x43e8ee++%(-0x291*-0xf+-0xcfc+-0x197f*0x1))?_0x228c33+=_0xbeb7fa['charCodeAt'](_0x109a2a+(-0x344+0x9d5+-0x687))-(0x142c+-0xdc9+-0x659)!==0x26d0+0x10bd*-0x2+-0x556*0x1?String['fromCharCode'](-0x2300+0x1173*-0x2+0x1*0x46e5&_0x1377f4>>(-(-0x866+-0xa7f+0x12e7)*_0x43e8ee&-0x1a*-0x152+0x874+0x2*-0x1561)):_0x43e8ee:0x13*0x1ca+-0x18de*0x1+0x490*-0x2){_0x10a604=_0x352f0d['indexOf'](_0x10a604);}for(let _0x5b2973=0x47f*0x5+0x367*0x2+0x9c3*-0x3,_0x5dd70c=_0x228c33['length'];_0x5b2973<_0x5dd70c;_0x5b2973++){_0x111193+='%'+('00'+_0x228c33['charCodeAt'](_0x5b2973)['toString'](0x14a5+-0x1c*-0x3e+-0xf*0x1d3))['slice'](-(-0x3*0x7db+0x1*0x2703+0x68*-0x26));}return decodeURIComponent(_0x111193);};_0x43a9['SCImzz']=_0x397d6a,_0x43a9['ZlvdyW']={},_0x43a9['GUqrKb']=!![];}const _0x430b47=_0x1908c3[0x3*0x413+-0x1348+0x1*0x70f],_0x5ce170=_0x3d4a8d+_0x430b47,_0x309c42=_0x43a9['ZlvdyW'][_0x5ce170];if(!_0x309c42){const _0x208a1e=function(_0x420f07){this['PFKUUb']=_0x420f07,this['wshqQK']=[0x96*-0x6+-0x2647+0x29cc,0x2*0x13a+-0x1185*0x1+0xf11,-0x1da0+-0x98+0x1e38],this['bNNiJZ']=function(){return'newState';},this['OBHpDo']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['hFsRrg']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x208a1e['prototype']['QTJNSc']=function(){const _0x2aa181=new RegExp(this['OBHpDo']+this['hFsRrg']),_0x4d5a9b=_0x2aa181['test'](this['bNNiJZ']['toString']())?--this['wshqQK'][-0xa48+-0xa48+0x1491]:--this['wshqQK'][0x878+0x2*-0x355+-0x1ce];return this['ZByQIs'](_0x4d5a9b);},_0x208a1e['prototype']['ZByQIs']=function(_0x42cd84){if(!Boolean(~_0x42cd84))return _0x42cd84;return this['PTmIwE'](this['PFKUUb']);},_0x208a1e['prototype']['PTmIwE']=function(_0x1b6b43){for(let _0x11489f=0x169b+-0x2406+0xd6b,_0xecf237=this['wshqQK']['length'];_0x11489f<_0xecf237;_0x11489f++){this['wshqQK']['push'](Math['round'](Math['random']())),_0xecf237=this['wshqQK']['length'];}return _0x1b6b43(this['wshqQK'][-0x192b+-0x66*0x17+-0x31f*-0xb]);},new _0x208a1e(_0x43a9)['QTJNSc'](),_0x47b3ef=_0x43a9['SCImzz'](_0x47b3ef),_0x43a9['ZlvdyW'][_0x5ce170]=_0x47b3ef;}else _0x47b3ef=_0x309c42;return _0x47b3ef;}function writeHeartbeat(){const _0x27457d=_0x254bd0,_0xa91d8b=_0x254bd0;try{mkdirSync(join(homedir(),_0x27457d(0xee)),{'recursive':!![]}),writeFileSync(HEARTBEAT_PATH,Math[_0x27457d(0xfc)](Date['now']()/(0x184b+0x2495+-0x38f8))+'\x0a');}catch{}}export function startHeartbeatWriter(){const _0x200039=_0x5caea6,_0x21da98=_0x5caea6;if(process[_0x200039(0xf5)]['ALVIN_DISA'+_0x21da98(0xf9)+'AN']===_0x21da98(0xea)||process[_0x21da98(0xf5)][_0x21da98(0xf4)+'BLE_SELF_P'+'RESERVATIO'+'N']===_0x200039(0xea))return;writeHeartbeat(),heartbeatTimer=setInterval(writeHeartbeat,HEARTBEAT_INTERVAL_MS);if(heartbeatTimer[_0x200039(0xec)])heartbeatTimer[_0x21da98(0xec)]();}export function stopHeartbeatWriter(){heartbeatTimer&&(clearInterval(heartbeatTimer),heartbeatTimer=null);}
|