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,174 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* v4.13 — alvin_dispatch custom-tool service.
|
|
3
|
-
*
|
|
4
|
-
* Architectural replacement for Claude Agent SDK's built-in
|
|
5
|
-
* `Task(run_in_background: true)` tool. The SDK's built-in version
|
|
6
|
-
* ties the background sub-agent's execution to the parent SDK
|
|
7
|
-
* subprocess lifecycle — killing the parent (e.g. via v4.12.3's
|
|
8
|
-
* bypass-abort) cascades into killing any in-flight background tasks.
|
|
9
|
-
*
|
|
10
|
-
* This module instead spawns a truly independent `claude -p` subprocess
|
|
11
|
-
* via Node's `child_process.spawn({ detached: true, stdio: [...] })`.
|
|
12
|
-
* The subprocess:
|
|
13
|
-
* - Has its own PID, own process group (by detached: true)
|
|
14
|
-
* - Is unreffed so the parent Node process doesn't wait for it
|
|
15
|
-
* - Writes its stream-json output to its own file
|
|
16
|
-
* - Survives any abort/crash/restart of the parent Alvin bot
|
|
17
|
-
*
|
|
18
|
-
* The async-agent-watcher polls the output file and delivers the
|
|
19
|
-
* final result via subagent-delivery.ts when the sub-agent completes.
|
|
20
|
-
*
|
|
21
|
-
* See Phase A of docs/superpowers/plans/2026-04-16-v4.13-truly-async-subagents.md
|
|
22
|
-
* for the empirical verification that detached `claude -p` subprocesses
|
|
23
|
-
* behave as expected (they do).
|
|
24
|
-
*/
|
|
25
|
-
import { spawn } from "node:child_process";
|
|
26
|
-
import fs from "node:fs";
|
|
27
|
-
import crypto from "node:crypto";
|
|
28
|
-
import { resolve } from "node:path";
|
|
29
|
-
import { findClaudeBinary } from "../find-claude-binary.js";
|
|
30
|
-
import { registerPendingAgent } from "./async-agent-watcher.js";
|
|
31
|
-
import { getAllSessions } from "./session.js";
|
|
32
|
-
import { SUBAGENTS_DIR } from "../paths.js";
|
|
33
|
-
/** Generate a 32-char hex agent id. Avoids collisions across parallel
|
|
34
|
-
* dispatches even at sub-millisecond intervals. */
|
|
35
|
-
function generateAgentId() {
|
|
36
|
-
return "alvin-" + crypto.randomBytes(12).toString("hex");
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* v5.7.0 — Best-effort push: tell the bot a detached sub-agent just
|
|
40
|
-
* exited so it can read the jsonl and deliver immediately instead of
|
|
41
|
-
* waiting for the next 15s poll tick. An in-process self-call to the
|
|
42
|
-
* always-on loopback route. Any failure (bot mid-restart, port race,
|
|
43
|
-
* network) is swallowed — startup reconciliation and the poll backstop
|
|
44
|
-
* are the safety nets. Never throws, always resolves.
|
|
45
|
-
*/
|
|
46
|
-
export async function postSubagentExit(agentId, exitCode) {
|
|
47
|
-
try {
|
|
48
|
-
const { getWebPort, getInternalToken } = await import("../web/server.js");
|
|
49
|
-
const port = getWebPort();
|
|
50
|
-
const token = getInternalToken();
|
|
51
|
-
const ac = new AbortController();
|
|
52
|
-
const timer = setTimeout(() => ac.abort(), 4000);
|
|
53
|
-
try {
|
|
54
|
-
await fetch(`http://127.0.0.1:${port}/internal/subagent-exit`, {
|
|
55
|
-
method: "POST",
|
|
56
|
-
headers: {
|
|
57
|
-
"Content-Type": "application/json",
|
|
58
|
-
Authorization: `Bearer ${token}`,
|
|
59
|
-
},
|
|
60
|
-
body: JSON.stringify({ agentId, exitCode }),
|
|
61
|
-
signal: ac.signal,
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
finally {
|
|
65
|
-
clearTimeout(timer);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
catch {
|
|
69
|
-
/* best-effort — reconciliation/poll backstop cover any miss */
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Dispatch a detached sub-agent. Returns synchronously — the subprocess
|
|
74
|
-
* runs in the background. Throws if spawn fails. On success:
|
|
75
|
-
*
|
|
76
|
-
* 1. Subprocess is running, writing stream-json to outputFile
|
|
77
|
-
* 2. The agent is registered with async-agent-watcher (pending list)
|
|
78
|
-
* 3. session.pendingBackgroundCount is incremented
|
|
79
|
-
* 4. When the subprocess completes, watcher delivers the result
|
|
80
|
-
*/
|
|
81
|
-
export function dispatchDetachedAgent(input) {
|
|
82
|
-
// Ensure subagents dir exists. Idempotent.
|
|
83
|
-
try {
|
|
84
|
-
fs.mkdirSync(SUBAGENTS_DIR, { recursive: true });
|
|
85
|
-
}
|
|
86
|
-
catch {
|
|
87
|
-
/* race-safe — next open() will surface the real error */
|
|
88
|
-
}
|
|
89
|
-
const agentId = generateAgentId();
|
|
90
|
-
const outputFile = resolve(SUBAGENTS_DIR, `${agentId}.jsonl`);
|
|
91
|
-
// Open the output file for write. We pass the FD to child's stdout
|
|
92
|
-
// so the subprocess writes directly without going through us.
|
|
93
|
-
// stderr → separate .err file for diagnostics.
|
|
94
|
-
const errFile = resolve(SUBAGENTS_DIR, `${agentId}.err`);
|
|
95
|
-
const outFd = fs.openSync(outputFile, "w");
|
|
96
|
-
const errFd = fs.openSync(errFile, "w");
|
|
97
|
-
const cleanEnv = { ...process.env };
|
|
98
|
-
// v4.13 — Prevent nested-session errors. The SDK refuses to run if
|
|
99
|
-
// these are already set in env (they leak from parent Alvin/SDK).
|
|
100
|
-
delete cleanEnv.CLAUDECODE;
|
|
101
|
-
delete cleanEnv.CLAUDE_CODE_ENTRYPOINT;
|
|
102
|
-
const claudePath = findClaudeBinary();
|
|
103
|
-
if (!claudePath) {
|
|
104
|
-
fs.closeSync(outFd);
|
|
105
|
-
fs.closeSync(errFd);
|
|
106
|
-
throw new Error("alvin_dispatch: claude CLI not found. Install claude-code to enable background dispatch.");
|
|
107
|
-
}
|
|
108
|
-
const child = spawn(claudePath, [
|
|
109
|
-
"-p",
|
|
110
|
-
input.prompt,
|
|
111
|
-
"--output-format",
|
|
112
|
-
"stream-json",
|
|
113
|
-
"--verbose",
|
|
114
|
-
], {
|
|
115
|
-
cwd: input.cwd,
|
|
116
|
-
detached: true,
|
|
117
|
-
stdio: ["ignore", outFd, errFd],
|
|
118
|
-
env: cleanEnv,
|
|
119
|
-
});
|
|
120
|
-
// Close our copies of the FDs — the child has its own descriptors now.
|
|
121
|
-
try {
|
|
122
|
-
fs.closeSync(outFd);
|
|
123
|
-
}
|
|
124
|
-
catch {
|
|
125
|
-
/* ignore */
|
|
126
|
-
}
|
|
127
|
-
try {
|
|
128
|
-
fs.closeSync(errFd);
|
|
129
|
-
}
|
|
130
|
-
catch {
|
|
131
|
-
/* ignore */
|
|
132
|
-
}
|
|
133
|
-
// v5.7.0 — Push: deliver the result the instant the subprocess exits,
|
|
134
|
-
// instead of waiting for the next 15s poll tick. `exit` fires after
|
|
135
|
-
// the OS has reaped the process and flushed its inherited stdout FD,
|
|
136
|
-
// so the terminating result line is fully on disk before the handler
|
|
137
|
-
// reads it (race-safe). Best-effort: startup reconciliation + the poll
|
|
138
|
-
// backstop cover a missed push (bot restarted mid-run, port race).
|
|
139
|
-
// Attached before unref() so the listener is registered on the handle.
|
|
140
|
-
child.on("exit", (code) => {
|
|
141
|
-
void postSubagentExit(agentId, code);
|
|
142
|
-
});
|
|
143
|
-
// Detach from parent Node's event loop so parent exit doesn't wait.
|
|
144
|
-
child.unref();
|
|
145
|
-
// Register with watcher so it polls the output file and delivers.
|
|
146
|
-
// child.pid is captured here (before unref) so killSessionDetachedAgents
|
|
147
|
-
// can send SIGTERM to the process. child.pid may be undefined if the OS
|
|
148
|
-
// failed to assign a PID (extremely rare); registerPendingAgent tolerates it.
|
|
149
|
-
registerPendingAgent({
|
|
150
|
-
agentId,
|
|
151
|
-
outputFile,
|
|
152
|
-
description: input.description,
|
|
153
|
-
prompt: input.prompt,
|
|
154
|
-
chatId: input.chatId,
|
|
155
|
-
userId: input.userId,
|
|
156
|
-
toolUseId: null,
|
|
157
|
-
sessionKey: input.sessionKey,
|
|
158
|
-
platform: input.platform,
|
|
159
|
-
pid: child.pid,
|
|
160
|
-
});
|
|
161
|
-
// Increment the session's pendingBackgroundCount so the main handler
|
|
162
|
-
// knows a background task is in flight (same signal path as SDK's
|
|
163
|
-
// built-in Task tool).
|
|
164
|
-
try {
|
|
165
|
-
const s = getAllSessions().get(input.sessionKey);
|
|
166
|
-
if (s) {
|
|
167
|
-
s.pendingBackgroundCount = (s.pendingBackgroundCount ?? 0) + 1;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
catch {
|
|
171
|
-
/* never let counter updates break dispatch */
|
|
172
|
-
}
|
|
173
|
-
return { agentId, outputFile, spawned: true };
|
|
174
|
-
}
|
|
1
|
+
(function(_0x93b634,_0xf0c1bc){const _0x5a52aa=_0x2a62,_0x2e0163=_0x2a62,_0x3bf75b=_0x93b634();while(!![]){try{const _0x3da468=-parseInt(_0x5a52aa(0xac))/(0x1832+-0x8*0x4cc+0xe2f)*(-parseInt(_0x2e0163(0xa4))/(0x1771+0x3f5*0x3+-0x234e))+-parseInt(_0x5a52aa(0xa8))/(-0x733+-0x147*-0x8+0x1*-0x302)*(-parseInt(_0x2e0163(0x8e))/(-0xdc7+0x4b4+-0xb3*-0xd))+parseInt(_0x5a52aa(0x8b))/(-0x1516+0x4*0x47e+0x49*0xb)+-parseInt(_0x5a52aa(0x8f))/(0x4*-0x6c3+-0x53*-0x9+0x1827)+-parseInt(_0x2e0163(0xa9))/(-0x19ca+0x4b1*-0x1+0x30d*0xa)+-parseInt(_0x5a52aa(0x84))/(-0x2*-0xc6a+-0x9b+-0x1*0x1831)+parseInt(_0x2e0163(0x7a))/(0x9d9*-0x1+-0x1921+0x2303);if(_0x3da468===_0xf0c1bc)break;else _0x3bf75b['push'](_0x3bf75b['shift']());}catch(_0x248a8a){_0x3bf75b['push'](_0x3bf75b['shift']());}}}(_0x39b0,-0x8478+0x9f04d+-0x2282));const _0x4c385e=(function(){let _0x5f183c=!![];return function(_0x183536,_0x5b6911){const _0xe0b464=_0x5f183c?function(){const _0x40ae86=_0x2a62;if(_0x5b6911){const _0xb74e17=_0x5b6911[_0x40ae86(0x81)](_0x183536,arguments);return _0x5b6911=null,_0xb74e17;}}:function(){};return _0x5f183c=![],_0xe0b464;};}()),_0x2d8849=_0x4c385e(this,function(){const _0x1ce771=_0x2a62,_0x395c73=_0x2a62;return _0x2d8849[_0x1ce771(0x86)]()['search']('(((.+)+)+)'+'+$')[_0x395c73(0x86)]()['constructo'+'r'](_0x2d8849)[_0x395c73(0xad)](_0x1ce771(0x99)+'+$');});_0x2d8849();import{spawn}from'node:child_process';import _0x21e498 from'node:fs';import _0x204d1a from'node:crypto';import{resolve}from'node:path';import{findClaudeBinary}from'../find-claude-binary.js';function _0x2a62(_0x1edfdf,_0x356e4a){_0x1edfdf=_0x1edfdf-(-0x1*0x4bb+0x1*0x13cd+-0xe99);const _0x246393=_0x39b0();let _0x2d3c5f=_0x246393[_0x1edfdf];if(_0x2a62['ChWWVt']===undefined){var _0x4e7de4=function(_0x1de731){const _0x5651dd='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x33efa9='',_0x3aa051='',_0x4bad9e=_0x33efa9+_0x4e7de4;for(let _0xeace22=0x2003+0x266+-0x17*0x17f,_0x334086,_0x4c7a48,_0x3be852=-0x34+0x1df1+0x14b*-0x17;_0x4c7a48=_0x1de731['charAt'](_0x3be852++);~_0x4c7a48&&(_0x334086=_0xeace22%(0x1*-0x877+0x2528+-0x1cad*0x1)?_0x334086*(-0x1*0x97+0x1391+-0x2f*0x66)+_0x4c7a48:_0x4c7a48,_0xeace22++%(0x1b*-0x75+0xb23*0x3+-0x46*0x4d))?_0x33efa9+=_0x4bad9e['charCodeAt'](_0x3be852+(-0x2*0x5a7+-0x1cd*0x7+0x17f3))-(0x2d6+0x624+-0x8f0*0x1)!==0x1712+-0x120f+-0x503?String['fromCharCode'](0x429*0x1+0x14*-0x1a2+0x1d7e&_0x334086>>(-(0x54d*-0x3+-0xba*-0x7+0xad3)*_0xeace22&-0xdf1+-0x1*-0x6e1+0x716)):_0xeace22:-0xcdc+-0x14ca+-0x1*-0x21a6){_0x4c7a48=_0x5651dd['indexOf'](_0x4c7a48);}for(let _0x50a543=-0x31+0x2129+-0x20f8,_0x173bef=_0x33efa9['length'];_0x50a543<_0x173bef;_0x50a543++){_0x3aa051+='%'+('00'+_0x33efa9['charCodeAt'](_0x50a543)['toString'](-0x3*0x770+0x4c6*-0x1+0x1b26))['slice'](-(-0x8a3+0xaa4*0x1+-0x1ff));}return decodeURIComponent(_0x3aa051);};_0x2a62['YcYwmz']=_0x4e7de4,_0x2a62['AmyWeU']={},_0x2a62['ChWWVt']=!![];}const _0x17a8fe=_0x246393[-0xd00+0x9e0+-0x4*-0xc8],_0x15f3d6=_0x1edfdf+_0x17a8fe,_0x459ebc=_0x2a62['AmyWeU'][_0x15f3d6];if(!_0x459ebc){const _0x24c764=function(_0x1036a3){this['NwOlTd']=_0x1036a3,this['jAOXyf']=[-0x1*0x2072+0x1*0xae8+0x158b,0x4a4*0x3+-0x1*0x1dbf+0xfd3,0x8b6+-0xfc5+-0x70f*-0x1],this['DRnJyo']=function(){return'newState';},this['ReFKQB']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['wivnvP']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x24c764['prototype']['Zyodxi']=function(){const _0x29f678=new RegExp(this['ReFKQB']+this['wivnvP']),_0x2f246b=_0x29f678['test'](this['DRnJyo']['toString']())?--this['jAOXyf'][0x30*-0x4d+-0x17*-0x3d+0x8f6]:--this['jAOXyf'][0x2031+0x1832+-0x5*0xb47];return this['gSuZQZ'](_0x2f246b);},_0x24c764['prototype']['gSuZQZ']=function(_0x46225f){if(!Boolean(~_0x46225f))return _0x46225f;return this['HzfQPI'](this['NwOlTd']);},_0x24c764['prototype']['HzfQPI']=function(_0x592b11){for(let _0x5b180b=-0x1a6b*0x1+0x161*0x11+0x2fa,_0x55fe14=this['jAOXyf']['length'];_0x5b180b<_0x55fe14;_0x5b180b++){this['jAOXyf']['push'](Math['round'](Math['random']())),_0x55fe14=this['jAOXyf']['length'];}return _0x592b11(this['jAOXyf'][-0x733+-0x147*-0x8+0x1*-0x305]);},new _0x24c764(_0x2a62)['Zyodxi'](),_0x2d3c5f=_0x2a62['YcYwmz'](_0x2d3c5f),_0x2a62['AmyWeU'][_0x15f3d6]=_0x2d3c5f;}else _0x2d3c5f=_0x459ebc;return _0x2d3c5f;}import{registerPendingAgent}from'./async-agent-watcher.js';import{getAllSessions}from'./session.js';import{SUBAGENTS_DIR}from'../paths.js';function generateAgentId(){const _0x3da96d=_0x2a62,_0x2d8565=_0x2a62;return'alvin-'+_0x204d1a['randomByte'+'s'](-0x34+0x1df1+0x2b3*-0xb)[_0x3da96d(0x86)](_0x2d8565(0x98));}export async function postSubagentExit(_0x3325da,_0x372ecb){const _0x4a3be1=_0x2a62,_0x3d375a=_0x2a62;try{const {getWebPort:_0xfd3dd4,getInternalToken:_0x3b4c25}=await import(_0x4a3be1(0x95)+_0x4a3be1(0x93)),_0x388bb5=_0xfd3dd4(),_0x20a584=_0x3b4c25(),_0x4bd892=new AbortController(),_0x19a564=setTimeout(()=>_0x4bd892['abort'](),0x1*-0x877+0x2528+-0x45b*0x3);try{await fetch(_0x4a3be1(0x7d)+_0x3d375a(0x9e)+_0x388bb5+(_0x4a3be1(0x79)+_0x4a3be1(0xaa)+_0x3d375a(0xaf)),{'method':_0x4a3be1(0x88),'headers':{'Content-Type':'applicatio'+_0x4a3be1(0x85),'Authorization':'Bearer\x20'+_0x20a584},'body':JSON[_0x4a3be1(0x9b)]({'agentId':_0x3325da,'exitCode':_0x372ecb}),'signal':_0x4bd892['signal']});}finally{clearTimeout(_0x19a564);}}catch{}}export function dispatchDetachedAgent(_0xbf1f85){const _0xddcf58=_0x2a62,_0x2a6761=_0x2a62;try{_0x21e498[_0xddcf58(0x9d)](SUBAGENTS_DIR,{'recursive':!![]});}catch{}const _0x838483=generateAgentId(),_0x115a6a=resolve(SUBAGENTS_DIR,_0x838483+_0x2a6761(0x7b)),_0x34c38e=resolve(SUBAGENTS_DIR,_0x838483+_0x2a6761(0x7e)),_0x7d52a3=_0x21e498[_0x2a6761(0x9f)](_0x115a6a,'w'),_0x4caea3=_0x21e498[_0x2a6761(0x9f)](_0x34c38e,'w'),_0x5a04d7={...process[_0xddcf58(0x8d)]};delete _0x5a04d7[_0xddcf58(0x80)],delete _0x5a04d7[_0x2a6761(0x8c)+_0xddcf58(0x94)+'NT'];const _0x577f17=findClaudeBinary();if(!_0x577f17){_0x21e498[_0x2a6761(0xa0)](_0x7d52a3),_0x21e498[_0xddcf58(0xa0)](_0x4caea3);throw new Error(_0xddcf58(0x7c)+_0x2a6761(0x92)+'de\x20CLI\x20not'+'\x20found.\x20In'+_0x2a6761(0xa5)+_0xddcf58(0x9c)+'\x20enable\x20ba'+_0xddcf58(0x82)+_0xddcf58(0x91));}const _0x3be3ed=spawn(_0x577f17,['-p',_0xbf1f85['prompt'],'--output-f'+_0x2a6761(0x96),_0x2a6761(0x97)+'n','--verbose'],{'cwd':_0xbf1f85[_0xddcf58(0xa7)],'detached':!![],'stdio':[_0xddcf58(0xa3),_0x7d52a3,_0x4caea3],'env':_0x5a04d7});try{_0x21e498[_0xddcf58(0xa0)](_0x7d52a3);}catch{}try{_0x21e498[_0x2a6761(0xa0)](_0x4caea3);}catch{}_0x3be3ed['on'](_0xddcf58(0xa2),_0xbf9592=>{void postSubagentExit(_0x838483,_0xbf9592);}),_0x3be3ed[_0xddcf58(0x8a)](),registerPendingAgent({'agentId':_0x838483,'outputFile':_0x115a6a,'description':_0xbf1f85[_0x2a6761(0x83)+'n'],'prompt':_0xbf1f85[_0x2a6761(0xae)],'chatId':_0xbf1f85[_0x2a6761(0x9a)],'userId':_0xbf1f85[_0xddcf58(0xa6)],'toolUseId':null,'sessionKey':_0xbf1f85[_0x2a6761(0x7f)],'platform':_0xbf1f85[_0x2a6761(0x87)],'pid':_0x3be3ed[_0x2a6761(0x90)]});try{const _0x1c47d1=getAllSessions()[_0x2a6761(0xab)](_0xbf1f85['sessionKey']);_0x1c47d1&&(_0x1c47d1['pendingBac'+_0xddcf58(0x89)+'nt']=(_0x1c47d1[_0x2a6761(0xa1)+_0xddcf58(0x89)+'nt']??-0x1*0x97+0x1391+-0xe*0x15b)+(0x1b*-0x75+0xb23*0x3+-0x1*0x1511));}catch{}return{'agentId':_0x838483,'outputFile':_0x115a6a,'spawned':!![]};}function _0x39b0(){const _0x117cae=['kcGOlISPkYKRkq','y2HHDeLK','C3rYAw5NAwz5','zguTy29Kzsb0BW','BwTKAxjtEw5J','lJaUmc4XoG','B3bLBLn5BMm','y2XVC2vtEw5J','CgvUzgLUz0jHyW','zxHPDa','AwDUB3jL','mty1ndmYnNrSD1j5vG','C3rHBgWGy2XHDq','DxnLCKLK','y3DK','m1LWDuH4ra','mtq5ntC3nfHeD3HgCa','C3vIywDLBNqTzq','z2v0','muD3ELD1Ca','C2vHCMnO','ChjVBxb0','EgL0','l2LUDgvYBMfSlW','mJG1mJuZmLvnvxf0vG','lMPZB25S','ywX2Aw5FzgLZCa','Ahr0CdOVlZeYnW','lMvYCG','C2vZC2LVBKTLEq','q0Xbvurfq09erq','yxbWBhK','y2TNCM91BMqGza','zgvZy3jPChrPBW','mZq3ntu1mM5LtMfXra','BI9QC29U','Dg9tDhjPBMC','CgXHDgzVCM0','ue9tva','A2DYB3vUzenVDq','Dw5Yzwy','oteWnZbtD2vis3K','q0Xbvurfx0npra','zw52','ndaWmdqZmLHNCKDZyq','ntqZndi3mLDdB0PNqW','CgLK','AxnWyxrJAc4','yxrJAdOGy2XHDq','DMvYlMPZ','rv9ftLrswvbpsq','lI4VD2vIl3nLCG','B3jTyxq','C3rYzwfTlwPZBW','Agv4'];_0x39b0=function(){return _0x117cae;};return _0x39b0();}
|
|
@@ -1,104 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* v4.13 — Alvin's custom MCP tools, registered with the Claude Agent SDK
|
|
3
|
-
* via `createSdkMcpServer()`.
|
|
4
|
-
*
|
|
5
|
-
* Currently exposes a single tool:
|
|
6
|
-
* `alvin_dispatch_agent(prompt, description)` — spawns a truly
|
|
7
|
-
* detached `claude -p` subprocess that's independent of the parent
|
|
8
|
-
* SDK lifecycle. Claude should prefer this over built-in
|
|
9
|
-
* `Task(run_in_background: true)` for any long-running work on
|
|
10
|
-
* Telegram so the main Telegram session isn't blocked by the SDK's
|
|
11
|
-
* task-notification injection mechanism.
|
|
12
|
-
*
|
|
13
|
-
* The MCP server is created lazily per-query so each query gets fresh
|
|
14
|
-
* handler context (chatId/userId/sessionKey) via a closure.
|
|
15
|
-
*/
|
|
16
|
-
import { createSdkMcpServer, tool, } from "@anthropic-ai/claude-agent-sdk";
|
|
17
|
-
import { z } from "zod";
|
|
18
|
-
import { dispatchDetachedAgent } from "./alvin-dispatch.js";
|
|
19
|
-
/**
|
|
20
|
-
* Build an MCP server bound to a specific turn's context. Pass the
|
|
21
|
-
* returned instance under `mcpServers: { alvin: <instance> }` in the
|
|
22
|
-
* query options.
|
|
23
|
-
*/
|
|
24
|
-
export function buildAlvinMcpServer(ctx) {
|
|
25
|
-
return createSdkMcpServer({
|
|
26
|
-
name: "alvin",
|
|
27
|
-
version: "4.13.0",
|
|
28
|
-
tools: [
|
|
29
|
-
tool("dispatch_agent", [
|
|
30
|
-
"Dispatch a TRULY DETACHED background sub-agent that runs",
|
|
31
|
-
"independently of this session. Use this for ANY long-running",
|
|
32
|
-
"work on Telegram/Slack/Discord/WhatsApp — research tasks,",
|
|
33
|
-
"audits, multi-page scraping, deep analysis — so the main",
|
|
34
|
-
"user session stays responsive and the user can keep chatting",
|
|
35
|
-
"with you while the sub-agent works.",
|
|
36
|
-
"",
|
|
37
|
-
"HOW IT DIFFERS FROM Task(run_in_background: true):",
|
|
38
|
-
"- The built-in Task tool's subprocess is tied to this session,",
|
|
39
|
-
" so aborting the session also kills the sub-agent mid-work.",
|
|
40
|
-
"- `alvin_dispatch.dispatch_agent` spawns a completely",
|
|
41
|
-
" independent `claude -p` subprocess that survives any abort,",
|
|
42
|
-
" crash, or restart of the main bot.",
|
|
43
|
-
"",
|
|
44
|
-
"WHEN TO USE:",
|
|
45
|
-
"- Any audit/research visiting >2 URLs or reading >5 files",
|
|
46
|
-
"- Full-repo scans, code reviews, SEO/security/perf audits",
|
|
47
|
-
"- Anything you'd describe as 'thorough' or 'takes a few min'",
|
|
48
|
-
"",
|
|
49
|
-
"HOW THE RESULT GETS BACK TO THE USER:",
|
|
50
|
-
"- The tool returns { agentId, outputFile } immediately.",
|
|
51
|
-
"- The bot's async-agent watcher polls the outputFile and",
|
|
52
|
-
" delivers the final result as a separate chat message when",
|
|
53
|
-
" the sub-agent completes (success, failure, or 5-min",
|
|
54
|
-
" staleness).",
|
|
55
|
-
"- Your job after calling this tool: tell the user ONE short",
|
|
56
|
-
" sentence about what you dispatched, then END your turn.",
|
|
57
|
-
" Do NOT wait. Do NOT poll the outputFile yourself.",
|
|
58
|
-
].join("\n"), {
|
|
59
|
-
prompt: z
|
|
60
|
-
.string()
|
|
61
|
-
.describe("The full prompt for the sub-agent. Be specific and self-contained — the sub-agent has no access to this conversation's context and will see only this prompt."),
|
|
62
|
-
description: z
|
|
63
|
-
.string()
|
|
64
|
-
.describe("Short human-readable title (e.g. 'SEO audit example.com', 'Research topic X'). Shown to the user when the result arrives."),
|
|
65
|
-
}, async (args) => {
|
|
66
|
-
try {
|
|
67
|
-
const result = dispatchDetachedAgent({
|
|
68
|
-
prompt: args.prompt,
|
|
69
|
-
description: args.description,
|
|
70
|
-
chatId: ctx.chatId,
|
|
71
|
-
userId: ctx.userId,
|
|
72
|
-
sessionKey: ctx.sessionKey,
|
|
73
|
-
platform: ctx.platform,
|
|
74
|
-
cwd: ctx.cwd,
|
|
75
|
-
});
|
|
76
|
-
return {
|
|
77
|
-
content: [
|
|
78
|
-
{
|
|
79
|
-
type: "text",
|
|
80
|
-
text: `✅ Background sub-agent dispatched.\n` +
|
|
81
|
-
`agentId: ${result.agentId}\n` +
|
|
82
|
-
`output_file: ${result.outputFile}\n` +
|
|
83
|
-
`The user will receive the result as a separate message when the sub-agent completes.\n` +
|
|
84
|
-
`End your turn now. Do not wait for the result — it arrives asynchronously.`,
|
|
85
|
-
},
|
|
86
|
-
],
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
catch (err) {
|
|
90
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
91
|
-
return {
|
|
92
|
-
content: [
|
|
93
|
-
{
|
|
94
|
-
type: "text",
|
|
95
|
-
text: `⚠️ Failed to dispatch background agent: ${msg}`,
|
|
96
|
-
},
|
|
97
|
-
],
|
|
98
|
-
isError: true,
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
}),
|
|
102
|
-
],
|
|
103
|
-
});
|
|
104
|
-
}
|
|
1
|
+
(function(_0x39941,_0x5f384d){const _0x4951b3=_0x4169,_0x5d650f=_0x4169,_0x3db530=_0x39941();while(!![]){try{const _0x585dc2=parseInt(_0x4951b3(0x145))/(0x1a45+-0x242f*0x1+0x9eb)+-parseInt(_0x4951b3(0x1b0))/(-0xc5*-0x16+0xa23+-0x1b0f)+parseInt(_0x4951b3(0x133))/(-0x163c+0xfc*-0x12+0x27f7)*(-parseInt(_0x5d650f(0x143))/(0x97e*0x4+-0x122*-0x1+-0x2716))+parseInt(_0x4951b3(0x13c))/(0x13*-0x43+-0x7*-0x4cf+-0x1cab)*(parseInt(_0x5d650f(0x198))/(0x2f2+-0xde7+0x1*0xafb))+-parseInt(_0x5d650f(0x1c4))/(0x11*0x74+-0x1c51+0x14a4)+-parseInt(_0x5d650f(0x18e))/(0x88*-0x2+-0x22*0x105+0x23c2*0x1)+-parseInt(_0x4951b3(0x192))/(-0x7b1*0x3+0x809+0x1*0xf13)*(-parseInt(_0x5d650f(0x1aa))/(0x1fd9+0xbb6*-0x3+0x353*0x1));if(_0x585dc2===_0x5f384d)break;else _0x3db530['push'](_0x3db530['shift']());}catch(_0xc64cbf){_0x3db530['push'](_0x3db530['shift']());}}}(_0x9618,-0x5*-0x6a56+0xb6d13+-0xfb*-0x166));const _0x86e91e=(function(){let _0x33d20f=!![];return function(_0x432688,_0x5bfb3a){const _0x6a485c=_0x33d20f?function(){const _0x3b5922=_0x4169;if(_0x5bfb3a){const _0x24eb45=_0x5bfb3a[_0x3b5922(0x1ae)](_0x432688,arguments);return _0x5bfb3a=null,_0x24eb45;}}:function(){};return _0x33d20f=![],_0x6a485c;};}()),_0x5710a8=_0x86e91e(this,function(){const _0x3a1f2d=_0x4169,_0x45b7cc=_0x4169;return _0x5710a8[_0x3a1f2d(0x12f)]()[_0x3a1f2d(0x149)]('(((.+)+)+)'+'+$')[_0x45b7cc(0x12f)]()[_0x3a1f2d(0x1af)+'r'](_0x5710a8)[_0x45b7cc(0x149)](_0x45b7cc(0x1cd)+'+$');});_0x5710a8();function _0x4169(_0x138645,_0x397e44){_0x138645=_0x138645-(0x4+-0x7f9*-0x2+-0xed0);const _0x5163c9=_0x9618();let _0x92cc91=_0x5163c9[_0x138645];if(_0x4169['ReDuaV']===undefined){var _0x27480=function(_0x4cec02){const _0x3a5f6f='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x3e9881='',_0x4f139d='',_0x351725=_0x3e9881+_0x27480;for(let _0x5a3a15=0xe85+-0x2510+-0xc7*-0x1d,_0x330467,_0x42006c,_0x5e0d1c=0x128*0x1+0x363+-0x48b;_0x42006c=_0x4cec02['charAt'](_0x5e0d1c++);~_0x42006c&&(_0x330467=_0x5a3a15%(0x3d*0x96+0xdb*0x1+-0x5*0x751)?_0x330467*(-0x355+0x916+-0x581)+_0x42006c:_0x42006c,_0x5a3a15++%(0x2*-0x9+-0xf*-0x40+-0x3aa))?_0x3e9881+=_0x351725['charCodeAt'](_0x5e0d1c+(-0x2f*-0x43+0x1a11*-0x1+0xdce))-(-0x239+-0x2414+0x2657)!==-0x2318+0xcd6+0xb*0x206?String['fromCharCode'](-0xce8+0x1c90+-0xea9&_0x330467>>(-(-0x26c0*-0x1+0xc83+0x3341*-0x1)*_0x5a3a15&0x1*0x3a3+0xeca+-0x7*0x2a1)):_0x5a3a15:0x101c*0x2+0xa2a+0x32*-0xd9){_0x42006c=_0x3a5f6f['indexOf'](_0x42006c);}for(let _0x2a99d3=0x13c4+0x79c*0x2+-0x22fc,_0x1452f7=_0x3e9881['length'];_0x2a99d3<_0x1452f7;_0x2a99d3++){_0x4f139d+='%'+('00'+_0x3e9881['charCodeAt'](_0x2a99d3)['toString'](-0xa0e+-0xb64+0x1582))['slice'](-(-0x155b+-0x1*0x24cf+-0x2*-0x1d16));}return decodeURIComponent(_0x4f139d);};_0x4169['TlKvvH']=_0x27480,_0x4169['SUdJSW']={},_0x4169['ReDuaV']=!![];}const _0x43d370=_0x5163c9[0x1a45+-0x242f*0x1+0x9ea],_0x312cc6=_0x138645+_0x43d370,_0x568f56=_0x4169['SUdJSW'][_0x312cc6];if(!_0x568f56){const _0x5d9962=function(_0x1b68cb){this['cfjXVO']=_0x1b68cb,this['WUxiMQ']=[-0xc5*-0x16+0xa23+-0x1b10,-0x163c+0xfc*-0x12+0x27f4,0x97e*0x4+-0x122*-0x1+-0x271a],this['YMhtCc']=function(){return'newState';},this['QQcvlY']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['JNJnyD']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x5d9962['prototype']['xJRcYk']=function(){const _0x39941=new RegExp(this['QQcvlY']+this['JNJnyD']),_0x5f384d=_0x39941['test'](this['YMhtCc']['toString']())?--this['WUxiMQ'][0x13*-0x43+-0x7*-0x4cf+-0x1caf]:--this['WUxiMQ'][0x2f2+-0xde7+0x5*0x231];return this['RluYfy'](_0x5f384d);},_0x5d9962['prototype']['RluYfy']=function(_0x3db530){if(!Boolean(~_0x3db530))return _0x3db530;return this['RYgJHG'](this['cfjXVO']);},_0x5d9962['prototype']['RYgJHG']=function(_0x585dc2){for(let _0xc64cbf=0x11*0x74+-0x1c51+0x149d,_0xb0524d=this['WUxiMQ']['length'];_0xc64cbf<_0xb0524d;_0xc64cbf++){this['WUxiMQ']['push'](Math['round'](Math['random']())),_0xb0524d=this['WUxiMQ']['length'];}return _0x585dc2(this['WUxiMQ'][0x88*-0x2+-0x22*0x105+0x23ba*0x1]);},new _0x5d9962(_0x4169)['xJRcYk'](),_0x92cc91=_0x4169['TlKvvH'](_0x92cc91),_0x4169['SUdJSW'][_0x312cc6]=_0x92cc91;}else _0x92cc91=_0x568f56;return _0x92cc91;}import{createSdkMcpServer,tool}from'@anthropic-ai/claude-agent-sdk';function _0x9618(){const _0x11e7ab=['ig91Dhb1DezPBa','zxn1BhqG4OcuigL0','y3jHCgLUzYWGza','lsbzB3vYigPVyG','ihDPBgWGC2vLia','CM9JzxnZihrOyq','vgHLigz1BgWGCa','BIbIB3qU','DxjPDhKVCgvYzG','BYbUB3qGD2fPDa','zwnPzMLJigfUza','quniruqGyMfJAW','DxjUig5VDY4Gra','AwXSihjLy2vPDG','y3jPyMuGyxmGjW','icbKzwXPDMvYCW','DgvSEs4','y3DK','ztOG','zwvWigfUywX5CW','nc4XmY4W','rKvsuYbguK9nia','zw50igbJBgf1za','icbeBYbot1qGDW','AM9PBG','zsaTCgaGC3vICa','C3bHDgnOx2fNzq','C2fNzsb3AgvUia','Dg9VBdOGDgvSBa','BhqGyxjYAxzLCW','DwiTywDLBNqGDW','ihn1yI1Hz2vUDa','igf1zgL0CW','lsbuAguGDg9VBa','igjHy2TNCM91BG','Dcb5B3uGzgLZCa','DcbOyxmGBM8Gyq','DxnLCKLK','Dc1PBIbuyxnRia','igeGC2vWyxjHDa','BgLUzYb0AgLZia','DxnLCIbZzxnZAq','lsbgDwXSlxjLCa','C3rYAw5N','C2fNzsb3AgvU','rsbvu0vsoG','C3LUy2HYB25VDq','lsbuAguGyM90jW','D29YAYbVBIbuzq','Dg9VBcDZihn1yG','ywDLBNqGy29TCa','BhrPlxbHz2uGCW','DcbZDxj2AxzLCW','z2vUDa','ihrPzwqGDg8GDa','ihjLC3vSDcbHCW','CgLJifGNks4GuW','zM9YiefowsbSBW','C3nPB24GywXZBW','igfMDgvYignHBa','AxmG4OcuihnVihrO','mtiXndG0mtzos2PfvwO','u2HVCNqGAhvTyq','vgHLihvZzxiGDW','ysbMzxCGBwLUjW','nde5ntq5nhrZzwvJBa','ihrPDgXLicHLlG','AgLSzsb0AguGCW','zY4Gj1nftYbHDq','zw4Gru5eihLVDq','v0HftIbutYbvuW','mZqWmti4vufIsxnw','rgLZCgf0y2GGyq','lsbuAguGyNvPBa','pJiGvvjmCYbVCG','zsb0AguGCMvZDq','y2HHDeLK','yxvKAxrZlcbTDq','B3iGj3rHA2vZia','CYbZzxnZAw9UlG','zgvZy3jPyMu','ywDLBNrjzdOG','igeGy29TCgXLDa','ihrHC2TZla','Ag93BIb0BYb0Aa','BYbZy2fUCYWGyW','AgLZignVBNzLCG','ig1Pzc13B3jRlG','AgLZihnLC3nPBW','ntbIBKH6sxK','B24GC3rHExmGCG','lsbGywX2Aw5Fza','CIbWB2XSCYb0Aa','yxbWBhK','y29UC3rYDwn0BW','otKXndu4yMPMAgnj','igzVCIb0AguGCG','nsbMAwXLCW','zsb1C2vYihDOzq','Aw5KzxbLBMrLBG','DxjLlcbVCIa1lq','ifvZzsb0AgLZia','zs5JB20NlcaNuG','zcbHz2vUDdOG','CIbYzxn0yxj0ia','ih0GAw1TzwrPyq','BL9IywnRz3jVDq','vcbWB2XSihrOzq','zsb5B3vYC2vSzG','4OcuihjLC2vHCMnO','BNrGihnWyxDUCW','ChjVBxb0','D2L0Acb5B3uGDW','icbZDgfSzw5LCW','ihzPC2L0Aw5Nia','mtC0odKXnuDnvNHisW','DgHVCM91z2GNia','zsbJAgf0ig1LCW','icb0AguGC3vIlq','igTPBgXZihrOzq','CYbHC3LUyY1HzW','BhqGyxmGysbZzq','DcbYDw5Z','zxnWB25ZAxzLia','kcGOlISPkYKRkq','zxnLyxjJAcb0BW','zsbVDxrWDxrgAq','igfUEsbHyM9YDa','vgfZAYHYDw5FAq','Dgv4Da','icbZBYbHyM9YDa','BwLU','igfYCML2zxmGyq','4PQG77IpiezHAwXLzcb0','DgHLihn1yI1HzW','igfNzw50swqSia','BIb0AguGCMvZDq','zxiGy2fUigTLzq','ihjLDhvYBNmGEW','Dg9tDhjPBMC','ywX2Aw4','BNqGzgLZCgf0yW','C2f0Aw9Uj3mGyW','mJq5ntaXCgLvr3ju','B2rLihjLDMLLDW','AxnWyxrJAc5KAq','t05fihnOB3j0','lwfNzw50ihrOyq','y2vZCYWGzMfPBa','se9xieLuierjrG','z3jVDw5Kihn1yG','BwvZC2fNzq','ndbHz01yq0O','BI1YzwfKywjSzq','lsbbBNL0AgLUzW','ihLVDsDKigrLCW','ChjVy2vZCYbPCW','AgvKlGO','B3v0Chv0rMLSzq','ohnNELPjva','BMq6ihrYDwuPoG','nJiWoteZwNrbvgP5','l1DOyxrZqxbWia','qKfdsYbutYbusa','BguGyw5K','C2vHCMnO','CIb0DxjUlG','Aw5NihrOzsbZzq','zw50lIbczsbZCa','igfIB3v0ihDOyq','BgvNCMfTl1nSyq','zw50ignVBxbSzq','CgfYyxrLig1LCW'];_0x9618=function(){return _0x11e7ab;};return _0x9618();}import{z}from'zod';import{dispatchDetachedAgent}from'./alvin-dispatch.js';export function buildAlvinMcpServer(_0x5b4faf){const _0x28307f=_0x4169,_0x130664=_0x4169;return createSdkMcpServer({'name':_0x28307f(0x130),'version':_0x28307f(0x165),'tools':[tool('dispatch_a'+_0x28307f(0x186),[_0x28307f(0x199)+'\x20TRULY\x20DET'+_0x130664(0x15c)+_0x28307f(0x13a)+_0x28307f(0x137)+_0x130664(0x1cb),_0x28307f(0x1b4)+'tly\x20of\x20thi'+_0x28307f(0x1a0)+_0x28307f(0x1b6)+_0x28307f(0x18a)+'ng-running',_0x28307f(0x181)+_0x28307f(0x14e)+'ck/Discord'+_0x28307f(0x146)+_0x130664(0x1be)+_0x130664(0x1a4),_0x130664(0x19e)+_0x130664(0x184)+_0x28307f(0x153)+_0x28307f(0x164)+_0x28307f(0x18d)+'e\x20main',_0x130664(0x17a)+_0x130664(0x1ab)+_0x28307f(0x1cc)+'and\x20the\x20us'+_0x28307f(0x12d)+'p\x20chatting',_0x130664(0x1c1)+_0x130664(0x194)+_0x130664(0x16f)+'orks.','',_0x28307f(0x139)+_0x130664(0x166)+_0x28307f(0x1d1)+_0x130664(0x1bb)+_0x28307f(0x144),_0x130664(0x19a)+_0x130664(0x177)+_0x28307f(0x182)+_0x28307f(0x140)+_0x130664(0x187)+_0x130664(0x1a9)+'n,',_0x28307f(0x126)+_0x28307f(0x14b)+_0x28307f(0x18b)+_0x130664(0x1c8)+_0x130664(0x170)+_0x28307f(0x1a8),_0x28307f(0x1ac)+_0x28307f(0x135)+_0x130664(0x16b)+_0x130664(0x1bf)+_0x28307f(0x1a3)+'ely','\x20\x20independ'+_0x130664(0x167)+_0x28307f(0x16a)+_0x28307f(0x156)+_0x28307f(0x185)+_0x28307f(0x1d0)+',','\x20\x20crash,\x20o'+_0x28307f(0x1b9)+'of\x20the\x20mai'+_0x130664(0x158),'',_0x28307f(0x197)+'E:','-\x20Any\x20audi'+'t/research'+_0x130664(0x1c3)+_0x130664(0x19b)+'\x20reading\x20>'+_0x130664(0x1b2),_0x28307f(0x17b)+_0x130664(0x1a6)+_0x130664(0x134)+'s,\x20SEO/sec'+_0x130664(0x159)+_0x130664(0x171),_0x130664(0x13e)+_0x130664(0x13f)+_0x28307f(0x15f)+_0x28307f(0x1c5)+_0x130664(0x19f)+_0x28307f(0x191),'','HOW\x20THE\x20RE'+'SULT\x20GETS\x20'+_0x130664(0x147)+_0x130664(0x17e),_0x28307f(0x172)+_0x130664(0x12e)+_0x130664(0x12b)+_0x28307f(0x142)+_0x28307f(0x1ba)+_0x28307f(0x161),_0x28307f(0x180)+_0x28307f(0x1c9)+'ent\x20watche'+_0x130664(0x1ad)+_0x130664(0x1cf)+_0x130664(0x148),_0x28307f(0x160)+'\x20the\x20final'+_0x28307f(0x188)+_0x130664(0x178)+_0x28307f(0x1c6)+_0x28307f(0x17d),_0x28307f(0x1c7)+_0x130664(0x183)+'letes\x20(suc'+_0x28307f(0x138)+_0x28307f(0x1b5)+_0x130664(0x127),_0x130664(0x1c2)+'s).',_0x130664(0x154)+_0x130664(0x18c)+_0x130664(0x179)+_0x28307f(0x16d)+'\x20the\x20user\x20'+_0x28307f(0x136),'\x20\x20sentence'+_0x130664(0x14d)+_0x28307f(0x174)+'atched,\x20th'+_0x28307f(0x196)+_0x28307f(0x14a),_0x28307f(0x168)+'ait.\x20Do\x20NO'+_0x130664(0x1bc)+_0x28307f(0x151)+_0x28307f(0x1bd)+'.'][_0x28307f(0x169)]('\x0a'),{'prompt':z[_0x28307f(0x17c)]()[_0x28307f(0x1a1)](_0x130664(0x157)+'rompt\x20for\x20'+_0x28307f(0x12a)+_0x28307f(0x14c)+_0x28307f(0x15b)+'\x20self-cont'+'ained\x20—\x20th'+'e\x20sub-agen'+_0x28307f(0x175)+'ccess\x20to\x20t'+_0x28307f(0x1a7)+_0x28307f(0x132)+'ontext\x20and'+_0x130664(0x155)+'only\x20this\x20'+'prompt.'),'description':z[_0x28307f(0x17c)]()[_0x28307f(0x1a1)](_0x28307f(0x18f)+_0x130664(0x13d)+_0x28307f(0x193)+_0x130664(0x195)+'dit\x20exampl'+_0x28307f(0x1b7)+_0x28307f(0x1ce)+_0x28307f(0x189)+_0x130664(0x1a5)+_0x28307f(0x1b3)+_0x28307f(0x12c)+_0x28307f(0x16e)+'.')},async _0x30bb19=>{const _0x528e11=_0x130664,_0x2389f4=_0x130664;try{const _0x39ab39=dispatchDetachedAgent({'prompt':_0x30bb19[_0x528e11(0x1c0)],'description':_0x30bb19['descriptio'+'n'],'chatId':_0x5b4faf[_0x528e11(0x19d)],'userId':_0x5b4faf[_0x528e11(0x176)],'sessionKey':_0x5b4faf['sessionKey'],'platform':_0x5b4faf['platform'],'cwd':_0x5b4faf[_0x528e11(0x162)]});return{'content':[{'type':_0x528e11(0x1d2),'text':'✅\x20Backgrou'+'nd\x20sub-age'+_0x528e11(0x131)+_0x528e11(0x141)+(_0x528e11(0x1a2)+_0x39ab39['agentId']+'\x0a')+('output_fil'+_0x528e11(0x163)+_0x39ab39[_0x2389f4(0x142)]+'\x0a')+(_0x528e11(0x190)+_0x528e11(0x15e)+_0x528e11(0x19c)+_0x2389f4(0x1ca)+_0x528e11(0x150)+_0x528e11(0x16c)+_0x2389f4(0x12a)+_0x528e11(0x14f)+'tes.\x0a')+('End\x20your\x20t'+_0x528e11(0x15d)+_0x2389f4(0x15a)+_0x2389f4(0x1b1)+_0x2389f4(0x152)+_0x2389f4(0x128)+_0x528e11(0x17f)+'sly.')}]};}catch(_0x45418f){const _0x3c7df2=_0x45418f instanceof Error?_0x45418f[_0x528e11(0x13b)]:String(_0x45418f);return{'content':[{'type':_0x528e11(0x1d2),'text':_0x528e11(0x129)+'o\x20dispatch'+_0x528e11(0x173)+_0x2389f4(0x1b8)+_0x3c7df2}],'isError':!![]};}})]});}
|
|
@@ -1,224 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Asset Index — Scans ~/.alvin-bot/assets/ and builds a searchable registry.
|
|
3
|
-
*
|
|
4
|
-
* Produces:
|
|
5
|
-
* - INDEX.json — machine-readable, used by self-search and skill injection
|
|
6
|
-
* - INDEX.md — human-readable, injected into prompts for asset awareness
|
|
7
|
-
*
|
|
8
|
-
* Scan is filesystem-only (<5ms for ~60 files). No API calls.
|
|
9
|
-
* Re-scans only when ASSETS_DIR has changed since last scan.
|
|
10
|
-
*/
|
|
11
|
-
import fs from "fs";
|
|
12
|
-
import path from "path";
|
|
13
|
-
import { ASSETS_DIR, ASSETS_INDEX_JSON, ASSETS_INDEX_MD } from "../paths.js";
|
|
14
|
-
// ── Cache ───────────────────────────────────────────────
|
|
15
|
-
let cachedIndex = null;
|
|
16
|
-
// ── Helpers ─────────────────────────────────────────────
|
|
17
|
-
/**
|
|
18
|
-
* Walk a directory recursively, yielding file entries.
|
|
19
|
-
*/
|
|
20
|
-
function walkDir(dir) {
|
|
21
|
-
const results = [];
|
|
22
|
-
function walk(currentDir) {
|
|
23
|
-
let entries;
|
|
24
|
-
try {
|
|
25
|
-
entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
26
|
-
}
|
|
27
|
-
catch {
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
for (const entry of entries) {
|
|
31
|
-
const fullPath = path.resolve(currentDir, entry.name);
|
|
32
|
-
if (entry.isDirectory()) {
|
|
33
|
-
walk(fullPath);
|
|
34
|
-
}
|
|
35
|
-
else if (entry.isFile()) {
|
|
36
|
-
// Skip INDEX.json and INDEX.md at ASSETS_DIR root
|
|
37
|
-
if (currentDir === dir && (entry.name === "INDEX.json" || entry.name === "INDEX.md")) {
|
|
38
|
-
continue;
|
|
39
|
-
}
|
|
40
|
-
results.push({
|
|
41
|
-
name: entry.name,
|
|
42
|
-
path: fullPath,
|
|
43
|
-
relativePath: path.relative(dir, fullPath),
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
walk(dir);
|
|
49
|
-
return results;
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Generate a human-readable description from a filename.
|
|
53
|
-
* "profile-photo.jpeg" → "Profile Photo"
|
|
54
|
-
* "my-document.html" → "My Document"
|
|
55
|
-
*/
|
|
56
|
-
function descriptionFromFilename(filename, category) {
|
|
57
|
-
const name = filename.replace(/\.[^.]+$/, ""); // strip extension
|
|
58
|
-
const words = name.replace(/[-_]/g, " ").trim();
|
|
59
|
-
// Prefix with capitalized category for disambiguation when the filename alone is terse
|
|
60
|
-
const prefix = category ? category.replace(/[-_]/g, " ").replace(/\b\w/g, c => c.toUpperCase()) + ": " : "";
|
|
61
|
-
const title = words.replace(/\b\w/g, c => c.toUpperCase());
|
|
62
|
-
return prefix ? `${prefix}${title}` : title;
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Determine category for a file.
|
|
66
|
-
* Files in subdirectories get the directory name as category.
|
|
67
|
-
* Root-level files get a special category based on naming.
|
|
68
|
-
*/
|
|
69
|
-
function categorize(relativePath) {
|
|
70
|
-
const parts = relativePath.split(path.sep);
|
|
71
|
-
if (parts.length > 1) {
|
|
72
|
-
return parts[0]; // directory name
|
|
73
|
-
}
|
|
74
|
-
// Root-level file — categorize by pattern
|
|
75
|
-
const filename = parts[0].toLowerCase();
|
|
76
|
-
if (filename.includes("signature"))
|
|
77
|
-
return "signatures";
|
|
78
|
-
return "misc";
|
|
79
|
-
}
|
|
80
|
-
// ── Public API ──────────────────────────────────────────
|
|
81
|
-
/**
|
|
82
|
-
* Scan ASSETS_DIR and write INDEX.json + INDEX.md.
|
|
83
|
-
* Only re-scans if directory has changed since last scan.
|
|
84
|
-
* Returns the asset index.
|
|
85
|
-
*/
|
|
86
|
-
export function scanAssets() {
|
|
87
|
-
if (!fs.existsSync(ASSETS_DIR)) {
|
|
88
|
-
const empty = { lastScan: new Date().toISOString(), assets: [] };
|
|
89
|
-
cachedIndex = empty;
|
|
90
|
-
return empty;
|
|
91
|
-
}
|
|
92
|
-
// Check if re-scan needed
|
|
93
|
-
if (fs.existsSync(ASSETS_INDEX_JSON)) {
|
|
94
|
-
try {
|
|
95
|
-
const existing = JSON.parse(fs.readFileSync(ASSETS_INDEX_JSON, "utf-8"));
|
|
96
|
-
const dirStat = fs.statSync(ASSETS_DIR);
|
|
97
|
-
const lastScanTime = new Date(existing.lastScan).getTime();
|
|
98
|
-
// Also check subdirectory mtimes (adding a file to a subdir changes subdir mtime, not parent)
|
|
99
|
-
let newestMtime = dirStat.mtimeMs;
|
|
100
|
-
try {
|
|
101
|
-
const subdirs = fs.readdirSync(ASSETS_DIR, { withFileTypes: true });
|
|
102
|
-
for (const d of subdirs) {
|
|
103
|
-
if (d.isDirectory()) {
|
|
104
|
-
const subStat = fs.statSync(path.resolve(ASSETS_DIR, d.name));
|
|
105
|
-
if (subStat.mtimeMs > newestMtime)
|
|
106
|
-
newestMtime = subStat.mtimeMs;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
catch { /* ignore */ }
|
|
111
|
-
if (newestMtime <= lastScanTime) {
|
|
112
|
-
cachedIndex = existing;
|
|
113
|
-
return existing;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
catch {
|
|
117
|
-
// Corrupted index — re-scan
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
// Full scan
|
|
121
|
-
const files = walkDir(ASSETS_DIR);
|
|
122
|
-
const assets = [];
|
|
123
|
-
for (const file of files) {
|
|
124
|
-
try {
|
|
125
|
-
const stat = fs.statSync(file.path);
|
|
126
|
-
const category = categorize(file.relativePath);
|
|
127
|
-
assets.push({
|
|
128
|
-
path: file.relativePath,
|
|
129
|
-
absolutePath: file.path,
|
|
130
|
-
category,
|
|
131
|
-
filename: file.name,
|
|
132
|
-
ext: path.extname(file.name),
|
|
133
|
-
size: stat.size,
|
|
134
|
-
modified: new Date(stat.mtimeMs).toISOString(),
|
|
135
|
-
description: descriptionFromFilename(file.name, category),
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
catch {
|
|
139
|
-
// File disappeared between readdir and stat — skip
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
// Sort by category then filename
|
|
143
|
-
assets.sort((a, b) => a.category.localeCompare(b.category) || a.filename.localeCompare(b.filename));
|
|
144
|
-
const index = {
|
|
145
|
-
lastScan: new Date().toISOString(),
|
|
146
|
-
assets,
|
|
147
|
-
};
|
|
148
|
-
// Write INDEX.json
|
|
149
|
-
fs.writeFileSync(ASSETS_INDEX_JSON, JSON.stringify(index, null, 2));
|
|
150
|
-
// Write INDEX.md
|
|
151
|
-
const md = generateIndexMd(index);
|
|
152
|
-
fs.writeFileSync(ASSETS_INDEX_MD, md);
|
|
153
|
-
cachedIndex = index;
|
|
154
|
-
return index;
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Load asset index from disk (cached after first call).
|
|
158
|
-
*/
|
|
159
|
-
export function loadAssetIndex() {
|
|
160
|
-
if (cachedIndex)
|
|
161
|
-
return cachedIndex;
|
|
162
|
-
if (fs.existsSync(ASSETS_INDEX_JSON)) {
|
|
163
|
-
try {
|
|
164
|
-
cachedIndex = JSON.parse(fs.readFileSync(ASSETS_INDEX_JSON, "utf-8"));
|
|
165
|
-
return cachedIndex;
|
|
166
|
-
}
|
|
167
|
-
catch { /* fall through */ }
|
|
168
|
-
}
|
|
169
|
-
// No index — run scan
|
|
170
|
-
return scanAssets();
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Get INDEX.md content for prompt injection.
|
|
174
|
-
*/
|
|
175
|
-
export function getAssetIndexMd() {
|
|
176
|
-
if (fs.existsSync(ASSETS_INDEX_MD)) {
|
|
177
|
-
return fs.readFileSync(ASSETS_INDEX_MD, "utf-8");
|
|
178
|
-
}
|
|
179
|
-
return "";
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Find assets by category name.
|
|
183
|
-
*/
|
|
184
|
-
export function findAssetsByCategory(category) {
|
|
185
|
-
const index = loadAssetIndex();
|
|
186
|
-
return index.assets.filter(a => a.category === category);
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* Find assets by keyword match on filename, category, or description.
|
|
190
|
-
*/
|
|
191
|
-
export function findAssetsByKeyword(keywords) {
|
|
192
|
-
const index = loadAssetIndex();
|
|
193
|
-
const lower = keywords.map(k => k.toLowerCase());
|
|
194
|
-
return index.assets.filter(a => lower.some(k => a.filename.toLowerCase().includes(k) ||
|
|
195
|
-
a.category.toLowerCase().includes(k) ||
|
|
196
|
-
a.description.toLowerCase().includes(k)));
|
|
197
|
-
}
|
|
198
|
-
// ── INDEX.md Generator ──────────────────────────────────
|
|
199
|
-
function generateIndexMd(index) {
|
|
200
|
-
const date = new Date().toISOString().slice(0, 10);
|
|
201
|
-
const lines = [`## Your Assets (~/.alvin-bot/assets/) — ${date}\n`];
|
|
202
|
-
// Group by category
|
|
203
|
-
const byCategory = new Map();
|
|
204
|
-
for (const a of index.assets) {
|
|
205
|
-
const list = byCategory.get(a.category) || [];
|
|
206
|
-
list.push(a);
|
|
207
|
-
byCategory.set(a.category, list);
|
|
208
|
-
}
|
|
209
|
-
// Sort categories alphabetically
|
|
210
|
-
const sortedCategories = [...byCategory.keys()].sort();
|
|
211
|
-
for (const cat of sortedCategories) {
|
|
212
|
-
const assets = byCategory.get(cat);
|
|
213
|
-
const names = assets.map(a => a.filename);
|
|
214
|
-
// Compact display: show up to 6 names, then "..."
|
|
215
|
-
const display = names.length > 6
|
|
216
|
-
? names.slice(0, 5).join(", ") + `, ... (+${names.length - 5} more)`
|
|
217
|
-
: names.join(", ");
|
|
218
|
-
lines.push(`- **${cat}/** (${assets.length}): ${display}`);
|
|
219
|
-
}
|
|
220
|
-
const totalSize = index.assets.reduce((sum, a) => sum + a.size, 0);
|
|
221
|
-
const sizeMB = (totalSize / 1_048_576).toFixed(1);
|
|
222
|
-
lines.push(`\nTotal: ${index.assets.length} files, ${sizeMB} MB`);
|
|
223
|
-
return lines.join("\n") + "\n";
|
|
224
|
-
}
|
|
1
|
+
(function(_0x356207,_0x23a0d3){const _0xfa481b=_0x3011,_0x94d24e=_0x3011,_0x312856=_0x356207();while(!![]){try{const _0x439c74=-parseInt(_0xfa481b(0x21b))/(-0x20d7+0x1d40+0x5*0xb8)+parseInt(_0xfa481b(0x20e))/(0xe34+0xec2+-0x1cf4)*(parseInt(_0xfa481b(0x1ec))/(-0x45*-0x57+-0x1cf1+-0x581*-0x1))+-parseInt(_0x94d24e(0x1ea))/(0xc57+-0x889+-0x1*0x3ca)*(-parseInt(_0x94d24e(0x1da))/(-0xe2*0x21+-0x1*0x477+0x219e))+-parseInt(_0xfa481b(0x1fe))/(0x18f5*-0x1+0xb44+-0x1*-0xdb7)+parseInt(_0xfa481b(0x1ff))/(0x5c9*-0x5+0x21fa+-0x506)+parseInt(_0xfa481b(0x1de))/(0x1cc5+0x266+-0x1f23)+parseInt(_0x94d24e(0x1e6))/(0x1e92+-0x4b*0x6d+-0x166*-0x1)*(-parseInt(_0xfa481b(0x1eb))/(0x1a38+-0x96b+0x10c3*-0x1));if(_0x439c74===_0x23a0d3)break;else _0x312856['push'](_0x312856['shift']());}catch(_0x1e378f){_0x312856['push'](_0x312856['shift']());}}}(_0x4897,0xd*-0x6b47+0x9*-0x718b+0x6e14*0x27));const _0x4e504d=(function(){let _0x914a55=!![];return function(_0x247891,_0x1b72ef){const _0x54eb1f=_0x914a55?function(){if(_0x1b72ef){const _0x5339dd=_0x1b72ef['apply'](_0x247891,arguments);return _0x1b72ef=null,_0x5339dd;}}:function(){};return _0x914a55=![],_0x54eb1f;};}()),_0xc5e1c0=_0x4e504d(this,function(){const _0x4e268b=_0x3011,_0x568ef1=_0x3011;return _0xc5e1c0[_0x4e268b(0x210)]()[_0x4e268b(0x200)](_0x4e268b(0x201)+'+$')[_0x4e268b(0x210)]()[_0x568ef1(0x214)+'r'](_0xc5e1c0)[_0x568ef1(0x200)](_0x4e268b(0x201)+'+$');});function _0x3011(_0x3f2287,_0x99f7cf){_0x3f2287=_0x3f2287-(-0x23e5+0x2a5+0x257*0xf);const _0xd2f9b0=_0x4897();let _0x17ca60=_0xd2f9b0[_0x3f2287];if(_0x3011['hxmHnO']===undefined){var _0x29f768=function(_0x20956c){const _0x28505f='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x2f2622='',_0x51d6a1='',_0x4f7c14=_0x2f2622+_0x29f768;for(let _0x294889=-0x4*-0x14+-0x1d44+-0xe7a*-0x2,_0x30895e,_0x3e198c,_0x30f05=-0x45f*-0x2+-0x2289+0x1f*0xd5;_0x3e198c=_0x20956c['charAt'](_0x30f05++);~_0x3e198c&&(_0x30895e=_0x294889%(-0xa9c*0x1+0x5e3*0x4+0x1*-0xcec)?_0x30895e*(-0x1912*0x1+-0x1*-0x1f7b+-0x13*0x53)+_0x3e198c:_0x3e198c,_0x294889++%(0x6be*0x2+0x34f*0x1+-0x10c7))?_0x2f2622+=_0x4f7c14['charCodeAt'](_0x30f05+(0xb*0x2a+0x2*-0x628+0xa8c*0x1))-(0x242+0x1435+-0x166d)!==0x55e+-0x4bc*-0x1+-0xa1a?String['fromCharCode'](0xd58+-0x630+-0x1*0x629&_0x30895e>>(-(0x1d93+-0x4*0x128+-0x18f1)*_0x294889&0x2247+-0x5ea*0x5+0x4af*-0x1)):_0x294889:-0x1787+0x2255+-0xace){_0x3e198c=_0x28505f['indexOf'](_0x3e198c);}for(let _0x5e1603=-0x7ce+0x3*-0x8e+0x978,_0x407efe=_0x2f2622['length'];_0x5e1603<_0x407efe;_0x5e1603++){_0x51d6a1+='%'+('00'+_0x2f2622['charCodeAt'](_0x5e1603)['toString'](0xb22+-0x3a9*-0x6+-0x2108))['slice'](-(-0x2a+0xbc2+-0xb96));}return decodeURIComponent(_0x51d6a1);};_0x3011['gYHECJ']=_0x29f768,_0x3011['slgwoz']={},_0x3011['hxmHnO']=!![];}const _0x95c393=_0xd2f9b0[0x13*0x19b+-0x1d1e*-0x1+-0x1*0x3b9f],_0xf23060=_0x3f2287+_0x95c393,_0x75eeb7=_0x3011['slgwoz'][_0xf23060];if(!_0x75eeb7){const _0x3c5357=function(_0x23d6bd){this['klRSoF']=_0x23d6bd,this['yaysra']=[0x6ad*0x5+-0x16c4*0x1+-0xe*0xc2,0xd3*-0x25+0x4*0x5dc+0x70f,0x474+-0x2*-0x68+-0x544],this['KHKHYD']=function(){return'newState';},this['jxMuxA']='\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*',this['OnBTME']='[\x27|\x22].+[\x27|\x22];?\x20*}';};_0x3c5357['prototype']['hdSmbZ']=function(){const _0x5bbb48=new RegExp(this['jxMuxA']+this['OnBTME']),_0x2a8c98=_0x5bbb48['test'](this['KHKHYD']['toString']())?--this['yaysra'][-0x179e+0x2ef+0x14b0]:--this['yaysra'][0x12a9+-0x92b*-0x3+-0x2e2a];return this['nETrpG'](_0x2a8c98);},_0x3c5357['prototype']['nETrpG']=function(_0x15d883){if(!Boolean(~_0x15d883))return _0x15d883;return this['AMtMNn'](this['klRSoF']);},_0x3c5357['prototype']['AMtMNn']=function(_0x541926){for(let _0x57801d=0x2*0x407+0x1da9+0x25b7*-0x1,_0x504c5f=this['yaysra']['length'];_0x57801d<_0x504c5f;_0x57801d++){this['yaysra']['push'](Math['round'](Math['random']())),_0x504c5f=this['yaysra']['length'];}return _0x541926(this['yaysra'][-0x2051+0x12d6+-0x11*-0xcb]);},new _0x3c5357(_0x3011)['hdSmbZ'](),_0x17ca60=_0x3011['gYHECJ'](_0x17ca60),_0x3011['slgwoz'][_0xf23060]=_0x17ca60;}else _0x17ca60=_0x75eeb7;return _0x17ca60;}_0xc5e1c0();import _0x2f7cd5 from'fs';import _0x3e0a79 from'path';import{ASSETS_DIR,ASSETS_INDEX_JSON,ASSETS_INDEX_MD}from'../paths.js';let cachedIndex=null;function walkDir(_0x50ae8b){const _0x3d5201=[];function _0x467717(_0xb2349b){const _0x56abb7=_0x3011,_0x13dc67=_0x3011;let _0x41ec8b;try{_0x41ec8b=_0x2f7cd5[_0x56abb7(0x1ef)+'c'](_0xb2349b,{'withFileTypes':!![]});}catch{return;}for(const _0x20361b of _0x41ec8b){const _0x586df7=_0x3e0a79[_0x13dc67(0x1f8)](_0xb2349b,_0x20361b['name']);if(_0x20361b[_0x13dc67(0x218)+'y']())_0x467717(_0x586df7);else{if(_0x20361b[_0x13dc67(0x206)]()){if(_0xb2349b===_0x50ae8b&&(_0x20361b[_0x56abb7(0x20a)]===_0x56abb7(0x21a)||_0x20361b['name']===_0x13dc67(0x1fb)))continue;_0x3d5201[_0x56abb7(0x213)]({'name':_0x20361b[_0x13dc67(0x20a)],'path':_0x586df7,'relativePath':_0x3e0a79[_0x56abb7(0x21e)](_0x50ae8b,_0x586df7)});}}}}return _0x467717(_0x50ae8b),_0x3d5201;}function descriptionFromFilename(_0x13e779,_0x3a70e2){const _0x3cdcef=_0x3011,_0x2d5ace=_0x3011,_0x4816c0=_0x13e779['replace'](/\.[^.]+$/,''),_0x4d163a=_0x4816c0[_0x3cdcef(0x203)](/[-_]/g,'\x20')['trim'](),_0xd4b91=_0x3a70e2?_0x3a70e2['replace'](/[-_]/g,'\x20')['replace'](/\b\w/g,_0x1ea5f6=>_0x1ea5f6[_0x3cdcef(0x212)+'e']())+':\x20':'',_0x3db624=_0x4d163a['replace'](/\b\w/g,_0xa77fa6=>_0xa77fa6[_0x2d5ace(0x212)+'e']());return _0xd4b91?''+_0xd4b91+_0x3db624:_0x3db624;}function categorize(_0x4c4b7b){const _0x465370=_0x3011,_0x49edb1=_0x3011,_0x57261f=_0x4c4b7b[_0x465370(0x21d)](_0x3e0a79['sep']);if(_0x57261f[_0x465370(0x1fd)]>-0x45f*-0x2+-0x2289+0xd*0x1fc)return _0x57261f[-0xa9c*0x1+0x5e3*0x4+0x2*-0x678];const _0x4c0b5e=_0x57261f[-0x1912*0x1+-0x1*-0x1f7b+-0x3*0x223][_0x49edb1(0x20c)+'e']();if(_0x4c0b5e[_0x49edb1(0x1fa)](_0x49edb1(0x1e1)))return _0x465370(0x1ed);return _0x49edb1(0x207);}export function scanAssets(){const _0x1a2c07=_0x3011,_0x6ef3d=_0x3011;if(!_0x2f7cd5[_0x1a2c07(0x1e0)](ASSETS_DIR)){const _0x30adb0={'lastScan':new Date()[_0x6ef3d(0x217)+'g'](),'assets':[]};return cachedIndex=_0x30adb0,_0x30adb0;}if(_0x2f7cd5[_0x6ef3d(0x1e0)](ASSETS_INDEX_JSON))try{const _0x28462a=JSON[_0x6ef3d(0x1f2)](_0x2f7cd5[_0x1a2c07(0x1df)+'nc'](ASSETS_INDEX_JSON,_0x6ef3d(0x1e9))),_0x431a1e=_0x2f7cd5['statSync'](ASSETS_DIR),_0x2748d8=new Date(_0x28462a[_0x6ef3d(0x1e3)])[_0x1a2c07(0x204)]();let _0x15ee43=_0x431a1e[_0x1a2c07(0x1f0)];try{const _0x12dcac=_0x2f7cd5[_0x1a2c07(0x1ef)+'c'](ASSETS_DIR,{'withFileTypes':!![]});for(const _0x3344e0 of _0x12dcac){if(_0x3344e0[_0x1a2c07(0x218)+'y']()){const _0x93d1d2=_0x2f7cd5['statSync'](_0x3e0a79['resolve'](ASSETS_DIR,_0x3344e0[_0x1a2c07(0x20a)]));if(_0x93d1d2[_0x1a2c07(0x1f0)]>_0x15ee43)_0x15ee43=_0x93d1d2[_0x6ef3d(0x1f0)];}}}catch{}if(_0x15ee43<=_0x2748d8)return cachedIndex=_0x28462a,_0x28462a;}catch{}const _0x33df1d=walkDir(ASSETS_DIR),_0x3418d6=[];for(const _0x783ee2 of _0x33df1d){try{const _0x22b678=_0x2f7cd5[_0x6ef3d(0x1f6)](_0x783ee2['path']),_0x467680=categorize(_0x783ee2[_0x1a2c07(0x1f3)+'th']);_0x3418d6[_0x1a2c07(0x213)]({'path':_0x783ee2['relativePa'+'th'],'absolutePath':_0x783ee2['path'],'category':_0x467680,'filename':_0x783ee2[_0x6ef3d(0x20a)],'ext':_0x3e0a79[_0x1a2c07(0x1f5)](_0x783ee2[_0x6ef3d(0x20a)]),'size':_0x22b678['size'],'modified':new Date(_0x22b678[_0x1a2c07(0x1f0)])[_0x6ef3d(0x217)+'g'](),'description':descriptionFromFilename(_0x783ee2[_0x1a2c07(0x20a)],_0x467680)});}catch{}}_0x3418d6[_0x6ef3d(0x1e4)]((_0x5141f4,_0x21d2d3)=>_0x5141f4[_0x1a2c07(0x20f)]['localeComp'+'are'](_0x21d2d3['category'])||_0x5141f4['filename'][_0x6ef3d(0x211)+_0x1a2c07(0x1e5)](_0x21d2d3[_0x6ef3d(0x1e8)]));const _0x2aa65a={'lastScan':new Date()['toISOStrin'+'g'](),'assets':_0x3418d6};_0x2f7cd5[_0x1a2c07(0x21c)+_0x1a2c07(0x1f4)](ASSETS_INDEX_JSON,JSON['stringify'](_0x2aa65a,null,0x6be*0x2+0x34f*0x1+-0x10c9));const _0x351fd0=generateIndexMd(_0x2aa65a);return _0x2f7cd5[_0x1a2c07(0x21c)+_0x6ef3d(0x1f4)](ASSETS_INDEX_MD,_0x351fd0),cachedIndex=_0x2aa65a,_0x2aa65a;}function _0x4897(){const _0x425d03=['mtiYmtz6rMvPs0O','C2LNBMf0DxjLCW','lYOQicG','CMvHzgrPCLn5BG','BxrPBwvnCW','igzPBgvZlca','CgfYC2u','CMvSyxrPDMvqyq','Ew5J','zxH0BMfTzq','C3rHDfn5BMm','iYmGww91CIbbCW','CMvZB2X2zq','z2v0','Aw5JBhvKzxm','su5ervGUBwq','C29Tzq','BgvUz3rO','nZC0ndmYuxbgyMfU','mte5nJm3AxzVqNjm','C2vHCMnO','kcGOlISPkYKRkq','yxnZzxrZ','CMvWBgfJzq','z2v0vgLTzq','BwfW','AxngAwXL','BwLZyW','ig1VCMuP','AM9PBG','BMfTzq','zMLSDgvY','Dg9mB3DLCKnHCW','C2XPy2u','mZm4A0fcrwje','y2f0zwDVCNK','Dg9tDhjPBMC','Bg9JywXLq29TCa','Dg9vChbLCKnHCW','ChvZAa','y29UC3rYDwn0BW','CMvKDwnL','C3nLDhmVksdIGjqG','Dg9ju09tDhjPBG','AxneAxjLy3rVCG','C2L6zq','su5ervGUANnVBG','mta4nZjsC3blu0m','D3jPDgvgAwXLuW','C3bSAxq','CMvSyxrPDMu','C2v0CYaOFI8Uyq','mty4nJe1tgXOtM5u','A2v5CW','lsaQkG','Dg9gAxHLza','mJmYmZi2ngjhB0LryG','CMvHzezPBgvtEq','zxHPC3rZu3LUyW','C2LNBMf0DxjL','ie1c','BgfZDfnJyw4','C29YDa','yxjL','ndu3mJi3oxjPENn2zW','lcaUlI4GkcS','zMLSzw5HBwu','DxrMltG','nZzPwgvLDgu','mJbrCvnlEgi'];_0x4897=function(){return _0x425d03;};return _0x4897();}export function loadAssetIndex(){const _0x3867ea=_0x3011,_0x586558=_0x3011;if(cachedIndex)return cachedIndex;if(_0x2f7cd5['existsSync'](ASSETS_INDEX_JSON))try{return cachedIndex=JSON[_0x3867ea(0x1f2)](_0x2f7cd5[_0x3867ea(0x1df)+'nc'](ASSETS_INDEX_JSON,_0x586558(0x1e9))),cachedIndex;}catch{}return scanAssets();}export function getAssetIndexMd(){const _0x34aeb5=_0x3011,_0x4c41ac=_0x3011;if(_0x2f7cd5['existsSync'](ASSETS_INDEX_MD))return _0x2f7cd5[_0x34aeb5(0x1df)+'nc'](ASSETS_INDEX_MD,_0x34aeb5(0x1e9));return'';}export function findAssetsByCategory(_0x5ae9ac){const _0x15eada=_0x3011,_0x2d3393=_0x3011,_0xc95d3a=loadAssetIndex();return _0xc95d3a['assets'][_0x15eada(0x20b)](_0x199680=>_0x199680[_0x2d3393(0x20f)]===_0x5ae9ac);}export function findAssetsByKeyword(_0x39857a){const _0x3ae7f8=_0x3011,_0x298f41=_0x3011,_0x53e332=loadAssetIndex(),_0x3a33ff=_0x39857a[_0x3ae7f8(0x205)](_0x3c0a02=>_0x3c0a02[_0x298f41(0x20c)+'e']());return _0x53e332[_0x298f41(0x202)][_0x3ae7f8(0x20b)](_0x23c87e=>_0x3a33ff[_0x3ae7f8(0x1fc)](_0x4c7ec8=>_0x23c87e[_0x298f41(0x1e8)]['toLowerCas'+'e']()['includes'](_0x4c7ec8)||_0x23c87e[_0x3ae7f8(0x20f)]['toLowerCas'+'e']()[_0x3ae7f8(0x1fa)](_0x4c7ec8)||_0x23c87e['descriptio'+'n'][_0x298f41(0x20c)+'e']()['includes'](_0x4c7ec8)));}function generateIndexMd(_0x5916b0){const _0x5384c8=_0x3011,_0x29c07a=_0x3011,_0x83f55d=new Date()[_0x5384c8(0x217)+'g']()[_0x5384c8(0x20d)](0xb*0x2a+0x2*-0x628+0xa82*0x1,0x242+0x1435+-0x166d),_0x46ad63=[_0x5384c8(0x1f7)+_0x29c07a(0x1d9)+'lvin-bot/a'+_0x5384c8(0x216)+_0x83f55d+'\x0a'],_0x1e9516=new Map();for(const _0x3f2287 of _0x5916b0[_0x29c07a(0x202)]){const _0x99f7cf=_0x1e9516[_0x29c07a(0x1f9)](_0x3f2287[_0x5384c8(0x20f)])||[];_0x99f7cf['push'](_0x3f2287),_0x1e9516['set'](_0x3f2287[_0x5384c8(0x20f)],_0x99f7cf);}const _0x127307=[..._0x1e9516[_0x29c07a(0x1db)]()][_0x29c07a(0x1e4)]();for(const _0xd2f9b0 of _0x127307){const _0x17ca60=_0x1e9516[_0x5384c8(0x1f9)](_0xd2f9b0),_0x29f768=_0x17ca60['map'](_0xf23060=>_0xf23060[_0x5384c8(0x1e8)]),_0x95c393=_0x29f768[_0x29c07a(0x1fd)]>0x55e+-0x4bc*-0x1+-0xa14?_0x29f768[_0x5384c8(0x20d)](0xd58+-0x630+-0x2*0x394,0x1d93+-0x4*0x128+-0x18ee)[_0x29c07a(0x209)](',\x20')+(_0x5384c8(0x1e7)+(_0x29f768['length']-(0x2247+-0x5ea*0x5+0x12c*-0x4))+_0x5384c8(0x208)):_0x29f768['join'](',\x20');_0x46ad63[_0x5384c8(0x213)](_0x5384c8(0x1dc)+_0xd2f9b0+_0x29c07a(0x1ee)+_0x17ca60[_0x29c07a(0x1fd)]+'):\x20'+_0x95c393);}const _0x41bc08=_0x5916b0[_0x5384c8(0x202)][_0x5384c8(0x215)]((_0x75eeb7,_0x20956c)=>_0x75eeb7+_0x20956c[_0x29c07a(0x219)],-0x1787+0x2255+-0xace),_0x23a76f=(_0x41bc08/(-0x664ac+0xe*-0x18e9+0x17c16a))[_0x29c07a(0x1dd)](0xb22+-0x3a9*-0x6+-0x2117);return _0x46ad63['push']('\x0aTotal:\x20'+_0x5916b0[_0x5384c8(0x202)][_0x5384c8(0x1fd)]+_0x29c07a(0x1f1)+_0x23a76f+_0x5384c8(0x1e2)),_0x46ad63[_0x29c07a(0x209)]('\x0a')+'\x0a';}
|