miladyai 2.0.0-alpha.27
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/dist/_virtual/_rolldown/runtime.js +7 -0
- package/dist/actions/emote.js +64 -0
- package/dist/actions/restart.js +81 -0
- package/dist/actions/send-message.js +152 -0
- package/dist/agent-admin-routes.js +82 -0
- package/dist/agent-lifecycle-routes.js +79 -0
- package/dist/agent-transfer-routes.js +102 -0
- package/dist/api/agent-admin-routes.js +82 -0
- package/dist/api/agent-lifecycle-routes.js +79 -0
- package/dist/api/agent-transfer-routes.js +102 -0
- package/dist/api/apps-hyperscape-routes.js +58 -0
- package/dist/api/apps-routes.js +114 -0
- package/dist/api/auth-routes.js +56 -0
- package/dist/api/autonomy-routes.js +44 -0
- package/dist/api/bug-report-routes.js +111 -0
- package/dist/api/character-routes.js +195 -0
- package/dist/api/cloud-routes.js +330 -0
- package/dist/api/cloud-status-routes.js +155 -0
- package/dist/api/compat-utils.js +111 -0
- package/dist/api/database.js +735 -0
- package/dist/api/diagnostics-routes.js +205 -0
- package/dist/api/drop-service.js +134 -0
- package/dist/api/early-logs.js +86 -0
- package/dist/api/http-helpers.js +131 -0
- package/dist/api/knowledge-routes.js +534 -0
- package/dist/api/memory-bounds.js +71 -0
- package/dist/api/models-routes.js +28 -0
- package/dist/api/og-tracker.js +36 -0
- package/dist/api/permissions-routes.js +109 -0
- package/dist/api/plugin-validation.js +198 -0
- package/dist/api/provider-switch-config.js +41 -0
- package/dist/api/registry-routes.js +86 -0
- package/dist/api/registry-service.js +164 -0
- package/dist/api/sandbox-routes.js +1112 -0
- package/dist/api/server.js +7949 -0
- package/dist/api/subscription-routes.js +172 -0
- package/dist/api/terminal-run-limits.js +24 -0
- package/dist/api/training-routes.js +158 -0
- package/dist/api/trajectory-routes.js +300 -0
- package/dist/api/trigger-routes.js +246 -0
- package/dist/api/twitter-verify.js +134 -0
- package/dist/api/tx-service.js +108 -0
- package/dist/api/wallet-routes.js +266 -0
- package/dist/api/wallet.js +568 -0
- package/dist/api/whatsapp-routes.js +182 -0
- package/dist/api/zip-utils.js +109 -0
- package/dist/apps-hyperscape-routes.js +58 -0
- package/dist/apps-routes.js +114 -0
- package/dist/ascii.js +20 -0
- package/dist/auth/anthropic.js +44 -0
- package/dist/auth/apply-stealth.js +41 -0
- package/dist/auth/claude-code-stealth.js +78 -0
- package/dist/auth/credentials.js +156 -0
- package/dist/auth/index.js +5 -0
- package/dist/auth/openai-codex.js +66 -0
- package/dist/auth/types.js +9 -0
- package/dist/auth-routes.js +56 -0
- package/dist/autonomy-routes.js +44 -0
- package/dist/bug-report-routes.js +111 -0
- package/dist/build-info.json +6 -0
- package/dist/character-routes.js +195 -0
- package/dist/cli/argv.js +63 -0
- package/dist/cli/banner.js +34 -0
- package/dist/cli/cli-name.js +21 -0
- package/dist/cli/cli-utils.js +16 -0
- package/dist/cli/git-commit.js +78 -0
- package/dist/cli/parse-duration.js +15 -0
- package/dist/cli/plugins-cli.js +590 -0
- package/dist/cli/profile-utils.js +9 -0
- package/dist/cli/profile.js +95 -0
- package/dist/cli/program/build-program.js +17 -0
- package/dist/cli/program/command-registry.js +23 -0
- package/dist/cli/program/help.js +47 -0
- package/dist/cli/program/preaction.js +33 -0
- package/dist/cli/program/register.config.js +106 -0
- package/dist/cli/program/register.configure.js +20 -0
- package/dist/cli/program/register.dashboard.js +124 -0
- package/dist/cli/program/register.models.js +23 -0
- package/dist/cli/program/register.setup.js +36 -0
- package/dist/cli/program/register.start.js +22 -0
- package/dist/cli/program/register.subclis.js +70 -0
- package/dist/cli/program/register.tui.js +163 -0
- package/dist/cli/program/register.update.js +154 -0
- package/dist/cli/program.js +3 -0
- package/dist/cli/run-main.js +37 -0
- package/dist/cli/version.js +7 -0
- package/dist/cloud/validate-url.js +93 -0
- package/dist/cloud-routes.js +330 -0
- package/dist/cloud-status-routes.js +155 -0
- package/dist/compat-utils.js +111 -0
- package/dist/config/config.js +69 -0
- package/dist/config/env-vars.js +19 -0
- package/dist/config/includes.js +121 -0
- package/dist/config/object-utils.js +7 -0
- package/dist/config/paths.js +38 -0
- package/dist/config/plugin-auto-enable.js +231 -0
- package/dist/config/schema.js +864 -0
- package/dist/config/telegram-custom-commands.js +76 -0
- package/dist/config/zod-schema.agent-runtime.js +519 -0
- package/dist/config/zod-schema.core.js +538 -0
- package/dist/config/zod-schema.hooks.js +103 -0
- package/dist/config/zod-schema.js +488 -0
- package/dist/config/zod-schema.providers-core.js +785 -0
- package/dist/config/zod-schema.session.js +73 -0
- package/dist/core-plugins.js +37 -0
- package/dist/custom-actions.js +250 -0
- package/dist/database.js +735 -0
- package/dist/diagnostics/integration-observability.js +57 -0
- package/dist/diagnostics-routes.js +205 -0
- package/dist/drop-service.js +134 -0
- package/dist/early-logs.js +24 -0
- package/dist/eliza.js +2061 -0
- package/dist/emotes/catalog.js +271 -0
- package/dist/entry.js +40 -0
- package/dist/hooks/discovery.js +167 -0
- package/dist/hooks/eligibility.js +64 -0
- package/dist/hooks/index.js +4 -0
- package/dist/hooks/loader.js +147 -0
- package/dist/hooks/registry.js +55 -0
- package/dist/http-helpers.js +131 -0
- package/dist/index.js +49 -0
- package/dist/knowledge-routes.js +534 -0
- package/dist/memory-bounds.js +71 -0
- package/dist/milady-plugin.js +90 -0
- package/dist/models-routes.js +28 -0
- package/dist/onboarding-names.js +78 -0
- package/dist/onboarding-presets.js +922 -0
- package/dist/package.json +1 -0
- package/dist/permissions-routes.js +109 -0
- package/dist/plugin-validation.js +107 -0
- package/dist/plugins/whatsapp/actions.js +91 -0
- package/dist/plugins/whatsapp/index.js +16 -0
- package/dist/plugins/whatsapp/service.js +270 -0
- package/dist/provider-switch-config.js +41 -0
- package/dist/providers/admin-trust.js +46 -0
- package/dist/providers/autonomous-state.js +101 -0
- package/dist/providers/session-bridge.js +86 -0
- package/dist/providers/session-utils.js +36 -0
- package/dist/providers/simple-mode.js +50 -0
- package/dist/providers/ui-catalog.js +15 -0
- package/dist/providers/workspace-provider.js +93 -0
- package/dist/providers/workspace.js +348 -0
- package/dist/registry-routes.js +86 -0
- package/dist/registry-service.js +164 -0
- package/dist/restart.js +40 -0
- package/dist/runtime/core-plugins.js +37 -0
- package/dist/runtime/custom-actions.js +250 -0
- package/dist/runtime/eliza.js +2061 -0
- package/dist/runtime/embedding-manager-support.js +185 -0
- package/dist/runtime/embedding-manager.js +193 -0
- package/dist/runtime/embedding-presets.js +54 -0
- package/dist/runtime/embedding-state.js +8 -0
- package/dist/runtime/milady-plugin.js +90 -0
- package/dist/runtime/onboarding-names.js +78 -0
- package/dist/runtime/restart.js +40 -0
- package/dist/runtime/version.js +7 -0
- package/dist/sandbox-routes.js +1112 -0
- package/dist/security/audit-log.js +149 -0
- package/dist/security/network-policy.js +70 -0
- package/dist/server.js +7949 -0
- package/dist/services/agent-export.js +559 -0
- package/dist/services/app-manager.js +389 -0
- package/dist/services/browser-capture.js +86 -0
- package/dist/services/fallback-training-service.js +128 -0
- package/dist/services/mcp-marketplace.js +134 -0
- package/dist/services/plugin-installer.js +396 -0
- package/dist/services/plugin-manager-types.js +15 -0
- package/dist/services/registry-client-app-meta.js +144 -0
- package/dist/services/registry-client-endpoints.js +166 -0
- package/dist/services/registry-client-local.js +271 -0
- package/dist/services/registry-client-network.js +93 -0
- package/dist/services/registry-client-queries.js +70 -0
- package/dist/services/registry-client.js +157 -0
- package/dist/services/sandbox-engine.js +511 -0
- package/dist/services/sandbox-manager.js +297 -0
- package/dist/services/self-updater.js +175 -0
- package/dist/services/skill-catalog-client.js +119 -0
- package/dist/services/skill-marketplace.js +521 -0
- package/dist/services/stream-manager.js +236 -0
- package/dist/services/update-checker.js +121 -0
- package/dist/services/update-notifier.js +29 -0
- package/dist/services/version-compat.js +78 -0
- package/dist/services/whatsapp-pairing.js +196 -0
- package/dist/shared/ui-catalog-prompt.js +728 -0
- package/dist/subscription-routes.js +172 -0
- package/dist/terminal/links.js +19 -0
- package/dist/terminal/palette.js +14 -0
- package/dist/terminal/theme.js +25 -0
- package/dist/terminal-run-limits.js +24 -0
- package/dist/training-routes.js +158 -0
- package/dist/trajectory-routes.js +300 -0
- package/dist/trigger-routes.js +246 -0
- package/dist/triggers/action.js +218 -0
- package/dist/triggers/runtime.js +281 -0
- package/dist/triggers/scheduling.js +295 -0
- package/dist/triggers/types.js +5 -0
- package/dist/tui/components/assistant-message.js +76 -0
- package/dist/tui/components/chat-editor.js +34 -0
- package/dist/tui/components/embeddings-overlay.js +46 -0
- package/dist/tui/components/footer.js +60 -0
- package/dist/tui/components/index.js +15 -0
- package/dist/tui/components/modal-frame.js +45 -0
- package/dist/tui/components/modal-style.js +15 -0
- package/dist/tui/components/model-selector.js +70 -0
- package/dist/tui/components/pinned-chat-layout.js +46 -0
- package/dist/tui/components/plugins-endpoints-tab.js +196 -0
- package/dist/tui/components/plugins-installed-tab-view.js +69 -0
- package/dist/tui/components/plugins-installed-tab.js +319 -0
- package/dist/tui/components/plugins-overlay-catalog.js +81 -0
- package/dist/tui/components/plugins-overlay-data-api.js +21 -0
- package/dist/tui/components/plugins-overlay-data-shared.js +20 -0
- package/dist/tui/components/plugins-overlay-data.js +323 -0
- package/dist/tui/components/plugins-overlay.js +117 -0
- package/dist/tui/components/plugins-store-tab.js +148 -0
- package/dist/tui/components/settings-overlay.js +61 -0
- package/dist/tui/components/status-bar.js +64 -0
- package/dist/tui/components/tool-execution.js +68 -0
- package/dist/tui/components/user-message.js +22 -0
- package/dist/tui/eliza-tui-bridge.js +606 -0
- package/dist/tui/index.js +370 -0
- package/dist/tui/modal-presets.js +33 -0
- package/dist/tui/model-spec.js +46 -0
- package/dist/tui/sse-parser.js +78 -0
- package/dist/tui/theme.js +110 -0
- package/dist/tui/titlebar-spinner.js +62 -0
- package/dist/tui/tui-app.js +311 -0
- package/dist/tui/ws-client.js +215 -0
- package/dist/twitter-verify.js +134 -0
- package/dist/tx-service.js +108 -0
- package/dist/utils/exec-safety.js +17 -0
- package/dist/utils/globals.js +20 -0
- package/dist/utils/milady-root.js +61 -0
- package/dist/utils/number-parsing.js +37 -0
- package/dist/version-resolver.js +37 -0
- package/dist/version.js +7 -0
- package/dist/wallet-routes.js +266 -0
- package/dist/wallet.js +568 -0
- package/dist/whatsapp-routes.js +182 -0
- package/dist/zip-utils.js +109 -0
- package/milady.mjs +14 -0
- package/package.json +111 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { logger } from "@elizaos/core";
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
|
|
4
|
+
//#region src/services/stream-manager.ts
|
|
5
|
+
/**
|
|
6
|
+
* Stream Manager — macOS-compatible RTMP streaming via FFmpeg.
|
|
7
|
+
*
|
|
8
|
+
* Supports three input modes:
|
|
9
|
+
* - "pipe": Receives JPEG frames via writeFrame() → FFmpeg stdin (image2pipe).
|
|
10
|
+
* Used for streaming Electron window contents captured with capturePage().
|
|
11
|
+
* - "avfoundation": macOS screen capture via avfoundation device.
|
|
12
|
+
* - "testsrc": Solid color test pattern (default fallback).
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
* import { streamManager } from "./services/stream-manager";
|
|
16
|
+
* await streamManager.start({ rtmpUrl, rtmpKey, inputMode: "pipe" });
|
|
17
|
+
* streamManager.writeFrame(jpegBuffer); // called from frame capture
|
|
18
|
+
* await streamManager.stop();
|
|
19
|
+
*
|
|
20
|
+
* @module services/stream-manager
|
|
21
|
+
*/
|
|
22
|
+
const TAG = "[StreamManager]";
|
|
23
|
+
var StreamManager = class {
|
|
24
|
+
constructor() {
|
|
25
|
+
this.ffmpeg = null;
|
|
26
|
+
this._running = false;
|
|
27
|
+
this.startedAt = null;
|
|
28
|
+
this._frameCount = 0;
|
|
29
|
+
}
|
|
30
|
+
isRunning() {
|
|
31
|
+
return this._running;
|
|
32
|
+
}
|
|
33
|
+
getUptime() {
|
|
34
|
+
if (!this.startedAt) return 0;
|
|
35
|
+
return Math.floor((Date.now() - this.startedAt) / 1e3);
|
|
36
|
+
}
|
|
37
|
+
getHealth() {
|
|
38
|
+
return {
|
|
39
|
+
running: this._running,
|
|
40
|
+
ffmpegAlive: this.ffmpeg !== null && this.ffmpeg.exitCode === null && !this.ffmpeg.killed,
|
|
41
|
+
uptime: this.getUptime(),
|
|
42
|
+
frameCount: this._frameCount
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Write a JPEG frame to FFmpeg's stdin (only works in "pipe" mode).
|
|
47
|
+
* Returns true if the frame was accepted.
|
|
48
|
+
*/
|
|
49
|
+
writeFrame(jpegData) {
|
|
50
|
+
if (!this._running || !this.ffmpeg || !this.ffmpeg.stdin) return false;
|
|
51
|
+
if (this.ffmpeg.killed || this.ffmpeg.exitCode !== null) return false;
|
|
52
|
+
try {
|
|
53
|
+
this.ffmpeg.stdin.write(jpegData);
|
|
54
|
+
this._frameCount++;
|
|
55
|
+
if (this._frameCount % 150 === 0) logger.info(`${TAG} Piped ${this._frameCount} frames to FFmpeg`);
|
|
56
|
+
return true;
|
|
57
|
+
} catch {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async start(config) {
|
|
62
|
+
if (this._running) {
|
|
63
|
+
logger.warn(`${TAG} Already running — stop first`);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
this._frameCount = 0;
|
|
67
|
+
const resolution = config.resolution || "1280x720";
|
|
68
|
+
const bitrate = config.bitrate || "2500k";
|
|
69
|
+
const framerate = config.framerate || 15;
|
|
70
|
+
const rtmpTarget = `${config.rtmpUrl}/${config.rtmpKey}`;
|
|
71
|
+
const bufsize = `${parseInt(bitrate, 10) * 2}k`;
|
|
72
|
+
const mode = config.inputMode || "testsrc";
|
|
73
|
+
const inputArgs = this.buildInputArgs(config, resolution, framerate);
|
|
74
|
+
const isPipe = mode === "pipe";
|
|
75
|
+
const isScreenCapture = mode === "avfoundation" || mode === "screen";
|
|
76
|
+
const ffmpegArgs = [
|
|
77
|
+
"-thread_queue_size",
|
|
78
|
+
"512",
|
|
79
|
+
...inputArgs,
|
|
80
|
+
"-f",
|
|
81
|
+
"lavfi",
|
|
82
|
+
"-i",
|
|
83
|
+
"anullsrc=channel_layout=stereo:sample_rate=44100",
|
|
84
|
+
...isScreenCapture ? ["-vf", `scale=${resolution.replace("x", ":")}:flags=fast_bilinear`] : [],
|
|
85
|
+
...process.platform === "darwin" ? [
|
|
86
|
+
"-c:v",
|
|
87
|
+
"h264_videotoolbox",
|
|
88
|
+
"-realtime",
|
|
89
|
+
"1",
|
|
90
|
+
"-b:v",
|
|
91
|
+
bitrate,
|
|
92
|
+
"-maxrate",
|
|
93
|
+
bitrate,
|
|
94
|
+
"-bufsize",
|
|
95
|
+
bufsize
|
|
96
|
+
] : [
|
|
97
|
+
"-c:v",
|
|
98
|
+
"libx264",
|
|
99
|
+
"-preset",
|
|
100
|
+
"veryfast",
|
|
101
|
+
"-tune",
|
|
102
|
+
"zerolatency",
|
|
103
|
+
"-b:v",
|
|
104
|
+
bitrate,
|
|
105
|
+
"-maxrate",
|
|
106
|
+
bitrate,
|
|
107
|
+
"-bufsize",
|
|
108
|
+
bufsize
|
|
109
|
+
],
|
|
110
|
+
"-s",
|
|
111
|
+
resolution,
|
|
112
|
+
"-pix_fmt",
|
|
113
|
+
"yuv420p",
|
|
114
|
+
"-g",
|
|
115
|
+
"60",
|
|
116
|
+
"-c:a",
|
|
117
|
+
"aac",
|
|
118
|
+
"-b:a",
|
|
119
|
+
"128k",
|
|
120
|
+
"-f",
|
|
121
|
+
"flv",
|
|
122
|
+
rtmpTarget
|
|
123
|
+
];
|
|
124
|
+
logger.info(`${TAG} Starting FFmpeg RTMP stream (mode=${mode}) to ${config.rtmpUrl}`);
|
|
125
|
+
logger.info(`${TAG} Resolution: ${resolution}, Bitrate: ${bitrate}, FPS: ${framerate}`);
|
|
126
|
+
this.ffmpeg = spawn("ffmpeg", ["-y", ...ffmpegArgs], { stdio: [
|
|
127
|
+
isPipe ? "pipe" : "ignore",
|
|
128
|
+
"pipe",
|
|
129
|
+
"pipe"
|
|
130
|
+
] });
|
|
131
|
+
this.ffmpeg.stderr?.on("data", (chunk) => {
|
|
132
|
+
const line = chunk.toString().trim();
|
|
133
|
+
if (line) console.log(`[FFmpeg] ${line}`);
|
|
134
|
+
});
|
|
135
|
+
this.ffmpeg.on("exit", (code, signal) => {
|
|
136
|
+
if (this._running) {
|
|
137
|
+
logger.warn(`${TAG} FFmpeg exited unexpectedly (code=${code}, signal=${signal})`);
|
|
138
|
+
this._running = false;
|
|
139
|
+
this.startedAt = null;
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
if (isPipe && this.ffmpeg.stdin) this.ffmpeg.stdin.on("error", (err) => {
|
|
143
|
+
logger.warn(`${TAG} FFmpeg stdin error: ${err.message}`);
|
|
144
|
+
});
|
|
145
|
+
await new Promise((r) => setTimeout(r, 1500));
|
|
146
|
+
if (this.ffmpeg.exitCode !== null) {
|
|
147
|
+
const exitCode = this.ffmpeg.exitCode;
|
|
148
|
+
this.ffmpeg = null;
|
|
149
|
+
throw new Error(`${TAG} FFmpeg exited immediately with code ${exitCode}`);
|
|
150
|
+
}
|
|
151
|
+
this._running = true;
|
|
152
|
+
this.startedAt = Date.now();
|
|
153
|
+
logger.info(`${TAG} FFmpeg streaming to RTMP — stream should be live`);
|
|
154
|
+
}
|
|
155
|
+
async stop() {
|
|
156
|
+
const uptime = this.getUptime();
|
|
157
|
+
if (this.ffmpeg && !this.ffmpeg.killed && this.ffmpeg.exitCode === null) {
|
|
158
|
+
const ffmpegProc = this.ffmpeg;
|
|
159
|
+
if (ffmpegProc.stdin) try {
|
|
160
|
+
ffmpegProc.stdin.end();
|
|
161
|
+
} catch {}
|
|
162
|
+
ffmpegProc.kill("SIGTERM");
|
|
163
|
+
await Promise.race([new Promise((resolve) => ffmpegProc.on("exit", resolve)), new Promise((resolve) => setTimeout(resolve, 3e3))]);
|
|
164
|
+
if (ffmpegProc.exitCode === null) ffmpegProc.kill("SIGKILL");
|
|
165
|
+
}
|
|
166
|
+
this.ffmpeg = null;
|
|
167
|
+
this._running = false;
|
|
168
|
+
this.startedAt = null;
|
|
169
|
+
this._frameCount = 0;
|
|
170
|
+
logger.info(`${TAG} Stream stopped (uptime: ${uptime}s, frames: ${this._frameCount})`);
|
|
171
|
+
return { uptime };
|
|
172
|
+
}
|
|
173
|
+
buildInputArgs(config, resolution, framerate) {
|
|
174
|
+
switch (config.inputMode || "testsrc") {
|
|
175
|
+
case "pipe": return [
|
|
176
|
+
"-probesize",
|
|
177
|
+
"32",
|
|
178
|
+
"-analyzeduration",
|
|
179
|
+
"0",
|
|
180
|
+
"-f",
|
|
181
|
+
"image2pipe",
|
|
182
|
+
"-c:v",
|
|
183
|
+
"mjpeg",
|
|
184
|
+
"-framerate",
|
|
185
|
+
String(framerate),
|
|
186
|
+
"-i",
|
|
187
|
+
"pipe:0"
|
|
188
|
+
];
|
|
189
|
+
case "avfoundation":
|
|
190
|
+
case "screen": {
|
|
191
|
+
const videoDevice = config.videoDevice || "3";
|
|
192
|
+
return [
|
|
193
|
+
"-f",
|
|
194
|
+
"avfoundation",
|
|
195
|
+
"-framerate",
|
|
196
|
+
String(framerate),
|
|
197
|
+
"-pixel_format",
|
|
198
|
+
"nv12",
|
|
199
|
+
"-capture_cursor",
|
|
200
|
+
"1",
|
|
201
|
+
"-i",
|
|
202
|
+
`${videoDevice}:none`
|
|
203
|
+
];
|
|
204
|
+
}
|
|
205
|
+
case "file": {
|
|
206
|
+
const framePath = config.frameFile || "/tmp/milady-stream-frame.jpg";
|
|
207
|
+
return [
|
|
208
|
+
"-probesize",
|
|
209
|
+
"32",
|
|
210
|
+
"-analyzeduration",
|
|
211
|
+
"0",
|
|
212
|
+
"-loop",
|
|
213
|
+
"1",
|
|
214
|
+
"-f",
|
|
215
|
+
"image2",
|
|
216
|
+
"-c:v",
|
|
217
|
+
"mjpeg",
|
|
218
|
+
"-framerate",
|
|
219
|
+
String(framerate),
|
|
220
|
+
"-i",
|
|
221
|
+
framePath
|
|
222
|
+
];
|
|
223
|
+
}
|
|
224
|
+
default: return [
|
|
225
|
+
"-f",
|
|
226
|
+
"lavfi",
|
|
227
|
+
"-i",
|
|
228
|
+
`color=c=0x1a1a2e:s=${resolution}:r=${framerate}`
|
|
229
|
+
];
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
const streamManager = new StreamManager();
|
|
234
|
+
|
|
235
|
+
//#endregion
|
|
236
|
+
export { streamManager };
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { loadMiladyConfig, saveMiladyConfig } from "../config/config.js";
|
|
2
|
+
import { VERSION } from "../runtime/version.js";
|
|
3
|
+
import { compareSemver } from "./version-compat.js";
|
|
4
|
+
|
|
5
|
+
//#region src/services/update-checker.ts
|
|
6
|
+
/**
|
|
7
|
+
* Queries the npm registry for new miladyai versions on the user's
|
|
8
|
+
* configured release channel (stable/beta/nightly).
|
|
9
|
+
*/
|
|
10
|
+
const CHECK_INTERVAL_SECONDS = 14400;
|
|
11
|
+
const REGISTRY_TIMEOUT_MS = 8e3;
|
|
12
|
+
const NPM_REGISTRY_PACKUMENT_URL = "https://registry.npmjs.org/miladyai";
|
|
13
|
+
/** npm dist-tag corresponding to each release channel. */
|
|
14
|
+
const CHANNEL_DIST_TAGS = {
|
|
15
|
+
stable: "latest",
|
|
16
|
+
beta: "beta",
|
|
17
|
+
nightly: "nightly"
|
|
18
|
+
};
|
|
19
|
+
/** Fetch dist-tags from the npm registry. Returns null on any failure. */
|
|
20
|
+
async function fetchDistTags() {
|
|
21
|
+
const controller = new AbortController();
|
|
22
|
+
const timer = setTimeout(() => controller.abort(), REGISTRY_TIMEOUT_MS);
|
|
23
|
+
try {
|
|
24
|
+
const res = await fetch(NPM_REGISTRY_PACKUMENT_URL, {
|
|
25
|
+
headers: { Accept: "application/vnd.npm.install-v1+json" },
|
|
26
|
+
signal: controller.signal
|
|
27
|
+
});
|
|
28
|
+
if (!res.ok) return null;
|
|
29
|
+
return (await res.json())["dist-tags"] ?? null;
|
|
30
|
+
} catch {
|
|
31
|
+
return null;
|
|
32
|
+
} finally {
|
|
33
|
+
clearTimeout(timer);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function shouldSkipCheck(cfg) {
|
|
37
|
+
if (!cfg?.lastCheckAt) return false;
|
|
38
|
+
const interval = cfg.checkIntervalSeconds ?? CHECK_INTERVAL_SECONDS;
|
|
39
|
+
return (Date.now() - new Date(cfg.lastCheckAt).getTime()) / 1e3 < interval;
|
|
40
|
+
}
|
|
41
|
+
/** Resolve the effective release channel from config, env, or default. */
|
|
42
|
+
function resolveChannel(cfg) {
|
|
43
|
+
const env = process.env.MILADY_UPDATE_CHANNEL?.trim().toLowerCase();
|
|
44
|
+
if (env === "stable" || env === "beta" || env === "nightly") return env;
|
|
45
|
+
return cfg?.channel ?? "stable";
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Check whether a newer version is available.
|
|
49
|
+
* Respects the check interval; pass `force: true` to bypass.
|
|
50
|
+
*/
|
|
51
|
+
async function checkForUpdate(options) {
|
|
52
|
+
const config = loadMiladyConfig();
|
|
53
|
+
const updateCfg = config.update;
|
|
54
|
+
const channel = resolveChannel(updateCfg);
|
|
55
|
+
const distTag = CHANNEL_DIST_TAGS[channel];
|
|
56
|
+
if (!options?.force && shouldSkipCheck(updateCfg)) return {
|
|
57
|
+
updateAvailable: updateCfg?.lastCheckVersion ? (compareSemver(VERSION, updateCfg.lastCheckVersion) ?? 0) < 0 : false,
|
|
58
|
+
currentVersion: VERSION,
|
|
59
|
+
latestVersion: updateCfg?.lastCheckVersion ?? null,
|
|
60
|
+
channel,
|
|
61
|
+
distTag,
|
|
62
|
+
cached: true,
|
|
63
|
+
error: null
|
|
64
|
+
};
|
|
65
|
+
const distTags = await fetchDistTags();
|
|
66
|
+
if (!distTags) return {
|
|
67
|
+
updateAvailable: false,
|
|
68
|
+
currentVersion: VERSION,
|
|
69
|
+
latestVersion: null,
|
|
70
|
+
channel,
|
|
71
|
+
distTag,
|
|
72
|
+
cached: false,
|
|
73
|
+
error: "Unable to reach the npm registry. Check your network connection."
|
|
74
|
+
};
|
|
75
|
+
const latestVersion = distTags[distTag] ?? null;
|
|
76
|
+
if (!latestVersion) return {
|
|
77
|
+
updateAvailable: false,
|
|
78
|
+
currentVersion: VERSION,
|
|
79
|
+
latestVersion: null,
|
|
80
|
+
channel,
|
|
81
|
+
distTag,
|
|
82
|
+
cached: false,
|
|
83
|
+
error: `No version found for dist-tag "${distTag}". The "${channel}" channel may not have any published releases yet.`
|
|
84
|
+
};
|
|
85
|
+
const cmp = compareSemver(VERSION, latestVersion);
|
|
86
|
+
const updateAvailable = cmp !== null && cmp < 0;
|
|
87
|
+
try {
|
|
88
|
+
saveMiladyConfig({
|
|
89
|
+
...config,
|
|
90
|
+
update: {
|
|
91
|
+
...config.update,
|
|
92
|
+
lastCheckAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
93
|
+
lastCheckVersion: latestVersion
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
} catch (err) {
|
|
97
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
98
|
+
process.stderr.write(`[milady] Warning: could not save update-check metadata: ${msg}\n`);
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
updateAvailable,
|
|
102
|
+
currentVersion: VERSION,
|
|
103
|
+
latestVersion,
|
|
104
|
+
channel,
|
|
105
|
+
distTag,
|
|
106
|
+
cached: false,
|
|
107
|
+
error: null
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/** Returns the latest published version for each channel. */
|
|
111
|
+
async function fetchAllChannelVersions() {
|
|
112
|
+
const distTags = await fetchDistTags();
|
|
113
|
+
return {
|
|
114
|
+
stable: distTags?.latest ?? null,
|
|
115
|
+
beta: distTags?.beta ?? null,
|
|
116
|
+
nightly: distTags?.nightly ?? null
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
//#endregion
|
|
121
|
+
export { CHANNEL_DIST_TAGS, checkForUpdate, fetchAllChannelVersions, resolveChannel };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { loadMiladyConfig } from "../config/config.js";
|
|
2
|
+
import { theme } from "../terminal/theme.js";
|
|
3
|
+
import { checkForUpdate, resolveChannel } from "./update-checker.js";
|
|
4
|
+
|
|
5
|
+
//#region src/services/update-notifier.ts
|
|
6
|
+
/**
|
|
7
|
+
* Fire-and-forget background update check. Prints a one-line notice
|
|
8
|
+
* to stderr if a newer version is available (like npm's update-notifier).
|
|
9
|
+
*/
|
|
10
|
+
let notified = false;
|
|
11
|
+
function scheduleUpdateNotification() {
|
|
12
|
+
if (notified) return;
|
|
13
|
+
notified = true;
|
|
14
|
+
let config = {};
|
|
15
|
+
try {
|
|
16
|
+
config = loadMiladyConfig();
|
|
17
|
+
} catch {}
|
|
18
|
+
if (config.update?.checkOnStart === false) return;
|
|
19
|
+
if (process.env.CI || !process.stderr.isTTY) return;
|
|
20
|
+
checkForUpdate().then((result) => {
|
|
21
|
+
if (!result.updateAvailable || !result.latestVersion) return;
|
|
22
|
+
const channel = resolveChannel(config.update);
|
|
23
|
+
const suffix = channel !== "stable" ? ` (${channel})` : "";
|
|
24
|
+
process.stderr.write(`\n${theme.accent("Update available:")} ${theme.muted(result.currentVersion)} -> ${theme.success(result.latestVersion)}${theme.muted(suffix)}\n${theme.muted("Run")} ${theme.command("milady update")} ${theme.muted("to install")}\n\n`);
|
|
25
|
+
}).catch(() => {});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
//#endregion
|
|
29
|
+
export { scheduleUpdateNotification };
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
//#region src/services/version-compat.ts
|
|
2
|
+
/**
|
|
3
|
+
* Plugins that provide AI model capabilities. If ALL of these fail to load
|
|
4
|
+
* the agent is completely non-functional — no responses can be generated.
|
|
5
|
+
*/
|
|
6
|
+
const AI_PROVIDER_PLUGINS = [
|
|
7
|
+
"@elizaos/plugin-anthropic",
|
|
8
|
+
"@elizaos/plugin-openai",
|
|
9
|
+
"@elizaos/plugin-openrouter",
|
|
10
|
+
"@elizaos/plugin-ollama",
|
|
11
|
+
"@elizaos/plugin-google-genai",
|
|
12
|
+
"@elizaos/plugin-groq",
|
|
13
|
+
"@elizaos/plugin-xai",
|
|
14
|
+
"@homunculuslabs/plugin-zai",
|
|
15
|
+
"@elizaos/plugin-pi-ai",
|
|
16
|
+
"@elizaos/plugin-elizacloud"
|
|
17
|
+
];
|
|
18
|
+
/**
|
|
19
|
+
* Parse a semver string (including pre-release tags) into a comparable tuple.
|
|
20
|
+
* Returns null for unparseable versions.
|
|
21
|
+
*
|
|
22
|
+
* Examples:
|
|
23
|
+
* "2.0.0-alpha.3" → [2, 0, 0, 3]
|
|
24
|
+
* "2.0.0-alpha.4" → [2, 0, 0, 4]
|
|
25
|
+
* "2.0.0-nightly.20260208" → [2, 0, 0, 20260208]
|
|
26
|
+
* "2.0.0" → [2, 0, 0, Infinity] (release beats any pre-release)
|
|
27
|
+
*
|
|
28
|
+
* Note: comparisons are only meaningful within the same pre-release tag type
|
|
29
|
+
* (alpha vs alpha, nightly vs nightly). Cross-tag comparisons (alpha.7 vs beta.1)
|
|
30
|
+
* compare only the numeric suffix, which may not reflect the intended ordering.
|
|
31
|
+
* The update checker always compares within the same channel, so this is safe.
|
|
32
|
+
*/
|
|
33
|
+
function parseSemver(version) {
|
|
34
|
+
const match = version.match(/^(\d+)\.(\d+)\.(\d+)(?:-(?:alpha|beta|rc|nightly)\.(\d+))?$/);
|
|
35
|
+
if (!match) return null;
|
|
36
|
+
return [
|
|
37
|
+
Number(match[1]),
|
|
38
|
+
Number(match[2]),
|
|
39
|
+
Number(match[3]),
|
|
40
|
+
match[4] !== void 0 ? Number(match[4]) : Number.POSITIVE_INFINITY
|
|
41
|
+
];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Compare two semver strings. Returns:
|
|
45
|
+
* -1 if a < b
|
|
46
|
+
* 0 if a === b
|
|
47
|
+
* 1 if a > b
|
|
48
|
+
* null if either version is unparseable.
|
|
49
|
+
*/
|
|
50
|
+
function compareSemver(a, b) {
|
|
51
|
+
const pa = parseSemver(a);
|
|
52
|
+
const pb = parseSemver(b);
|
|
53
|
+
if (!pa || !pb) return null;
|
|
54
|
+
for (let i = 0; i < 4; i++) {
|
|
55
|
+
if (pa[i] < pb[i]) return -1;
|
|
56
|
+
if (pa[i] > pb[i]) return 1;
|
|
57
|
+
}
|
|
58
|
+
return 0;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* After plugin resolution, check whether at least one AI provider plugin
|
|
62
|
+
* loaded successfully. If none loaded, return a diagnostic message explaining
|
|
63
|
+
* whether this is a version-skew issue or a configuration issue.
|
|
64
|
+
*
|
|
65
|
+
* @param loadedPluginNames - Names of plugins that loaded successfully.
|
|
66
|
+
* @param failedPlugins - Names + error strings of plugins that failed to load.
|
|
67
|
+
*/
|
|
68
|
+
function diagnoseNoAIProvider(loadedPluginNames, failedPlugins) {
|
|
69
|
+
if (loadedPluginNames.filter((n) => AI_PROVIDER_PLUGINS.includes(n)).length > 0) return null;
|
|
70
|
+
const failedProviders = failedPlugins.filter((f) => AI_PROVIDER_PLUGINS.includes(f.name));
|
|
71
|
+
if (failedProviders.length === 0) return "No AI provider plugin was loaded. Set an API key environment variable (e.g. ANTHROPIC_API_KEY, OPENAI_API_KEY, OPENROUTER_API_KEY) or log in to Eliza Cloud (ELIZAOS_CLOUD_API_KEY) to enable at least one model provider.";
|
|
72
|
+
const versionSkewPlugins = failedProviders.filter((f) => f.error.includes("not found in module") || f.error.includes("Export named") || f.error.includes("does not provide an export named"));
|
|
73
|
+
if (versionSkewPlugins.length > 0) return `Version skew detected: ${versionSkewPlugins.map((f) => f.name).join(", ")} failed to import required symbols from @elizaos/core. This usually means the plugin version is ahead of the installed core version. Pin the affected plugins to a version compatible with your installed @elizaos/core, or upgrade core. See: https://github.com/milady-ai/milady/issues/10`;
|
|
74
|
+
return `All AI provider plugins failed to load:\n${failedProviders.map((f) => ` ${f.name}: ${f.error}`).join("\n")}`;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
//#endregion
|
|
78
|
+
export { compareSemver, diagnoseNoAIProvider };
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
|
|
4
|
+
//#region src/services/whatsapp-pairing.ts
|
|
5
|
+
/**
|
|
6
|
+
* WhatsApp pairing service — manages Baileys sessions for QR code authentication.
|
|
7
|
+
*
|
|
8
|
+
* This service is separate from `@elizaos/plugin-whatsapp` because the plugin
|
|
9
|
+
* initializes during runtime startup (too late for interactive QR flow).
|
|
10
|
+
* Once pairing succeeds, the auth state is persisted to disk so the plugin
|
|
11
|
+
* can reconnect automatically on subsequent startups.
|
|
12
|
+
*/
|
|
13
|
+
const LOG_PREFIX = "[whatsapp-pairing]";
|
|
14
|
+
/** Validate accountId to prevent path traversal. Only allows alphanumeric, dash, underscore. */
|
|
15
|
+
function sanitizeAccountId(raw) {
|
|
16
|
+
const cleaned = raw.replace(/[^a-zA-Z0-9_-]/g, "");
|
|
17
|
+
if (!cleaned || cleaned !== raw) throw new Error(`Invalid accountId: must only contain alphanumeric characters, dashes, and underscores`);
|
|
18
|
+
return cleaned;
|
|
19
|
+
}
|
|
20
|
+
var WhatsAppPairingSession = class {
|
|
21
|
+
constructor(options) {
|
|
22
|
+
this.socket = null;
|
|
23
|
+
this.status = "idle";
|
|
24
|
+
this.qrAttempts = 0;
|
|
25
|
+
this.MAX_QR_ATTEMPTS = 5;
|
|
26
|
+
this.restartTimer = null;
|
|
27
|
+
this.options = options;
|
|
28
|
+
}
|
|
29
|
+
async start() {
|
|
30
|
+
this.setStatus("initializing");
|
|
31
|
+
const baileys = await import("@whiskeysockets/baileys");
|
|
32
|
+
const makeWASocket = baileys.default;
|
|
33
|
+
const { useMultiFileAuthState, fetchLatestBaileysVersion, DisconnectReason } = baileys;
|
|
34
|
+
const QRCode = (await import("qrcode")).default;
|
|
35
|
+
const { Boom } = await import("@hapi/boom");
|
|
36
|
+
fs.mkdirSync(this.options.authDir, { recursive: true });
|
|
37
|
+
const { state, saveCreds } = await useMultiFileAuthState(this.options.authDir);
|
|
38
|
+
const { version } = await fetchLatestBaileysVersion();
|
|
39
|
+
const pino = (await import("pino")).default;
|
|
40
|
+
this.socket = makeWASocket({
|
|
41
|
+
version,
|
|
42
|
+
auth: state,
|
|
43
|
+
logger: pino({ level: "silent" }),
|
|
44
|
+
printQRInTerminal: false,
|
|
45
|
+
browser: [
|
|
46
|
+
"Milady AI",
|
|
47
|
+
"Desktop",
|
|
48
|
+
"1.0.0"
|
|
49
|
+
]
|
|
50
|
+
});
|
|
51
|
+
this.socket.ev.on("creds.update", saveCreds);
|
|
52
|
+
this.socket.ev.on("connection.update", async (update) => {
|
|
53
|
+
const { connection, lastDisconnect, qr } = update;
|
|
54
|
+
if (qr) {
|
|
55
|
+
this.qrAttempts++;
|
|
56
|
+
console.info(`${LOG_PREFIX} QR code received (attempt ${this.qrAttempts}/${this.MAX_QR_ATTEMPTS})`);
|
|
57
|
+
if (this.qrAttempts > this.MAX_QR_ATTEMPTS) {
|
|
58
|
+
this.setStatus("timeout");
|
|
59
|
+
this.stop();
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
const qrDataUrl = await QRCode.toDataURL(qr, {
|
|
64
|
+
width: 256,
|
|
65
|
+
margin: 2,
|
|
66
|
+
color: {
|
|
67
|
+
dark: "#000000",
|
|
68
|
+
light: "#ffffff"
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
this.setStatus("waiting_for_qr");
|
|
72
|
+
this.options.onEvent({
|
|
73
|
+
type: "whatsapp-qr",
|
|
74
|
+
accountId: this.options.accountId,
|
|
75
|
+
qrDataUrl,
|
|
76
|
+
expiresInMs: 2e4
|
|
77
|
+
});
|
|
78
|
+
} catch {}
|
|
79
|
+
}
|
|
80
|
+
if (connection === "close") {
|
|
81
|
+
const statusCode = (lastDisconnect?.error)?.output?.statusCode;
|
|
82
|
+
console.info(`${LOG_PREFIX} Connection closed, statusCode=${statusCode}, status=${this.status}`);
|
|
83
|
+
if (statusCode === DisconnectReason.loggedOut) this.setStatus("disconnected");
|
|
84
|
+
else if (statusCode === DisconnectReason.restartRequired || statusCode === DisconnectReason.timedOut || statusCode === DisconnectReason.connectionClosed || statusCode === DisconnectReason.connectionReplaced) {
|
|
85
|
+
console.info(`${LOG_PREFIX} Restarting pairing after transient close...`);
|
|
86
|
+
this.socket = null;
|
|
87
|
+
this.qrAttempts = 0;
|
|
88
|
+
this.restartTimer = setTimeout(() => {
|
|
89
|
+
this.restartTimer = null;
|
|
90
|
+
this.start().catch((err) => {
|
|
91
|
+
console.error(`${LOG_PREFIX} Restart failed:`, err);
|
|
92
|
+
this.setStatus("error");
|
|
93
|
+
this.options.onEvent({
|
|
94
|
+
type: "whatsapp-status",
|
|
95
|
+
accountId: this.options.accountId,
|
|
96
|
+
status: "error",
|
|
97
|
+
error: err instanceof Error ? err.message : String(err)
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
}, 3e3);
|
|
101
|
+
}
|
|
102
|
+
} else if (connection === "open") {
|
|
103
|
+
const phoneNumber = this.socket?.user?.id?.split(":")[0] ?? "";
|
|
104
|
+
this.setStatus("connected");
|
|
105
|
+
this.options.onEvent({
|
|
106
|
+
type: "whatsapp-status",
|
|
107
|
+
accountId: this.options.accountId,
|
|
108
|
+
status: "connected",
|
|
109
|
+
phoneNumber
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
stop() {
|
|
115
|
+
if (this.restartTimer) {
|
|
116
|
+
clearTimeout(this.restartTimer);
|
|
117
|
+
this.restartTimer = null;
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
this.socket?.end(void 0);
|
|
121
|
+
} catch {}
|
|
122
|
+
this.socket = null;
|
|
123
|
+
}
|
|
124
|
+
getStatus() {
|
|
125
|
+
return this.status;
|
|
126
|
+
}
|
|
127
|
+
setStatus(status) {
|
|
128
|
+
this.status = status;
|
|
129
|
+
this.options.onEvent({
|
|
130
|
+
type: "whatsapp-status",
|
|
131
|
+
accountId: this.options.accountId,
|
|
132
|
+
status
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* Check if WhatsApp auth credentials exist on disk for an account.
|
|
138
|
+
*/
|
|
139
|
+
function whatsappAuthExists(workspaceDir, accountId = "default") {
|
|
140
|
+
const credsPath = path.join(workspaceDir, "whatsapp-auth", accountId, "creds.json");
|
|
141
|
+
return fs.existsSync(credsPath);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Properly logout from WhatsApp (unlinks the device on WhatsApp servers)
|
|
145
|
+
* then delete auth files from disk.
|
|
146
|
+
*/
|
|
147
|
+
async function whatsappLogout(workspaceDir, accountId = "default") {
|
|
148
|
+
const authDir = path.join(workspaceDir, "whatsapp-auth", accountId);
|
|
149
|
+
const credsPath = path.join(authDir, "creds.json");
|
|
150
|
+
if (fs.existsSync(credsPath)) try {
|
|
151
|
+
const baileys = await import("@whiskeysockets/baileys");
|
|
152
|
+
const makeWASocket = baileys.default;
|
|
153
|
+
const { useMultiFileAuthState, fetchLatestBaileysVersion } = baileys;
|
|
154
|
+
const pino = (await import("pino")).default;
|
|
155
|
+
const logger = pino({ level: "silent" });
|
|
156
|
+
const { state } = await useMultiFileAuthState(authDir);
|
|
157
|
+
const { version } = await fetchLatestBaileysVersion();
|
|
158
|
+
const sock = makeWASocket({
|
|
159
|
+
version,
|
|
160
|
+
auth: state,
|
|
161
|
+
logger,
|
|
162
|
+
printQRInTerminal: false
|
|
163
|
+
});
|
|
164
|
+
await new Promise((resolve) => {
|
|
165
|
+
let settled = false;
|
|
166
|
+
const finish = () => {
|
|
167
|
+
if (settled) return;
|
|
168
|
+
settled = true;
|
|
169
|
+
clearTimeout(timeout);
|
|
170
|
+
try {
|
|
171
|
+
sock.ev.removeAllListeners("connection.update");
|
|
172
|
+
} catch {}
|
|
173
|
+
try {
|
|
174
|
+
sock.end(void 0);
|
|
175
|
+
} catch {}
|
|
176
|
+
resolve();
|
|
177
|
+
};
|
|
178
|
+
const timeout = setTimeout(finish, 1e4);
|
|
179
|
+
sock.ev.on("connection.update", async (update) => {
|
|
180
|
+
if (update.connection === "open") {
|
|
181
|
+
try {
|
|
182
|
+
await sock.logout();
|
|
183
|
+
} catch {}
|
|
184
|
+
finish();
|
|
185
|
+
} else if (update.connection === "close") finish();
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
} catch {}
|
|
189
|
+
fs.rmSync(authDir, {
|
|
190
|
+
recursive: true,
|
|
191
|
+
force: true
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
//#endregion
|
|
196
|
+
export { WhatsAppPairingSession, sanitizeAccountId, whatsappAuthExists, whatsappLogout };
|