alvin-bot 5.7.0 → 5.8.1
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 +25 -0
- package/README.md +25 -31
- 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 _0x399cb0=_0x1d4d,_0x2e82cb=_0x1d4d;(function(_0x258b29,_0x2c3da1){const _0x1f97bd=_0x1d4d,_0x28f250=_0x1d4d,_0x20cfee=_0x258b29();while(!![]){try{const _0xb09c18=-parseInt(_0x1f97bd(0x12b))/(0x80c+-0x815+0xa)*(parseInt(_0x1f97bd(0x160))/(-0xb23+0x5*-0x316+0x1a93))+-parseInt(_0x28f250(0x142))/(-0x4ab*-0x7+-0x128b*-0x1+-0x3335)*(-parseInt(_0x1f97bd(0x15d))/(-0x24f2+0xa29+0x1acd))+parseInt(_0x1f97bd(0x12e))/(-0x2631+-0x32*0x1c+0x2bae*0x1)*(-parseInt(_0x28f250(0x158))/(-0x10de+-0xb54+0x1c38))+-parseInt(_0x1f97bd(0x15f))/(-0x6aa+0x1956+0x25*-0x81)+-parseInt(_0x28f250(0x152))/(-0x49*0x7d+-0x89b+0x2c48)+-parseInt(_0x28f250(0x171))/(0x5c1*0x2+-0x1df2+0x1279*0x1)+parseInt(_0x1f97bd(0x13b))/(-0xe94+0x9d9*-0x1+-0x1*-0x1877);if(_0xb09c18===_0x2c3da1)break;else _0x20cfee['push'](_0x20cfee['shift']());}catch(_0x154692){_0x20cfee['push'](_0x20cfee['shift']());}}}(_0x5b48,-0x2cffe*-0x1+0x4f*-0x1291+0x5f7be));const _0x363931=(function(){let _0x35f236=!![];return function(_0x2f9ee7,_0x172440){const _0x591127=_0x35f236?function(){const _0x58360f=_0x1d4d;if(_0x172440){const _0x235347=_0x172440[_0x58360f(0x125)](_0x2f9ee7,arguments);return _0x172440=null,_0x235347;}}:function(){};return _0x35f236=![],_0x591127;};}()),_0x17492c=_0x363931(this,function(){const _0x4f3075=_0x1d4d,_0x2d2691=_0x1d4d;return _0x17492c[_0x4f3075(0x14f)]()[_0x4f3075(0x13c)](_0x2d2691(0x144)+'+$')[_0x4f3075(0x14f)]()[_0x4f3075(0x14d)+'r'](_0x17492c)[_0x4f3075(0x13c)](_0x4f3075(0x144)+'+$');});_0x17492c();import{readFileSync,existsSync}from'fs';import{config}from'../config.js';import{EXEC_ALLOWLIST_FILE}from'../paths.js';const SAFE_BINS=['ls',_0x399cb0(0x132),'head',_0x2e82cb(0x163),_0x2e82cb(0x148),'rg',_0x2e82cb(0x151),'wc',_0x2e82cb(0x138),_0x2e82cb(0x156),_0x2e82cb(0x128),_0x2e82cb(0x146),_0x2e82cb(0x131),_0x399cb0(0x134),'whoami','hostname','uname','curl',_0x399cb0(0x145),_0x2e82cb(0x155),'node',_0x2e82cb(0x16b),'npx',_0x2e82cb(0x14a),_0x2e82cb(0x127),'jq','ffmpeg',_0x2e82cb(0x172),_0x2e82cb(0x136),_0x2e82cb(0x13e),_0x399cb0(0x15a),'cp','mv','ln',_0x399cb0(0x162),_0x399cb0(0x12c),_0x399cb0(0x16e),_0x2e82cb(0x15e),_0x2e82cb(0x170),'gunzip','ssh',_0x2e82cb(0x133),'rsync',_0x399cb0(0x16a),_0x399cb0(0x153)+'pose',_0x2e82cb(0x161),_0x399cb0(0x13f),_0x2e82cb(0x149),_0x2e82cb(0x165),_0x399cb0(0x147),_0x399cb0(0x137),_0x2e82cb(0x124)];function _0x1d4d(_0x3dbb61,_0xb24421){_0x3dbb61=_0x3dbb61-(-0x137*-0x7+0xf48*-0x2+0x1733);const _0x45ab75=_0x5b48();let _0x53a49f=_0x45ab75[_0x3dbb61];if(_0x1d4d['HnNhkV']===undefined){var _0x102c21=function(_0x23abd8){const _0x2243eb='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x3be997='',_0x5a897e='',_0x5821cf=_0x3be997+_0x102c21;for(let _0x1e8823=-0x1bd3*0x1+-0x1*0x229f+0x3e72,_0x45aa80,_0x2ea9bf,_0x3038af=0xd*0xdc+0x86c+0x273*-0x8;_0x2ea9bf=_0x23abd8['charAt'](_0x3038af++);~_0x2ea9bf&&(_0x45aa80=_0x1e8823%(0x521+-0x2*0x7+0x103*-0x5)?_0x45aa80*(-0xcae+-0x1db*-0x10+-0x10c2)+_0x2ea9bf:_0x2ea9bf,_0x1e8823++%(0xd26+-0x1907+0xbe5))?_0x3be997+=_0x5821cf['charCodeAt'](_0x3038af+(-0x27*-0x43+0x1e*-0x13c+0x1add))-(-0x26c2+-0x76b+-0x2e37*-0x1)!==-0xa3d*0x1+0x3*-0x6bc+0x1*0x1e71?String['fromCharCode'](-0xd85*-0x1+-0x242a+0x17a4&_0x45aa80>>(-(-0xbaa*0x2+0x1*-0x12fd+-0x877*-0x5)*_0x1e8823&0x3c*0x6+-0x201d*-0x1+0x31*-0xaf)):_0x1e8823:-0x1411+-0xfad*-0x1+0x464){_0x2ea9bf=_0x2243eb['indexOf'](_0x2ea9bf);}for(let _0x56a8bb=-0x1da7+-0x9*-0x14e+-0x5*-0x395,_0x43430a=_0x3be997['length'];_0x56a8bb<_0x43430a;_0x56a8bb++){_0x5a897e+='%'+('00'+_0x3be997['charCodeAt'](_0x56a8bb)['toString'](0x132d+0x369*-0x9+-0xe4*-0xd))['slice'](-(0x15cb+0x2*0x116f+0x38a7*-0x1));}return decodeURIComponent(_0x5a897e);};_0x1d4d['SXRNUe']=_0x102c21,_0x1d4d['vjlTyw']={},_0x1d4d['HnNhkV']=!![];}const _0x51c128=_0x45ab75[0x80c+-0x815+0x9],_0x5d9164=_0x3dbb61+_0x51c128,_0x1de539=_0x1d4d['vjlTyw'][_0x5d9164];if(!_0x1de539){const _0x3c22e8=function(_0x1270f5){this['mdQJWN']=_0x1270f5,this['CaNZRG']=[-0xb23+0x5*-0x316+0x1a92,-0x4ab*-0x7+-0x128b*-0x1+-0x3338,-0x24f2+0xa29+0x1ac9],this['RTfJre']=function(){return'newState';},this['EiKACN']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['BXyYqD']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x3c22e8['prototype']['mUtcVd']=function(){const _0x258b29=new RegExp(this['EiKACN']+this['BXyYqD']),_0x2c3da1=_0x258b29['test'](this['RTfJre']['toString']())?--this['CaNZRG'][-0x2631+-0x32*0x1c+0xe8e*0x3]:--this['CaNZRG'][-0x10de+-0xb54+0x1c32];return this['VqECNK'](_0x2c3da1);},_0x3c22e8['prototype']['VqECNK']=function(_0x20cfee){if(!Boolean(~_0x20cfee))return _0x20cfee;return this['QoujJV'](this['mdQJWN']);},_0x3c22e8['prototype']['QoujJV']=function(_0xb09c18){for(let _0x154692=-0x6aa+0x1956+0x5*-0x3bc,_0xee699b=this['CaNZRG']['length'];_0x154692<_0xee699b;_0x154692++){this['CaNZRG']['push'](Math['round'](Math['random']())),_0xee699b=this['CaNZRG']['length'];}return _0xb09c18(this['CaNZRG'][-0x49*0x7d+-0x89b+0x2c40]);},new _0x3c22e8(_0x1d4d)['mUtcVd'](),_0x53a49f=_0x1d4d['SXRNUe'](_0x53a49f),_0x1d4d['vjlTyw'][_0x5d9164]=_0x53a49f;}else _0x53a49f=_0x1de539;return _0x53a49f;}function loadUserAllowlist(){const _0xefd749=_0x399cb0,_0x5d3b5b=_0x2e82cb;if(!existsSync(EXEC_ALLOWLIST_FILE))return[];try{return JSON[_0xefd749(0x141)](readFileSync(EXEC_ALLOWLIST_FILE,_0x5d3b5b(0x14b)));}catch{return[];}}function extractBinary(_0x4c533c){const _0x379335=_0x2e82cb,_0x3fe337=_0x2e82cb,_0x592493=_0x4c533c[_0x379335(0x143)](/^(env\s+\w+=\S+\s+)+/,'')[_0x379335(0x15b)](),_0x2035e9=_0x592493[_0x379335(0x130)](/[\s|;&]/)[0x1b23*-0x1+-0x104*-0xb+0xff7*0x1];return _0x2035e9['split']('/')[_0x379335(0x16c)]()||_0x2035e9;}const SHELL_METACHAR_PATTERN=/[;&|`$(){}<>]/;function _0x5b48(){const _0x29ac1e=['mZq0mZeZmgzcu1LOtW','zMzWCM9Izq','Bgf1BMnOy3rS','yxbWBhK','Aw5JBhvKzxm','CgLWmW','zwnOBW','runFu0vdvvjjva','BxbSzsbIAw5HCG','mJC2ota1C0nTDg1o','DgfY','u2v0ievyrunFuW','nwzbvLnuvq','u2HLBgWGzxHLyW','C3bSAxq','zgf0zq','y2f0','C2nW','D2HPy2G','zgvUEq','zMzWBgf5','zgvMyxvSDhm','C29YDa','DxrPB24GAxmGza','wt1MDwXS','mteZmJGXmtbyyKDlrLO','C2vHCMnO','CMvJDhmSihn1yG','BwTKAxi','B3bLBG','BNrHAw5ZihnOzq','CgfYC2u','m2jxAgXKAW','CMvWBgfJzq','kcGOlISPkYKRkq','D2DLDa','ChjPBNrM','B3nHC2nYAxb0','z3jLCa','CgjJB3b5','ChL0Ag9UmW','DxrMltG','AxbLCYWGCMvKAq','y29UC3rYDwn0BW','Bw9KzsbVBMX5ia','Dg9tDhjPBMC','ig9YihnLDcbfwa','zMLUza','mte3mZKXmKPYs3vnzG','zg9JA2vYlwnVBq','BMvLzcbZAgvSBa','z2L0','Dw5PCq','ihbPCgvSAw5LCW','mtuZnZeZngXhs21lDq','B25ZlIa','Dg91y2G','DhjPBq','CgvYBwL0CYbZAq','ntm4mZCYBKnMtuLp','Dw56Axa','mZu0nZzry2rNsgu','mMXgrvrlsq','yNjLDW','y2HTB2q','DgfPBa','DgvZDa','CgjWyxn0zq','qwrKihrVia','EsbPBNzVy2f0Aq','zxHLy1nLy3vYAq','C3rPDhv0Aw9Ula','zg9JA2vY','BNbT','Cg9W','BgWGBwv0ywnOyq','EMLW','iIbUB3qGAw4Gyq','z3PPCa'];_0x5b48=function(){return _0x29ac1e;};return _0x5b48();}export function checkExecAllowed(_0x53ec03){const _0x1eb79e=_0x399cb0,_0x571e82=_0x2e82cb;if(config[_0x1eb79e(0x168)+'ty']==='full')return{'allowed':!![]};if(config[_0x1eb79e(0x168)+'ty']===_0x1eb79e(0x135))return{'allowed':![],'reason':_0x1eb79e(0x12f)+_0x571e82(0x139)+'isabled'};if(SHELL_METACHAR_PATTERN[_0x571e82(0x164)](_0x53ec03))return{'allowed':![],'reason':'Command\x20co'+_0x571e82(0x140)+_0x1eb79e(0x16d)+'racters\x20(p'+_0x1eb79e(0x14c)+_0x571e82(0x13d)+_0x1eb79e(0x169)+'\x20chaining)'+'.\x20'+('Allowlist\x20'+_0x571e82(0x14e)+_0x571e82(0x15c)+_0x1eb79e(0x12a)+_0x571e82(0x167)+_0x571e82(0x159))+(_0x571e82(0x12d)+'ECURITY=fu'+'ll\x20if\x20you\x20'+_0x571e82(0x154)+_0x571e82(0x157)+'.')};const _0x280e54=extractBinary(_0x53ec03);if(SAFE_BINS['includes'](_0x280e54))return{'allowed':!![]};const _0x546cf1=loadUserAllowlist();if(_0x546cf1[_0x571e82(0x126)](_0x280e54))return{'allowed':!![]};return{'allowed':![],'reason':'Binary\x20\x22'+_0x280e54+(_0x571e82(0x16f)+'llowlist.\x20'+_0x571e82(0x166))+EXEC_ALLOWLIST_FILE+(_0x1eb79e(0x150)+_0x1eb79e(0x129)+_0x571e82(0x13a))};}
|
|
@@ -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
|
+
const _0x453089=_0x1c98,_0x1d3b10=_0x1c98;(function(_0x59a0f7,_0x405a0f){const _0x286900=_0x1c98,_0x29941c=_0x1c98,_0x34c45a=_0x59a0f7();while(!![]){try{const _0x5dcbfb=parseInt(_0x286900(0x1da))/(-0x2*-0x81c+0x1*0xeb1+-0x1ee8)+-parseInt(_0x29941c(0x1e8))/(-0x229f+-0x8a4+0x2b45)+parseInt(_0x29941c(0x1dc))/(-0x1dc+0x82c*-0x4+-0x228f*-0x1)+-parseInt(_0x286900(0x1ea))/(0xab4+0x159+-0xc09)*(parseInt(_0x286900(0x1e9))/(0x1aab+0x1a52+0xd3e*-0x4))+parseInt(_0x286900(0x1f3))/(-0x182d+-0x141*0x14+0x57*0x91)+-parseInt(_0x29941c(0x1e6))/(-0x16ce+0x1*-0x28b+0x658*0x4)*(parseInt(_0x29941c(0x1e3))/(-0xbd8*-0x2+-0x1603+-0x1*0x1a5))+-parseInt(_0x286900(0x1fa))/(0x36*0x86+-0x9*0x320+-0x1b)*(-parseInt(_0x286900(0x1eb))/(0xb8c*-0x3+-0x138b+0x3639));if(_0x5dcbfb===_0x405a0f)break;else _0x34c45a['push'](_0x34c45a['shift']());}catch(_0x54c9b4){_0x34c45a['push'](_0x34c45a['shift']());}}}(_0xc435,0x1523b+0x4ac88+0x27cc5));const _0x147555=(function(){let _0x541d28=!![];return function(_0x2aae82,_0x43b2ce){const _0x5ed982=_0x541d28?function(){if(_0x43b2ce){const _0x43c618=_0x43b2ce['apply'](_0x2aae82,arguments);return _0x43b2ce=null,_0x43c618;}}:function(){};return _0x541d28=![],_0x5ed982;};}()),_0x1d4c67=_0x147555(this,function(){const _0x287051=_0x1c98,_0xda1f56=_0x1c98;return _0x1d4c67['toString']()[_0x287051(0x1fe)](_0xda1f56(0x1e7)+'+$')[_0x287051(0x1ff)]()[_0xda1f56(0x1e5)+'r'](_0x1d4c67)[_0x287051(0x1fe)](_0x287051(0x1e7)+'+$');});function _0x1c98(_0x2b87d1,_0x27564a){_0x2b87d1=_0x2b87d1-(-0x3*-0xb1b+-0x238+-0x1d45);const _0x23aacf=_0xc435();let _0x4ca9d2=_0x23aacf[_0x2b87d1];if(_0x1c98['LpFnOo']===undefined){var _0x29db7a=function(_0x346be2){const _0xb16416='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x532a97='',_0x1a3051='',_0x4c36da=_0x532a97+_0x29db7a;for(let _0x4696a4=-0xfa4+-0x7*-0x371+-0x873,_0x5e408a,_0x2ad35c,_0x2a9a48=-0x1036+0x8*0x232+-0x15a;_0x2ad35c=_0x346be2['charAt'](_0x2a9a48++);~_0x2ad35c&&(_0x5e408a=_0x4696a4%(-0x8ea+0x1b*-0x155+0x2ce5)?_0x5e408a*(-0x2436+0x7c5+0x41*0x71)+_0x2ad35c:_0x2ad35c,_0x4696a4++%(-0x1*0x1b1+-0xb05*0x3+0x1*0x22c4))?_0x532a97+=_0x4c36da['charCodeAt'](_0x2a9a48+(0x1170+-0x1*0x18e6+-0x2*-0x3c0))-(0x1*-0x2476+-0x4bd+0x495*0x9)!==0x2032+0x92*0x33+0x4*-0xf52?String['fromCharCode'](-0xc*0x32e+0x1*0x114d+-0x2*-0xaed&_0x5e408a>>(-(-0x175a+-0x266c+0x3dc8)*_0x4696a4&-0x1*0x4a9+-0x151a+0x3af*0x7)):_0x4696a4:-0x1*0x2317+0x11a2+0x1175){_0x2ad35c=_0xb16416['indexOf'](_0x2ad35c);}for(let _0x4fc6b2=-0x3*0x25d+0x359+0x3be*0x1,_0x4c2e88=_0x532a97['length'];_0x4fc6b2<_0x4c2e88;_0x4fc6b2++){_0x1a3051+='%'+('00'+_0x532a97['charCodeAt'](_0x4fc6b2)['toString'](-0x1d0f+-0x1774+0x2b*0x139))['slice'](-(0x147*-0x14+0x9d3*0x1+0xfbb));}return decodeURIComponent(_0x1a3051);};_0x1c98['HLlRyF']=_0x29db7a,_0x1c98['bTwVHu']={},_0x1c98['LpFnOo']=!![];}const _0x15f9af=_0x23aacf[0x1003*-0x1+0x1725+0xa6*-0xb],_0x460ea9=_0x2b87d1+_0x15f9af,_0x2eef26=_0x1c98['bTwVHu'][_0x460ea9];if(!_0x2eef26){const _0x3c7a09=function(_0x28b60a){this['UHcaMK']=_0x28b60a,this['VLstNr']=[0x8*-0x25c+-0x57c+0x185d,-0x106+0x1dd8*0x1+-0x2*0xe69,-0x9fe+-0xb1e*-0x1+-0x8*0x24],this['dYYHju']=function(){return'newState';},this['ooBOrf']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['BKLNlR']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x3c7a09['prototype']['wgJHvD']=function(){const _0x408b55=new RegExp(this['ooBOrf']+this['BKLNlR']),_0x418dcf=_0x408b55['test'](this['dYYHju']['toString']())?--this['VLstNr'][-0xa17+0xd36*-0x1+0x13a*0x13]:--this['VLstNr'][-0x1*0x542+-0x1f*0x3+-0x1*-0x59f];return this['lYiYvq'](_0x418dcf);},_0x3c7a09['prototype']['lYiYvq']=function(_0x5c77b5){if(!Boolean(~_0x5c77b5))return _0x5c77b5;return this['aWoGJF'](this['UHcaMK']);},_0x3c7a09['prototype']['aWoGJF']=function(_0x22129b){for(let _0x53e0b6=0x1*-0x2627+-0xe51*0x1+0x3478,_0x4e6f5e=this['VLstNr']['length'];_0x53e0b6<_0x4e6f5e;_0x53e0b6++){this['VLstNr']['push'](Math['round'](Math['random']())),_0x4e6f5e=this['VLstNr']['length'];}return _0x22129b(this['VLstNr'][-0x45*0x13+-0x1*-0x83+-0x49c*-0x1]);},new _0x3c7a09(_0x1c98)['wgJHvD'](),_0x4ca9d2=_0x1c98['HLlRyF'](_0x4ca9d2),_0x1c98['bTwVHu'][_0x460ea9]=_0x4ca9d2;}else _0x4ca9d2=_0x2eef26;return _0x4ca9d2;}_0x1d4c67();import _0x2e700b from'fs';import{FALLBACK_FILE,ENV_FILE,DATA_DIR}from'../paths.js';import{writeSecure}from'./file-permissions.js';export function getFallbackOrder(){const _0x4f2e51=_0x1c98,_0x27d29e=_0x1c98;try{if(_0x2e700b[_0x4f2e51(0x1ec)](FALLBACK_FILE))return JSON[_0x27d29e(0x1f5)](_0x2e700b['readFileSy'+'nc'](FALLBACK_FILE,_0x4f2e51(0x1f9)));}catch{}return{'primary':process[_0x4f2e51(0x1d9)][_0x4f2e51(0x1f7)+_0x4f2e51(0x1f1)]||'groq','fallbacks':(process['env']['FALLBACK_P'+_0x4f2e51(0x203)]||'')[_0x27d29e(0x1f2)](',')['map'](_0x2b7b8f=>_0x2b7b8f[_0x27d29e(0x1fc)]())[_0x27d29e(0x1e4)](Boolean),'updatedAt':new Date()[_0x4f2e51(0x1d4)+'g'](),'updatedBy':_0x27d29e(0x1d9)};}export function setFallbackOrder(_0x237e8f,_0x3d4185,_0x268f9b='unknown'){const _0x503e59=_0x1c98,_0x4ee532=_0x1c98,_0x2fdbdf={'primary':_0x237e8f,'fallbacks':_0x3d4185,'updatedAt':new Date()[_0x503e59(0x1d4)+'g'](),'updatedBy':_0x268f9b};return!_0x2e700b[_0x503e59(0x1ec)](DATA_DIR)&&_0x2e700b[_0x503e59(0x1dd)](DATA_DIR,{'recursive':!![]}),_0x2e700b[_0x503e59(0x1df)+_0x4ee532(0x201)](FALLBACK_FILE,JSON[_0x4ee532(0x1f4)](_0x2fdbdf,null,0x8*0x232+-0x763+-0xa2b)),syncToEnv(_0x237e8f,_0x3d4185),_0x2fdbdf;}export function moveUp(_0x2ce7a5,_0x489c66=_0x453089(0x1e0)){const _0xd232c1=_0x453089,_0x55f941=_0x453089,_0x215ec6=getFallbackOrder(),_0x235f9e=_0x215ec6[_0xd232c1(0x1e1)]['indexOf'](_0x2ce7a5);if(_0x235f9e>0x1b*-0x155+-0x389+0x2780)[_0x215ec6[_0xd232c1(0x1e1)][_0x235f9e-(0x7c5+0x28*-0xdb+0x1a74)],_0x215ec6['fallbacks'][_0x235f9e]]=[_0x215ec6[_0xd232c1(0x1e1)][_0x235f9e],_0x215ec6['fallbacks'][_0x235f9e-(-0x210f+-0x301*-0x1+0x1*0x1e0f)]];else{if(_0x235f9e===0x1170+-0x1*0x18e6+-0x1*-0x776){const _0x1f8fe6=_0x215ec6[_0x55f941(0x1ef)];_0x215ec6[_0x55f941(0x1ef)]=_0x2ce7a5,_0x215ec6[_0xd232c1(0x1e1)][0x1*-0x2476+-0x4bd+0x2933*0x1]=_0x1f8fe6;}}return setFallbackOrder(_0x215ec6[_0x55f941(0x1ef)],_0x215ec6[_0xd232c1(0x1e1)],_0x489c66);}export function moveDown(_0x1cfb57,_0x3038a0=_0x1d3b10(0x1e0)){const _0x1050aa=_0x1d3b10,_0x34567f=_0x1d3b10,_0x5a7a32=getFallbackOrder();if(_0x1cfb57===_0x5a7a32[_0x1050aa(0x1ef)]&&_0x5a7a32[_0x34567f(0x1e1)][_0x34567f(0x1db)]>0x2032+0x92*0x33+0x4*-0xf52){const _0x54fa3f=_0x5a7a32[_0x1050aa(0x1e1)][-0xc*0x32e+0x1*0x114d+-0x13*-0x119];_0x5a7a32['fallbacks'][-0x175a+-0x266c+0x3dc6]=_0x1cfb57,_0x5a7a32[_0x1050aa(0x1ef)]=_0x54fa3f;}else{const _0x524c3f=_0x5a7a32['fallbacks'][_0x34567f(0x1f8)](_0x1cfb57);_0x524c3f>=-0x1*0x4a9+-0x151a+0x19c3*0x1&&_0x524c3f<_0x5a7a32['fallbacks'][_0x1050aa(0x1db)]-(-0x1*0x2317+0x11a2+0x1176)&&([_0x5a7a32[_0x34567f(0x1e1)][_0x524c3f],_0x5a7a32[_0x34567f(0x1e1)][_0x524c3f+(-0x3*0x25d+0x359+0x3bf*0x1)]]=[_0x5a7a32[_0x1050aa(0x1e1)][_0x524c3f+(-0x1d0f+-0x1774+0x4*0xd21)],_0x5a7a32[_0x1050aa(0x1e1)][_0x524c3f]]);}return setFallbackOrder(_0x5a7a32[_0x1050aa(0x1ef)],_0x5a7a32[_0x34567f(0x1e1)],_0x3038a0);}export function addFallback(_0x29454e,_0x2f3ea2=_0x453089(0x1e0)){const _0x2e4756=_0x1d3b10,_0x3827e7=_0x1d3b10,_0x4592af=getFallbackOrder();return!_0x4592af[_0x2e4756(0x1e1)][_0x3827e7(0x1ee)](_0x29454e)&&_0x29454e!==_0x4592af[_0x3827e7(0x1ef)]&&_0x4592af[_0x2e4756(0x1e1)]['push'](_0x29454e),setFallbackOrder(_0x4592af['primary'],_0x4592af[_0x2e4756(0x1e1)],_0x2f3ea2);}export function removeFallback(_0x23f487,_0x46262b=_0x453089(0x1e0)){const _0x5b4619=_0x453089,_0x1296ae=_0x453089,_0x128028=getFallbackOrder();return _0x128028['fallbacks']=_0x128028[_0x5b4619(0x1e1)][_0x1296ae(0x1e4)](_0x30514f=>_0x30514f!==_0x23f487),setFallbackOrder(_0x128028[_0x1296ae(0x1ef)],_0x128028['fallbacks'],_0x46262b);}export function formatOrder(){const _0x5027c5=_0x1d3b10,_0x4cde43=_0x1d3b10,_0x24d83c=getFallbackOrder(),_0x11faf4=[];return _0x11faf4[_0x5027c5(0x1d5)](_0x5027c5(0x1f0)+_0x24d83c[_0x5027c5(0x1ef)]+'\x20(Primary)'),_0x24d83c['fallbacks'][_0x5027c5(0x1de)]((_0x1e36d1,_0x56ee97)=>{_0x11faf4['push'](_0x56ee97+(0x147*-0x14+0x9d3*0x1+0xfbb)+'.\x20'+(_0x56ee97===0x1003*-0x1+0x1725+0xa6*-0xb?'🥈':_0x56ee97===0x8*-0x25c+-0x57c+0x185d?'🥉':'\x20\x20')+'\x20'+_0x1e36d1);}),_0x11faf4[_0x4cde43(0x1d8)]('\x0a');}function _0xc435(){const _0x3ce6ef=['uK9wsurfuJ0','Ew5J','uK9wsurfuLm9','uK9wsurfuLm','Dg9ju09tDhjPBG','ChvZAa','rMfPBgvKihrVia','zxjYB3i','AM9PBG','zw52','ntuXmJKYvg9qtvP4','BgvUz3rO','mtK4ndeWmuPzC1rrtq','BwTKAxjtEw5J','zM9YrwfJAa','D3jPDgvgAwXLuW','Dw5RBM93BG','zMfSBgjHy2TZ','rKfmtejbq0TFua','odC0ndG2nej2wwferW','zMLSDgvY','y29UC3rYDwn0BW','n2zPzNPzqG','kcGOlISPkYKRkq','mtq2otmZnhHsueD3yW','mtu3mdi1Dfbwy3PN','og5oA1brra','nJbWDMvmAMS','zxHPC3rZu3LUyW','Bwf0y2G','Aw5JBhvKzxm','ChjPBwfYEq','ms4G8j+LHYa','t1zjrevs','C3bSAxq','ntGZmJyWsu9mywfu','C3rYAw5NAwz5','CgfYC2u','cLbssu1buLLFua','ufjjtufswv9quG','Aw5KzxHpzG','DxrMltG','mtCWndK0mM5htLLoAW','ufjpvKLervjtpq','DhjPBq','Dg8GlMvUDJO','C2vHCMnO','Dg9tDhjPBMC'];_0xc435=function(){return _0x3ce6ef;};return _0xc435();}function syncToEnv(_0x3919b6,_0x4c3cdf){const _0x7ccbd1=_0x1d3b10,_0x436ba0=_0x1d3b10;try{if(!_0x2e700b['existsSync'](ENV_FILE))return;let _0x9f4aa7=_0x2e700b['readFileSy'+'nc'](ENV_FILE,'utf-8');_0x9f4aa7[_0x7ccbd1(0x1ed)](/^PRIMARY_PROVIDER=.*/m)?_0x9f4aa7=_0x9f4aa7['replace'](/^PRIMARY_PROVIDER=.*/m,_0x436ba0(0x1f7)+'OVIDER='+_0x3919b6):_0x9f4aa7+=_0x7ccbd1(0x1f6)+_0x436ba0(0x200)+_0x3919b6;const _0xe11973=_0x4c3cdf[_0x7ccbd1(0x1d8)](',');_0x9f4aa7[_0x436ba0(0x1ed)](/^FALLBACK_PROVIDERS=.*/m)?_0x9f4aa7=_0x9f4aa7['replace'](/^FALLBACK_PROVIDERS=.*/m,_0x7ccbd1(0x1e2)+_0x436ba0(0x202)+_0xe11973):_0x9f4aa7+='\x0aFALLBACK_'+_0x7ccbd1(0x1fb)+_0xe11973,writeSecure(ENV_FILE,_0x9f4aa7);}catch(_0x29700e){console[_0x7ccbd1(0x1d7)](_0x436ba0(0x1d6)+'sync\x20fallb'+'ack\x20order\x20'+_0x7ccbd1(0x1fd),_0x29700e);}}
|
|
@@ -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(_0x390ffb,_0xe4be6a){const _0x3db768=_0x1254,_0x20bc4a=_0x1254,_0x5915a7=_0x390ffb();while(!![]){try{const _0x5ed835=parseInt(_0x3db768(0x1ac))/(0x243+0x657+-0x899)+parseInt(_0x20bc4a(0x1b4))/(0x2052+0x2634+0x11a1*-0x4)*(-parseInt(_0x3db768(0x1b7))/(0x1*0x2441+0x2403+-0x4841))+parseInt(_0x20bc4a(0x1a7))/(0x19ea+-0x1*0x5e7+-0x13ff)*(parseInt(_0x3db768(0x1a9))/(-0x76d+0x979+-0x207))+-parseInt(_0x3db768(0x1a6))/(0x744*0x1+0x1cba+0x47f*-0x8)*(-parseInt(_0x3db768(0x1be))/(-0x1*-0x18ca+0x37f+0xe21*-0x2))+-parseInt(_0x3db768(0x1af))/(-0x1a45+-0x1834+0x3281)*(-parseInt(_0x3db768(0x1b8))/(-0x5ef+0xe2*-0x10+0x1418))+-parseInt(_0x3db768(0x1c0))/(-0x5f*0x5d+-0x5f*-0x34+0xf41)+-parseInt(_0x3db768(0x1bb))/(-0x29*0xcb+-0x8*0x304+0x38ae*0x1)*(-parseInt(_0x20bc4a(0x1aa))/(0x17*0x161+-0x56b*-0x2+-0x345*0xd));if(_0x5ed835===_0xe4be6a)break;else _0x5915a7['push'](_0x5915a7['shift']());}catch(_0xfa11a0){_0x5915a7['push'](_0x5915a7['shift']());}}}(_0x3bf5,-0x54324+-0x96ae+0xcb526));const _0xd4dde2=(function(){let _0x2f4f90=!![];return function(_0x321153,_0x5f5132){const _0x283157=_0x2f4f90?function(){const _0x52a716=_0x1254;if(_0x5f5132){const _0x13c599=_0x5f5132[_0x52a716(0x1bd)](_0x321153,arguments);return _0x5f5132=null,_0x13c599;}}:function(){};return _0x2f4f90=![],_0x283157;};}()),_0x51ead5=_0xd4dde2(this,function(){const _0x3870fb=_0x1254,_0x135946=_0x1254;return _0x51ead5[_0x3870fb(0x1bc)]()['search'](_0x3870fb(0x1ba)+'+$')['toString']()[_0x135946(0x1b9)+'r'](_0x51ead5)['search']('(((.+)+)+)'+'+$');});_0x51ead5();import _0x430624 from'fs';export const SECURE_MODE=0x1a5*-0xd+-0x5*-0x5ab+-0x1d2*0x3;export function writeSecure(_0x403f26,_0x41e808){const _0x441ca0=_0x1254;_0x430624['writeFileS'+'ync'](_0x403f26,_0x41e808,{'mode':SECURE_MODE});try{_0x430624[_0x441ca0(0x1b1)](_0x403f26,SECURE_MODE);}catch{}}function _0x1254(_0x5bf048,_0x5ba40a){_0x5bf048=_0x5bf048-(-0x27e*-0x2+-0x21db+-0x259*-0xd);const _0x374877=_0x3bf5();let _0x3d659d=_0x374877[_0x5bf048];if(_0x1254['wurDjO']===undefined){var _0x29f83a=function(_0x1f2aa3){const _0x576495='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x1be4cd='',_0x2ba3da='',_0x269f9b=_0x1be4cd+_0x29f83a;for(let _0x3b3fc8=0x13*-0x1d3+-0x1f*-0x7+0x21d0,_0x2857ac,_0x34a74e,_0x1121e9=0x5*0x5ab+0x1c11+-0x17c*0x26;_0x34a74e=_0x1f2aa3['charAt'](_0x1121e9++);~_0x34a74e&&(_0x2857ac=_0x3b3fc8%(0x221*0xd+0x20e*0xc+0x3451*-0x1)?_0x2857ac*(0x154e+-0x138b+0x2b*-0x9)+_0x34a74e:_0x34a74e,_0x3b3fc8++%(-0x1*0x176c+0xd6*0x10+0xa10))?_0x1be4cd+=_0x269f9b['charCodeAt'](_0x1121e9+(0xfd8*0x1+-0x4f+-0xf7f))-(0xd91+0xeed*0x1+-0xc*0x25f)!==-0x2*-0x499+-0x2*0x1349+0x4*0x758?String['fromCharCode'](0xee7+0x209*-0xe+0xe96*0x1&_0x2857ac>>(-(-0x6*-0x151+-0x10b6+-0x1*-0x8d2)*_0x3b3fc8&-0x1ea3+0x68d*-0x3+0x3250)):_0x3b3fc8:0xb31+-0xb52+0x21){_0x34a74e=_0x576495['indexOf'](_0x34a74e);}for(let _0x388e11=-0x5*-0xcb+-0x153*0x10+-0x1139*-0x1,_0x52c031=_0x1be4cd['length'];_0x388e11<_0x52c031;_0x388e11++){_0x2ba3da+='%'+('00'+_0x1be4cd['charCodeAt'](_0x388e11)['toString'](-0x671*0x1+-0x422*-0x3+-0x1f7*0x3))['slice'](-(0x9*-0x3f+-0x904+0xb3d));}return decodeURIComponent(_0x2ba3da);};_0x1254['kDNlit']=_0x29f83a,_0x1254['SEAoiS']={},_0x1254['wurDjO']=!![];}const _0x68a4e9=_0x374877[-0x205*-0x8+0x1b26+0x1e2*-0x17],_0x4f51c3=_0x5bf048+_0x68a4e9,_0x287b90=_0x1254['SEAoiS'][_0x4f51c3];if(!_0x287b90){const _0x59ed98=function(_0x5e2fba){this['ypYNrA']=_0x5e2fba,this['swJTvG']=[0x1*-0x1039+0x1e7b+-0xe41,0x16*0xfd+0x100b+-0x25c9,0xbb8+-0x81a+-0x39e*0x1],this['XwqKwC']=function(){return'newState';},this['Ywmrsq']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['vQExcw']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x59ed98['prototype']['bojmwX']=function(){const _0x2234b2=new RegExp(this['Ywmrsq']+this['vQExcw']),_0x4da68f=_0x2234b2['test'](this['XwqKwC']['toString']())?--this['swJTvG'][-0x10ab*-0x2+-0xe2c+0x3*-0x663]:--this['swJTvG'][0x14a4+-0x131b+-0x1*0x189];return this['SRzVcS'](_0x4da68f);},_0x59ed98['prototype']['SRzVcS']=function(_0x4c9225){if(!Boolean(~_0x4c9225))return _0x4c9225;return this['BZXcCn'](this['ypYNrA']);},_0x59ed98['prototype']['BZXcCn']=function(_0x4df194){for(let _0x33f4b7=-0x1d41*0x1+0x243+0x1afe,_0x553361=this['swJTvG']['length'];_0x33f4b7<_0x553361;_0x33f4b7++){this['swJTvG']['push'](Math['round'](Math['random']())),_0x553361=this['swJTvG']['length'];}return _0x4df194(this['swJTvG'][0x2052+0x2634+0x99*-0x76]);},new _0x59ed98(_0x1254)['bojmwX'](),_0x3d659d=_0x1254['kDNlit'](_0x3d659d),_0x1254['SEAoiS'][_0x4f51c3]=_0x3d659d;}else _0x3d659d=_0x287b90;return _0x3d659d;}function _0x3bf5(){const _0x3bb37f=['mJu3ndu3nM5VBer5zW','BwLZC2LUzW','nJuWmZfMBwPiv3m','Bw9Kzq','y3vYzq','mJaWwu16ze9l','y29Kzq','y2HTB2rtEw5J','BwfW','ru5pru5u','mJC3mJziC3PKCem','zxjYB3i','BwvZC2fNzq','nJbSshvlAKW','mtiZndi2quL3EKH1','y29UC3rYDwn0BW','kcGOlISPkYKRkq','mtfqzwTbre4','Dg9tDhjPBMC','yxbWBhK','mJGWotaZzNPtu3bv','CMvWywLYzwq','nJu1ntaYmgLWrMnxCq','mtjlAw5lu1G','mtu5ody4ANzjrgjv','C3rHDfn5BMm','odvLqwL5DvO'];_0x3bf5=function(){return _0x3bb37f;};return _0x3bf5();}export function ensureSecureMode(_0x2de5ec){const _0x4943b5=_0x1254,_0x1fb29b=_0x1254;let _0x32c1b8;try{_0x32c1b8=_0x430624[_0x4943b5(0x1a8)](_0x2de5ec);}catch(_0x5d2066){const _0x1a4a30=_0x5d2066;if(_0x1a4a30[_0x1fb29b(0x1b0)]===_0x4943b5(0x1b3))return{'path':_0x2de5ec,'status':_0x4943b5(0x1ab)};return{'path':_0x2de5ec,'status':_0x1fb29b(0x1b5),'error':_0x1a4a30['message']};}const _0x583574=_0x32c1b8[_0x1fb29b(0x1ad)]&0x221*0xd+0x20e*0xc+0x192b*-0x2;if((_0x583574&~SECURE_MODE)===0x154e+-0x138b+0x29*-0xb)return{'path':_0x2de5ec,'status':'already-se'+_0x1fb29b(0x1ae)};try{return _0x430624[_0x1fb29b(0x1b1)](_0x2de5ec,SECURE_MODE),{'path':_0x2de5ec,'status':_0x4943b5(0x1bf),'previousMode':_0x583574['toString'](-0x1*0x176c+0xd6*0x10+0xa14)};}catch(_0x3ae919){return{'path':_0x2de5ec,'status':_0x4943b5(0x1b5),'error':_0x3ae919 instanceof Error?_0x3ae919[_0x1fb29b(0x1b6)]:String(_0x3ae919)};}}export function auditSensitiveFiles(_0x9c78c){const _0x88d88b=_0x1254;return _0x9c78c[_0x88d88b(0x1b2)](_0x32f799=>ensureSecureMode(_0x32f799));}
|
|
@@ -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
|
+
const _0x401d24=_0x185a,_0x4e77b6=_0x185a;(function(_0x113a87,_0x3267ef){const _0x3e4c8e=_0x185a,_0x2559a5=_0x185a,_0x14da63=_0x113a87();while(!![]){try{const _0x275e3b=parseInt(_0x3e4c8e(0x1d3))/(-0x125b+-0x1c4a+0x2ea6)+-parseInt(_0x3e4c8e(0x1e2))/(0xc*-0x229+0x11*0xc5+0xcd9)+-parseInt(_0x3e4c8e(0x1e8))/(-0x354+-0x1*0xff7+0x134e)*(parseInt(_0x2559a5(0x1d2))/(0x1f5e+-0x2219+-0x1*-0x2bf))+-parseInt(_0x3e4c8e(0x1d4))/(0x725+-0x1457+0xd37)*(parseInt(_0x3e4c8e(0x1e4))/(0x64e*0x1+-0x24e+-0x3fa))+-parseInt(_0x3e4c8e(0x1df))/(0x363+0x10a5+-0x1*0x1401)+-parseInt(_0x3e4c8e(0x1d5))/(0x1aca+-0x2406+0x944)+parseInt(_0x2559a5(0x1d6))/(0x13b3+0x2*-0x739+-0x538);if(_0x275e3b===_0x3267ef)break;else _0x14da63['push'](_0x14da63['shift']());}catch(_0x186a4d){_0x14da63['push'](_0x14da63['shift']());}}}(_0x5733,0xb5a84+-0x3*-0x49797+-0xd49e3));const _0x108e27=(function(){let _0x1bd297=!![];return function(_0x1eeaae,_0x5148f1){const _0x1adb4a=_0x1bd297?function(){const _0x3efa18=_0x185a;if(_0x5148f1){const _0x43657d=_0x5148f1[_0x3efa18(0x1e5)](_0x1eeaae,arguments);return _0x5148f1=null,_0x43657d;}}:function(){};return _0x1bd297=![],_0x1adb4a;};}()),_0x102eb6=_0x108e27(this,function(){const _0x57a72b=_0x185a,_0x4c62dd=_0x185a;return _0x102eb6[_0x57a72b(0x1de)]()[_0x57a72b(0x1e1)](_0x57a72b(0x1d1)+'+$')[_0x57a72b(0x1de)]()[_0x4c62dd(0x1db)+'r'](_0x102eb6)['search'](_0x4c62dd(0x1d1)+'+$');});_0x102eb6();import{writeFileSync,mkdirSync}from'fs';import{join}from'path';function _0x185a(_0x47bb14,_0x1e0f07){_0x47bb14=_0x47bb14-(0x17c6+0x1dd1+-0x33c6);const _0x1a4933=_0x5733();let _0x36afd0=_0x1a4933[_0x47bb14];if(_0x185a['shaahf']===undefined){var _0x3c146d=function(_0x98e462){const _0x4d1d72='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x2d83ee='',_0xb43482='',_0x113a87=_0x2d83ee+_0x3c146d;for(let _0x3267ef=0x2060+-0x98f*0x2+0x2*-0x6a1,_0x14da63,_0x275e3b,_0x186a4d=-0x61c+0x8ac+-0x290;_0x275e3b=_0x98e462['charAt'](_0x186a4d++);~_0x275e3b&&(_0x14da63=_0x3267ef%(-0x227c+-0x1*0x16df+0x395f)?_0x14da63*(0x15c6+-0x128c+-0x6*0x7f)+_0x275e3b:_0x275e3b,_0x3267ef++%(-0xd*-0x13e+0x139f+-0x23c1))?_0x2d83ee+=_0x113a87['charCodeAt'](_0x186a4d+(-0x15d5+-0x232a+-0x1f*-0x1d7))-(0x237a+-0xf3+-0x227d)!==0x1ae*0xd+0x66*-0x33+-0x184?String['fromCharCode'](0x93b+-0x217*-0x11+-0x2bc3&_0x14da63>>(-(0x17d2+-0x59*0x65+0xb4d)*_0x3267ef&0x15f2+0x168d+-0x45*0xa5)):_0x3267ef:-0x28*-0xcb+0xdce+-0x2d86){_0x275e3b=_0x4d1d72['indexOf'](_0x275e3b);}for(let _0x4dfd1e=0x1f26+-0x1d19+-0x15*0x19,_0x3f39b3=_0x2d83ee['length'];_0x4dfd1e<_0x3f39b3;_0x4dfd1e++){_0xb43482+='%'+('00'+_0x2d83ee['charCodeAt'](_0x4dfd1e)['toString'](-0x1*0x17dc+0x12b3+0x539))['slice'](-(-0x913+-0x1e40+0x2755));}return decodeURIComponent(_0xb43482);};_0x185a['HhTVlI']=_0x3c146d,_0x185a['pDhnMM']={},_0x185a['shaahf']=!![];}const _0x141930=_0x1a4933[0x481*-0x1+-0x4d6*-0x1+-0x55],_0x468bbc=_0x47bb14+_0x141930,_0x4b6c73=_0x185a['pDhnMM'][_0x468bbc];if(!_0x4b6c73){const _0x4a577a=function(_0x4cb7cc){this['ByoVKO']=_0x4cb7cc,this['iTRRqF']=[-0x1c4a+-0x27f+0x1eca,0xd15*0x1+-0x135e*-0x2+-0x33d1,-0x1*0xff7+-0xa12+-0x535*-0x5],this['hslmnM']=function(){return'newState';},this['YinEWg']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['JixbOM']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x4a577a['prototype']['IERjIz']=function(){const _0x2dbc3b=new RegExp(this['YinEWg']+this['JixbOM']),_0x4e2ee4=_0x2dbc3b['test'](this['hslmnM']['toString']())?--this['iTRRqF'][-0x2*0x659+-0xf1*0x23+0x2da6]:--this['iTRRqF'][-0x1*0xaa7+0x205d*-0x1+0x2b04];return this['fFJAEt'](_0x4e2ee4);},_0x4a577a['prototype']['fFJAEt']=function(_0x5a9662){if(!Boolean(~_0x5a9662))return _0x5a9662;return this['HhsYFl'](this['ByoVKO']);},_0x4a577a['prototype']['HhsYFl']=function(_0x408fe9){for(let _0x42cc37=-0xd*0xa3+0x363+-0x1*-0x4e4,_0x4bb4c1=this['iTRRqF']['length'];_0x42cc37<_0x4bb4c1;_0x42cc37++){this['iTRRqF']['push'](Math['round'](Math['random']())),_0x4bb4c1=this['iTRRqF']['length'];}return _0x408fe9(this['iTRRqF'][0x1aca+-0x2406+0x93c]);},new _0x4a577a(_0x185a)['IERjIz'](),_0x36afd0=_0x185a['HhTVlI'](_0x36afd0),_0x185a['pDhnMM'][_0x468bbc]=_0x36afd0;}else _0x36afd0=_0x4b6c73;return _0x36afd0;}function _0x5733(){const _0x4e2078=['qKXfx0rfqurFtq','qKXfx1nftezFua','Dg9tDhjPBMC','nJa3mJmZow9Rtvb6Ea','DhH0','C2vHCMnO','otq0ode4AeDyzenQ','Dhj1zq','mtaXmdu1mg5vz3PStG','yxbWBhK','BM93','lMfSDMLUlwjVDa','mJCZm2Lqy2fyCW','kcGOlISPkYKRkq','ndeYngjpuhP1wG','mti3mZa2mu9TvLrstG','nw9wsLLWBa','mteXnZCWmtzMDgzUDwC','mZaXmJG5mdr4reDpu2q','AgvHCNrIzwf0lG','zw52','Dw5Yzwy','zMXVB3i','y29UC3rYDwn0BW'];_0x5733=function(){return _0x4e2078;};return _0x5733();}import{homedir}from'os';const HEARTBEAT_PATH=join(homedir(),_0x401d24(0x1e7),_0x401d24(0x1d7)+_0x401d24(0x1e0)),HEARTBEAT_INTERVAL_MS=0x680d+-0x14f9c+0x1d1ef;let heartbeatTimer=null;function writeHeartbeat(){const _0x33fa1d=_0x401d24,_0xa51b1e=_0x4e77b6;try{mkdirSync(join(homedir(),_0x33fa1d(0x1e7)),{'recursive':!![]}),writeFileSync(HEARTBEAT_PATH,Math[_0xa51b1e(0x1da)](Date[_0x33fa1d(0x1e6)]()/(-0x1*0x16df+-0x1e23+-0x5e*-0x9b))+'\x0a');}catch{}}export function startHeartbeatWriter(){const _0x1c6184=_0x401d24,_0x4ec2b7=_0x401d24;if(process[_0x1c6184(0x1d8)]['ALVIN_DISA'+_0x4ec2b7(0x1dc)+'AN']===_0x4ec2b7(0x1e3)||process[_0x4ec2b7(0x1d8)]['ALVIN_DISA'+_0x1c6184(0x1dd)+'RESERVATIO'+'N']===_0x4ec2b7(0x1e3))return;writeHeartbeat(),heartbeatTimer=setInterval(writeHeartbeat,HEARTBEAT_INTERVAL_MS);if(heartbeatTimer[_0x4ec2b7(0x1d9)])heartbeatTimer[_0x1c6184(0x1d9)]();}export function stopHeartbeatWriter(){heartbeatTimer&&(clearInterval(heartbeatTimer),heartbeatTimer=null);}
|