levix-bot 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +105 -0
  3. package/SETUP.md +242 -0
  4. package/app.cjs +337 -0
  5. package/bin/levix.js +7 -0
  6. package/deploy/install.sh +182 -0
  7. package/deploy/levix.service +56 -0
  8. package/deploy/nginx/levix.leviro.net.conf +79 -0
  9. package/package.json +78 -0
  10. package/public/brand/apple-touch-icon.png +0 -0
  11. package/public/brand/banner.jpg +0 -0
  12. package/public/brand/banner.webp +0 -0
  13. package/public/brand/icon-16.png +0 -0
  14. package/public/brand/icon-192.png +0 -0
  15. package/public/brand/icon-32.png +0 -0
  16. package/public/brand/icon-512.png +0 -0
  17. package/public/brand/icon-512.webp +0 -0
  18. package/public/brand/mark.png +0 -0
  19. package/public/brand/mark.svg +16 -0
  20. package/public/brand/mark.webp +0 -0
  21. package/public/brand/wordmark.png +0 -0
  22. package/public/brand/wordmark.webp +0 -0
  23. package/public/dashboard.css +881 -0
  24. package/public/dashboard.js +1057 -0
  25. package/public/logo.svg +16 -0
  26. package/public/qrcode.min.js +1 -0
  27. package/public/socket.io.min.js +7 -0
  28. package/scheduler.cjs +197 -0
  29. package/src/auth/auth-storage.cjs +74 -0
  30. package/src/auth/use-database-auth-state.js +130 -0
  31. package/src/bootstrap/core.js +74 -0
  32. package/src/bootstrap/events.cjs +43 -0
  33. package/src/bootstrap/panel.js +97 -0
  34. package/src/cli.js +153 -0
  35. package/src/commands/autoschedule.cjs +84 -0
  36. package/src/commands/blacklist.cjs +116 -0
  37. package/src/commands/block.cjs +70 -0
  38. package/src/commands/calc.cjs +387 -0
  39. package/src/commands/debt.cjs +175 -0
  40. package/src/commands/deleteschedule.cjs +36 -0
  41. package/src/commands/gemini.cjs +727 -0
  42. package/src/commands/group/add.cjs +136 -0
  43. package/src/commands/group/all.cjs +43 -0
  44. package/src/commands/group/antiSpam.cjs +96 -0
  45. package/src/commands/group/antilink.cjs +167 -0
  46. package/src/commands/group/approveall.cjs +54 -0
  47. package/src/commands/group/clearwarns.cjs +41 -0
  48. package/src/commands/group/deletenote.cjs +33 -0
  49. package/src/commands/group/demote.cjs +62 -0
  50. package/src/commands/group/kick.cjs +85 -0
  51. package/src/commands/group/media.cjs +120 -0
  52. package/src/commands/group/members.cjs +59 -0
  53. package/src/commands/group/note.cjs +32 -0
  54. package/src/commands/group/promote.cjs +60 -0
  55. package/src/commands/group/removeall.cjs +42 -0
  56. package/src/commands/group/rules.cjs +31 -0
  57. package/src/commands/group/save.cjs +36 -0
  58. package/src/commands/group/setname.cjs +41 -0
  59. package/src/commands/group/setpp.cjs +51 -0
  60. package/src/commands/group/setrules.cjs +46 -0
  61. package/src/commands/group/setwarn.cjs +58 -0
  62. package/src/commands/group/tagadmins.cjs +50 -0
  63. package/src/commands/group/warn.cjs +105 -0
  64. package/src/commands/group/warns.cjs +66 -0
  65. package/src/commands/group/welcome.cjs +109 -0
  66. package/src/commands/group.cjs +160 -0
  67. package/src/commands/help.cjs +230 -0
  68. package/src/commands/listschedules.cjs +47 -0
  69. package/src/commands/loop.cjs +163 -0
  70. package/src/commands/memory.cjs +201 -0
  71. package/src/commands/mod.cjs +155 -0
  72. package/src/commands/notes.cjs +28 -0
  73. package/src/commands/perm.cjs +236 -0
  74. package/src/commands/ping.cjs +17 -0
  75. package/src/commands/poll.cjs +80 -0
  76. package/src/commands/prayer.cjs +64 -0
  77. package/src/commands/qr.cjs +39 -0
  78. package/src/commands/rand.cjs +130 -0
  79. package/src/commands/restart.cjs +25 -0
  80. package/src/commands/schedule.cjs +86 -0
  81. package/src/commands/score.cjs +130 -0
  82. package/src/commands/setprefix.cjs +40 -0
  83. package/src/commands/shortlink.cjs +74 -0
  84. package/src/commands/shutdown.cjs +45 -0
  85. package/src/commands/status.cjs +75 -0
  86. package/src/commands/stt.cjs +150 -0
  87. package/src/commands/todo.cjs +88 -0
  88. package/src/commands/tts.cjs +170 -0
  89. package/src/commands/unblock.cjs +57 -0
  90. package/src/commands/weather.cjs +79 -0
  91. package/src/config/ai-persona.md +17 -0
  92. package/src/config/baileys.config.js +51 -0
  93. package/src/config/brand.cjs +36 -0
  94. package/src/config/brand.esm.js +17 -0
  95. package/src/config/constants.js +16 -0
  96. package/src/config/defaults.cjs +91 -0
  97. package/src/config/lock.cjs +110 -0
  98. package/src/config/paths.cjs +90 -0
  99. package/src/config/runtime-config.cjs +219 -0
  100. package/src/config/secrets.cjs +130 -0
  101. package/src/config/settings.cjs +386 -0
  102. package/src/core/connection.js +199 -0
  103. package/src/core/events.js +61 -0
  104. package/src/core/socket.js +64 -0
  105. package/src/db/db.cjs +282 -0
  106. package/src/db/store.cjs +837 -0
  107. package/src/db/store.esm.js +17 -0
  108. package/src/domain/caddy.js +120 -0
  109. package/src/domain/command.js +380 -0
  110. package/src/domain/detect.js +173 -0
  111. package/src/domain/nginx.js +138 -0
  112. package/src/domain/system.js +148 -0
  113. package/src/handlers/command.handler.js +414 -0
  114. package/src/handlers/group.handler.js +73 -0
  115. package/src/handlers/message.handler.js +149 -0
  116. package/src/index.js +217 -0
  117. package/src/middleware/antispam.middleware.js +68 -0
  118. package/src/middleware/blacklist.middleware.js +29 -0
  119. package/src/middleware/forward-tracking.middleware.js +49 -0
  120. package/src/middleware/permissions.middleware.js +114 -0
  121. package/src/routes/dashboard.api.esm.js +779 -0
  122. package/src/services/aiAgent.cjs +317 -0
  123. package/src/services/aiTools.cjs +635 -0
  124. package/src/utils/datetime.cjs +61 -0
  125. package/src/utils/lid-helper.esm.js +143 -0
  126. package/src/utils/logger.cjs +72 -0
  127. package/src/utils/memory.cjs +385 -0
  128. package/src/utils/normalizeJid.cjs +65 -0
  129. package/src/utils/normalizeJid.esm.js +37 -0
  130. package/src/utils/openBrowser.cjs +129 -0
  131. package/src/utils/permissions.cjs +154 -0
  132. package/src/utils/permissions.esm.js +375 -0
  133. package/src/utils/recentMessageCache.esm.js +70 -0
  134. package/src/utils/requestOrigin.cjs +102 -0
  135. package/src/utils/sendBotMessage.cjs +43 -0
  136. package/src/utils/sendBotMessage.esm.js +139 -0
  137. package/src/utils/statusMessage.cjs +179 -0
  138. package/src/utils/storage-hub.cjs +49 -0
  139. package/src/utils/storage-hub.esm.js +24 -0
  140. package/src/utils/storage.cjs +80 -0
  141. package/src/utils/storage.esm.js +88 -0
  142. package/src/utils/textDecode.cjs +197 -0
  143. package/src/utils/thumbnail.cjs +591 -0
  144. package/src/utils/typing.esm.js +102 -0
  145. package/views/dashboard.ejs +329 -0
  146. package/views/login.ejs +105 -0
  147. package/views/qr.ejs +108 -0
  148. package/views/setup.ejs +122 -0
package/bin/levix.js ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ // The `levix` command. Everything it does lives in src/cli.js, so the packaged
3
+ // executable and this wrapper share one implementation.
4
+
5
+ import { run } from "../src/cli.js";
6
+
7
+ await run(process.argv);
@@ -0,0 +1,182 @@
1
+ #!/usr/bin/env bash
2
+ # Install Levix on a Linux server and run it as a service.
3
+ #
4
+ # curl -fsSL https://levix.leviro.net/install.sh | bash
5
+ #
6
+ # This file is the source of every public installer. The copy served from
7
+ # levix.leviro.net/install/vX.Y.Z.sh is this same script with VERSION rewritten
8
+ # to that release, which is why a pinned URL keeps installing that version
9
+ # forever. The copy in git leaves VERSION as "latest".
10
+ #
11
+ # What it does, in order — read it before you pipe it into a shell, as you
12
+ # should with any script that asks for sudo:
13
+ #
14
+ # 1. checks for Node 24+ and stops with instructions if it isn't there
15
+ # 2. installs the `levix` command globally from the `levix-bot` npm package
16
+ # 3. creates a `levix` system user and /var/lib/levix for its data
17
+ # 4. installs the systemd unit, pointed at the levix it just installed
18
+ # 5. enables it, starts it, and prints where to go next
19
+ # 6. offers — but never assumes — to connect a domain
20
+ #
21
+ # It writes exactly three things outside npm's own prefix: the system user,
22
+ # /var/lib/levix, and /etc/systemd/system/levix.service. It never touches an
23
+ # existing installation's data, and it can be re-run to upgrade.
24
+
25
+ set -euo pipefail
26
+
27
+ PACKAGE="levix-bot"
28
+ # Rewritten by scripts/build-release-installer.mjs when a release is published.
29
+ # Keep this line exactly as it is: one assignment, one double-quoted value.
30
+ VERSION="latest"
31
+ SERVICE="levix"
32
+ DATA_DIR="/var/lib/levix"
33
+ UNIT="/etc/systemd/system/${SERVICE}.service"
34
+ MIN_NODE_MAJOR=24
35
+ PORT=3001
36
+
37
+ say() { printf '\n %s\n' "$*"; }
38
+ die() { printf '\n error: %s\n\n' "$*" >&2; exit 1; }
39
+
40
+ sudo_if_needed() {
41
+ if [ "$(id -u)" -eq 0 ]; then
42
+ "$@"
43
+ else
44
+ command -v sudo >/dev/null 2>&1 || die "This needs root, and sudo is not installed."
45
+ sudo "$@"
46
+ fi
47
+ }
48
+
49
+ # --- 1. Node ---------------------------------------------------------------
50
+
51
+ command -v node >/dev/null 2>&1 ||
52
+ die "Node is not installed. Get Node ${MIN_NODE_MAJOR} LTS from https://nodejs.org"
53
+
54
+ NODE_MAJOR="$(node -p 'process.versions.node.split(".")[0]')"
55
+ if [ "$NODE_MAJOR" -lt "$MIN_NODE_MAJOR" ]; then
56
+ die "Node ${MIN_NODE_MAJOR}+ is required (found $(node -v)). Levix stores everything in SQLite, which Node only ships with itself from ${MIN_NODE_MAJOR} on."
57
+ fi
58
+
59
+ command -v npm >/dev/null 2>&1 || die "npm is not installed."
60
+ command -v systemctl >/dev/null 2>&1 ||
61
+ die "This script installs a systemd service, and systemd isn't here. Run 'npm i -g ${PACKAGE}' and start 'levix' yourself."
62
+
63
+ say "Node $(node -v) — good."
64
+
65
+ # --- 2. The package --------------------------------------------------------
66
+
67
+ if [ "$VERSION" = "latest" ]; then
68
+ say "Installing ${PACKAGE}…"
69
+ else
70
+ say "Installing ${PACKAGE} ${VERSION}…"
71
+ fi
72
+ sudo_if_needed npm install -g "${PACKAGE}@${VERSION}"
73
+
74
+ # Where did it land? `/usr/bin/env levix` in the unit would depend on systemd's
75
+ # PATH, which does not include nvm's prefix and is not guaranteed to include
76
+ # npm's. Resolve it now and write the real path into the unit.
77
+ LEVIX_BIN="$(command -v levix || true)"
78
+ if [ -z "$LEVIX_BIN" ]; then
79
+ NPM_BIN="$(npm bin -g 2>/dev/null || npm prefix -g 2>/dev/null)/bin"
80
+ [ -x "${NPM_BIN}/levix" ] && LEVIX_BIN="${NPM_BIN}/levix"
81
+ fi
82
+ [ -n "$LEVIX_BIN" ] || die "levix installed but could not be found on PATH."
83
+ say "Installed at ${LEVIX_BIN}"
84
+
85
+ # --- 3. User and data directory -------------------------------------------
86
+
87
+ if ! id -u levix >/dev/null 2>&1; then
88
+ say "Creating the levix system user…"
89
+ sudo_if_needed useradd --system --home-dir "$DATA_DIR" --shell /usr/sbin/nologin levix
90
+ fi
91
+
92
+ sudo_if_needed mkdir -p "$DATA_DIR"
93
+ sudo_if_needed chown -R levix:levix "$DATA_DIR"
94
+ # The database holds the WhatsApp session and the panel password hash. Nobody
95
+ # else on the machine has any business reading it.
96
+ sudo_if_needed chmod 750 "$DATA_DIR"
97
+
98
+ # --- 4. The service --------------------------------------------------------
99
+
100
+ say "Installing the systemd service…"
101
+
102
+ UNIT_SOURCE=""
103
+ for candidate in \
104
+ "$(npm root -g 2>/dev/null)/${PACKAGE}/deploy/levix.service" \
105
+ "$(dirname "$0")/levix.service"; do
106
+ if [ -f "$candidate" ]; then UNIT_SOURCE="$candidate"; break; fi
107
+ done
108
+ [ -n "$UNIT_SOURCE" ] || die "Couldn't find the unit file to install."
109
+
110
+ # Written through a temp file in the same directory, then moved into place, so
111
+ # an interrupted run never leaves systemd a half-written unit. mktemp, not a
112
+ # predictable name in /tmp.
113
+ TMP_UNIT="$(mktemp)"
114
+ trap 'rm -f "$TMP_UNIT"' EXIT
115
+
116
+ sed "s|^ExecStart=.*|ExecStart=${LEVIX_BIN} --data ${DATA_DIR}|" "$UNIT_SOURCE" > "$TMP_UNIT"
117
+ grep -q "^ExecStart=${LEVIX_BIN}" "$TMP_UNIT" || die "Failed to set ExecStart in the unit file."
118
+
119
+ sudo_if_needed install -m 0644 -o root -g root "$TMP_UNIT" "$UNIT"
120
+
121
+ sudo_if_needed systemctl daemon-reload
122
+ sudo_if_needed systemctl enable "$SERVICE"
123
+ sudo_if_needed systemctl restart "$SERVICE"
124
+
125
+ # --- 5. Did it actually start? --------------------------------------------
126
+
127
+ started=0
128
+ for _ in $(seq 1 30); do
129
+ if systemctl is-active --quiet "$SERVICE"; then started=1; break; fi
130
+ sleep 1
131
+ done
132
+
133
+ if [ "$started" -ne 1 ]; then
134
+ printf '\n Levix was installed but the service did not start.\n\n'
135
+ printf ' What systemd says:\n\n'
136
+ sudo_if_needed systemctl status "$SERVICE" --no-pager --lines 20 || true
137
+ printf '\n Full log: journalctl -u %s -n 50\n\n' "$SERVICE"
138
+ exit 1
139
+ fi
140
+
141
+ IP="$(hostname -I 2>/dev/null | awk '{print $1}')"
142
+
143
+ cat <<EOF
144
+
145
+ Levix is running.
146
+
147
+ Control panel http://${IP:-<this server>}:${PORT}/
148
+ Data ${DATA_DIR}
149
+ Logs journalctl -u ${SERVICE} -f
150
+
151
+ Open the panel and pick a password. Opening it from another machine also
152
+ asks for a setup code — this prints it:
153
+
154
+ journalctl -u ${SERVICE} -n 40 | grep -A3 'Setup code'
155
+
156
+ Then scan the QR from the Connection screen with WhatsApp.
157
+
158
+ EOF
159
+
160
+ # --- 6. A domain, if they want one now ------------------------------------
161
+
162
+ # Optional, and entirely skippable: an IP is a perfectly good way to run this,
163
+ # and `levix domain` works just as well next week. Only ask when there is
164
+ # somebody at the keyboard — piping this script into bash gives us no stdin.
165
+ if [ -t 0 ]; then
166
+ printf ' The panel has no HTTPS of its own. Connect a domain now? [y/N] '
167
+ read -r answer </dev/tty || answer=""
168
+ case "$answer" in
169
+ [yY]*)
170
+ # One implementation, in the CLI. This script does not have its own.
171
+ sudo_if_needed "$LEVIX_BIN" --data "$DATA_DIR" domain
172
+ ;;
173
+ *)
174
+ printf '\n Fine — run this whenever you are ready:\n\n sudo levix --data %s domain bot.example.com\n\n' "$DATA_DIR"
175
+ ;;
176
+ esac
177
+ else
178
+ printf ' To put it behind a domain with HTTPS:\n\n sudo levix --data %s domain bot.example.com\n\n' "$DATA_DIR"
179
+ fi
180
+
181
+ printf ' If this server is on the public internet, do that (or put it behind\n'
182
+ printf ' your own reverse proxy) before sharing the panel address.\n\n'
@@ -0,0 +1,56 @@
1
+ # systemd unit for Levix.
2
+ #
3
+ # sudo cp deploy/levix.service /etc/systemd/system/
4
+ # sudo systemctl enable --now levix
5
+ # journalctl -u levix -f # the setup code is printed here on first run
6
+ #
7
+ # deploy/install.sh installs this and rewrites ExecStart with the real path of
8
+ # the `levix` command it just installed — `/usr/bin/env levix` only works when
9
+ # npm's global bin is on systemd's own PATH, which it is not under nvm and not
10
+ # on every distro. If you are installing this by hand, check that line.
11
+
12
+ [Unit]
13
+ Description=Levix WhatsApp bot
14
+ Documentation=https://github.com/Abdodiab2005/levix
15
+ After=network-online.target
16
+ Wants=network-online.target
17
+
18
+ # A misconfiguration — a port permanently taken, a corrupt install — must not
19
+ # turn into a restart loop that spins the CPU and fills the journal forever.
20
+ # Five failures in a minute and systemd stops trying, leaving the unit failed
21
+ # where `systemctl status` will show it.
22
+ StartLimitIntervalSec=60
23
+ StartLimitBurst=5
24
+
25
+ [Service]
26
+ Type=simple
27
+ User=levix
28
+ Group=levix
29
+ ExecStart=/usr/bin/env levix --data /var/lib/levix
30
+ Restart=always
31
+ # Long enough not to hammer, short enough to recover from a blip unattended.
32
+ RestartSec=5
33
+ KillSignal=SIGTERM
34
+ # Long enough for the database to checkpoint and the socket to close cleanly.
35
+ TimeoutStopSec=30
36
+
37
+ # Everything it writes is under one directory, which makes the rest of this
38
+ # easy. StateDirectory creates it and fixes its ownership on every start.
39
+ StateDirectory=levix
40
+ WorkingDirectory=/var/lib/levix
41
+
42
+ NoNewPrivileges=true
43
+ PrivateTmp=true
44
+ ProtectSystem=strict
45
+ ProtectHome=true
46
+ ReadWritePaths=/var/lib/levix
47
+ ProtectKernelTunables=true
48
+ ProtectControlGroups=true
49
+ RestrictSUIDSGID=true
50
+ # The bot needs outbound network and nothing else; it binds an ordinary port,
51
+ # so it never needs a capability.
52
+ RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
53
+ CapabilityBoundingSet=
54
+
55
+ [Install]
56
+ WantedBy=multi-user.target
@@ -0,0 +1,79 @@
1
+ # Reference Nginx configuration for the Levix download host.
2
+ #
3
+ # This file is documentation, not something Levix installs. Copy the parts you
4
+ # need into the server block that already serves levix.leviro.net.
5
+ #
6
+ # Two things live on that hostname:
7
+ #
8
+ # /install.sh, /install, /install/* static files, published by a release
9
+ # everything else the Next.js site, on 127.0.0.1:3000
10
+ #
11
+ # The installers are plain files on disk. Publishing a release replaces one of
12
+ # them with a rename; nothing here needs a reload, a restart, or an Nginx that
13
+ # knows anything about releases.
14
+
15
+ server {
16
+ listen 443 ssl;
17
+ listen [::]:443 ssl;
18
+ server_name levix.leviro.net;
19
+
20
+ # ssl_certificate / ssl_certificate_key — whatever certbot or your existing
21
+ # setup already wrote for this host.
22
+
23
+ charset utf-8;
24
+
25
+ # `location =` is an exact match and Nginx settles it before it looks at
26
+ # anything else, so this can never fall through to the proxy below.
27
+ location = /install.sh {
28
+ alias /var/www/levix-downloads/install.sh;
29
+
30
+ # Readable in a browser. Anyone about to pipe this into a shell should
31
+ # be able to click the URL and read it first — that is the whole point
32
+ # of publishing the source rather than a binary.
33
+ default_type text/plain;
34
+ add_header Content-Disposition "inline" always;
35
+
36
+ # A moving alias. Serving yesterday's stable installer from a cache
37
+ # after a release is the one failure this endpoint must not have.
38
+ add_header Cache-Control "no-cache, no-store, must-revalidate" always;
39
+ }
40
+
41
+ # Convenience only. The command in the documentation stays /install.sh.
42
+ location = /install {
43
+ return 302 /install.sh;
44
+ }
45
+
46
+ # `^~` stops Nginx from considering any regex location for these, so a
47
+ # future regex rule for the site cannot start swallowing installer URLs.
48
+ location ^~ /install/ {
49
+ alias /var/www/levix-downloads/install/;
50
+
51
+ default_type text/plain;
52
+ add_header Content-Disposition "inline" always;
53
+
54
+ # These files are immutable: v2.0.1.sh is written once and never
55
+ # rewritten, so it can be cached for as long as anyone likes.
56
+ add_header Cache-Control "public, max-age=31536000, immutable" always;
57
+
58
+ autoindex off;
59
+ }
60
+
61
+ # Everything else is the website, which knows nothing about any of this.
62
+ location / {
63
+ proxy_pass http://127.0.0.1:3000;
64
+ proxy_http_version 1.1;
65
+ proxy_set_header Upgrade $http_upgrade;
66
+ proxy_set_header Connection $connection_upgrade;
67
+ proxy_set_header Host $host;
68
+ proxy_set_header X-Real-IP $remote_addr;
69
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
70
+ proxy_set_header X-Forwarded-Proto $scheme;
71
+ }
72
+ }
73
+
74
+ # For the Upgrade header above, if the site does not already define it:
75
+ #
76
+ # map $http_upgrade $connection_upgrade {
77
+ # default upgrade;
78
+ # '' close;
79
+ # }
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "levix-bot",
3
+ "version": "2.0.0",
4
+ "description": "A self-hosted personal WhatsApp bot with an AI agent, group moderation and a web control panel.",
5
+ "main": "src/index.js",
6
+ "scripts": {
7
+ "start": "node bin/levix.js",
8
+ "dev": "nodemon bin/levix.js",
9
+ "test": "node tests/run.mjs",
10
+ "brand:assets": "node scripts/build-brand-assets.mjs",
11
+ "build:sea": "node scripts/build-sea.mjs",
12
+ "validate:tarball": "node scripts/validate-tarball.mjs",
13
+ "validate:sea": "node scripts/validate-sea.mjs",
14
+ "validate:docker": "bash scripts/validate-docker.sh"
15
+ },
16
+ "keywords": [
17
+ "whatsapp",
18
+ "bot",
19
+ "baileys",
20
+ "gemini",
21
+ "ai-agent",
22
+ "sqlite",
23
+ "self-hosted"
24
+ ],
25
+ "author": "Abdelrhman Diab (Leviro)",
26
+ "license": "MIT",
27
+ "type": "module",
28
+ "dependencies": {
29
+ "@google/generative-ai": "^0.24.1",
30
+ "@whiskeysockets/baileys": "7.0.0-rc13",
31
+ "axios": "^1.9.0",
32
+ "ejs": "^3.1.10",
33
+ "express": "^5.1.0",
34
+ "express-session": "^1.18.1",
35
+ "ffmpeg-static": "^5.2.0",
36
+ "fluent-ffmpeg": "^2.1.3",
37
+ "node-cache": "^5.1.2",
38
+ "node-cron": "^4.1.0",
39
+ "node-gtts": "^2.0.2",
40
+ "pino": "^9.7.0",
41
+ "pino-pretty": "^13.0.0",
42
+ "qrcode": "^1.5.4",
43
+ "qrcode-terminal": "^0.12.0",
44
+ "socket.io": "^4.8.1",
45
+ "uuid": "^11.1.0"
46
+ },
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "https://github.com/Abdodiab2005/levix.git"
50
+ },
51
+ "homepage": "https://github.com/Abdodiab2005/levix",
52
+ "bugs": {
53
+ "url": "https://github.com/Abdodiab2005/levix/issues"
54
+ },
55
+ "engines": {
56
+ "node": ">=24"
57
+ },
58
+ "devDependencies": {
59
+ "esbuild": "^0.28.2",
60
+ "postject": "^1.0.0-alpha.6",
61
+ "sharp": "^0.35.3"
62
+ },
63
+ "bin": {
64
+ "levix": "bin/levix.js"
65
+ },
66
+ "files": [
67
+ "bin/",
68
+ "src/",
69
+ "views/",
70
+ "public/",
71
+ "deploy/",
72
+ "app.cjs",
73
+ "scheduler.cjs",
74
+ "README.md",
75
+ "SETUP.md",
76
+ "LICENSE"
77
+ ]
78
+ }
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,16 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" fill="none">
2
+ <defs>
3
+ <linearGradient id="levix-gradient" x1="15" y1="86" x2="87" y2="14" gradientUnits="userSpaceOnUse">
4
+ <stop stop-color="#0045FF"/>
5
+ <stop offset=".55" stop-color="#0066F5"/>
6
+ <stop offset="1" stop-color="#00D4FF"/>
7
+ </linearGradient>
8
+ </defs>
9
+ <path d="M75.5 55.2C77.8 50.9 79 46 79 41C79 22 63.5 7.5 44 7.5C24.2 7.5 8.5 22.1 8.5 41C8.5 53.5 15.8 64.6 27.2 70.4L23.3 84.5L39.6 76.7C44.3 78.1 49.2 78.4 54.4 76.8" stroke="url(#levix-gradient)" stroke-width="8.5" stroke-linecap="round" stroke-linejoin="round"/>
10
+ <circle cx="34.8" cy="42.7" r="4.1" fill="url(#levix-gradient)"/>
11
+ <circle cx="55.4" cy="42.7" r="4.1" fill="url(#levix-gradient)"/>
12
+ <path d="M39.5 51.8C42.7 55.8 47.7 55.8 50.9 51.8" stroke="url(#levix-gradient)" stroke-width="3.8" stroke-linecap="round"/>
13
+ <path d="M59.2 59.2L83.2 83.2M84.2 57.8L58.4 83.2" stroke="url(#levix-gradient)" stroke-width="8.2" stroke-linecap="round"/>
14
+ <path d="M83.2 16.5C84.3 20.7 86.3 22.8 90.5 23.9C86.3 25 84.3 27.1 83.2 31.3C82.1 27.1 80.1 25 75.9 23.9C80.1 22.8 82.1 20.7 83.2 16.5Z" fill="url(#levix-gradient)"/>
15
+ </svg>
16
+
Binary file
Binary file
Binary file