claudity 1.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.
- package/.env.example +2 -0
- package/README.md +32 -0
- package/install.sh +343 -0
- package/package.json +28 -0
- package/public/css/style.css +1672 -0
- package/public/favicon.svg +9 -0
- package/public/font/berkeley.woff2 +0 -0
- package/public/index.html +262 -0
- package/public/js/app.js +1240 -0
- package/setup.sh +134 -0
- package/src/db.js +162 -0
- package/src/index.js +61 -0
- package/src/routes/api.js +194 -0
- package/src/routes/connections.js +41 -0
- package/src/routes/relay.js +37 -0
- package/src/services/auth.js +88 -0
- package/src/services/chat.js +365 -0
- package/src/services/claude.js +353 -0
- package/src/services/connections.js +97 -0
- package/src/services/discord.js +126 -0
- package/src/services/heartbeat.js +106 -0
- package/src/services/imessage.js +200 -0
- package/src/services/memory.js +183 -0
- package/src/services/scheduler.js +32 -0
- package/src/services/signal.js +237 -0
- package/src/services/slack.js +113 -0
- package/src/services/telegram.js +94 -0
- package/src/services/tools.js +467 -0
- package/src/services/whatsapp.js +111 -0
- package/src/services/workspace.js +162 -0
package/.env.example
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# claudity
|
|
2
|
+
kick your feet back as your army of constantly evolving agents knocks out every project you ever dreamed
|
|
3
|
+
|
|
4
|
+
> [!WARNING]
|
|
5
|
+
> claudity is experimental software that can read, create, edit and delete files. please use with extreme caution.
|
|
6
|
+
|
|
7
|
+
## dive on in
|
|
8
|
+
*if only everything were this simple*
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
curl -fsSL https://claudity.ai/install.sh | bash
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
installing claudity takes less than a minute, so you can jump into its slick user friendly interface and put your agents to work right away with no chaos or clutter
|
|
15
|
+
|
|
16
|
+
## we know you have a choice in agents
|
|
17
|
+
*and it looks like you made the right one*
|
|
18
|
+
|
|
19
|
+
- **unlimited agents** that can work all at the same time
|
|
20
|
+
- **built for claude code** with automatic setup token detection
|
|
21
|
+
- **private and local** so your data only ever touches [anthropic's](https://anthropic.com) servers
|
|
22
|
+
- **persistent memory** that evolves over time and compacts when it needs to
|
|
23
|
+
- **always available** from discord, imessage, signal, slack, telegram or whatsapp
|
|
24
|
+
|
|
25
|
+
## penny for your thoughts
|
|
26
|
+
|
|
27
|
+
all feedback - kind or strongly worded - is greatly appreciated and can be sent to [hello@claudity.ai](https://claudity.ai)
|
|
28
|
+
|
|
29
|
+
## stealing credit
|
|
30
|
+
made with love by [mazz.digital](https://mazz.digital)
|
|
31
|
+
|
|
32
|
+
*and his mob of agents*
|
package/install.sh
ADDED
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -e
|
|
3
|
+
|
|
4
|
+
trap 'rm -f /tmp/claudity-install.log' EXIT
|
|
5
|
+
|
|
6
|
+
if [ "$(uname)" != "Darwin" ]; then
|
|
7
|
+
echo "this installer is for macos only" >&2
|
|
8
|
+
exit 1
|
|
9
|
+
fi
|
|
10
|
+
|
|
11
|
+
if ! tty -s </dev/tty 2>/dev/null; then
|
|
12
|
+
echo "interactive terminal required (no tty available)" >&2
|
|
13
|
+
exit 1
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
green="\033[92m"
|
|
17
|
+
dim="\033[2m"
|
|
18
|
+
red="\033[91m"
|
|
19
|
+
yellow="\033[93m"
|
|
20
|
+
bold="\033[1m"
|
|
21
|
+
reset="\033[0m"
|
|
22
|
+
|
|
23
|
+
step() { echo -e "\n${green}→${reset} $1"; }
|
|
24
|
+
ok() { echo -e " ${green}✓${reset} $1"; }
|
|
25
|
+
warn() { echo -e " ${yellow}!${reset} $1"; }
|
|
26
|
+
fail() { echo -e " ${red}✗${reset} $1"; exit 1; }
|
|
27
|
+
info() { echo -e " ${dim}$1${reset}"; }
|
|
28
|
+
|
|
29
|
+
spin() {
|
|
30
|
+
local msg="$1"
|
|
31
|
+
shift
|
|
32
|
+
local chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
|
|
33
|
+
"$@" >/tmp/claudity-install.log 2>&1 &
|
|
34
|
+
local pid=$!
|
|
35
|
+
local i=0
|
|
36
|
+
while kill -0 "$pid" 2>/dev/null; do
|
|
37
|
+
local c="${chars:i%10:1}"
|
|
38
|
+
printf "\r \033[92m%s\033[0m %s" "$c" "$msg"
|
|
39
|
+
i=$((i + 1))
|
|
40
|
+
sleep 0.1
|
|
41
|
+
done
|
|
42
|
+
wait "$pid" 2>/dev/null
|
|
43
|
+
local status=$?
|
|
44
|
+
printf "\r"
|
|
45
|
+
if [ "$status" -eq 0 ]; then
|
|
46
|
+
ok "$msg"
|
|
47
|
+
else
|
|
48
|
+
echo -e " ${red}✗${reset} $msg"
|
|
49
|
+
echo ""
|
|
50
|
+
echo -e " ${dim}log:${reset}"
|
|
51
|
+
tail -5 /tmp/claudity-install.log | while read -r line; do
|
|
52
|
+
echo -e " ${dim}$line${reset}"
|
|
53
|
+
done
|
|
54
|
+
exit 1
|
|
55
|
+
fi
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
boxlines() {
|
|
59
|
+
local maxlen=0
|
|
60
|
+
for arg in "$@"; do
|
|
61
|
+
local stripped
|
|
62
|
+
stripped=$(echo -e "$arg" | sed $'s/\033\[[0-9;]*m//g')
|
|
63
|
+
local slen=${#stripped}
|
|
64
|
+
if [ "$slen" -gt "$maxlen" ]; then maxlen=$slen; fi
|
|
65
|
+
done
|
|
66
|
+
local w=$((maxlen + 8))
|
|
67
|
+
if [ "$w" -lt 50 ]; then w=50; fi
|
|
68
|
+
local bar=""
|
|
69
|
+
for ((i = 0; i < w - 2; i++)); do bar="${bar}─"; done
|
|
70
|
+
echo ""
|
|
71
|
+
echo -e " ${dim}╭${bar}╮${reset}"
|
|
72
|
+
echo -e " ${dim}│${reset}$(printf '%*s' $((w - 2)) '')${dim}│${reset}"
|
|
73
|
+
while [ "$#" -gt 0 ]; do
|
|
74
|
+
local line="$1"
|
|
75
|
+
shift
|
|
76
|
+
local stripped
|
|
77
|
+
stripped=$(echo -e "$line" | sed $'s/\033\[[0-9;]*m//g')
|
|
78
|
+
local slen=${#stripped}
|
|
79
|
+
local pad=$((w - 2 - slen - 3))
|
|
80
|
+
if [ "$pad" -lt 0 ]; then pad=0; fi
|
|
81
|
+
echo -e " ${dim}│${reset} ${line}$(printf '%*s' "$pad" '')${dim}│${reset}"
|
|
82
|
+
done
|
|
83
|
+
echo -e " ${dim}│${reset}$(printf '%*s' $((w - 2)) '')${dim}│${reset}"
|
|
84
|
+
echo -e " ${dim}╰${bar}╯${reset}"
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
boxlines \
|
|
88
|
+
"${bold}${green}claudity installer${reset}" \
|
|
89
|
+
"" \
|
|
90
|
+
"this installer will:" \
|
|
91
|
+
"" \
|
|
92
|
+
"${dim}•${reset} install xcode command line tools, homebrew, node.js" \
|
|
93
|
+
" and npm packages if not already present" \
|
|
94
|
+
"${dim}•${reset} download ~200mb of dependencies" \
|
|
95
|
+
"${dim}•${reset} read macos keychain for claude authentication" \
|
|
96
|
+
"${dim}•${reset} optionally access ~/library/messages for imessage relay" \
|
|
97
|
+
"${dim}•${reset} run a local web server on port 6767" \
|
|
98
|
+
"" \
|
|
99
|
+
"claudity is experimental software that can read," \
|
|
100
|
+
"create, edit and delete files. please use with" \
|
|
101
|
+
"extreme caution."
|
|
102
|
+
|
|
103
|
+
echo ""
|
|
104
|
+
while true; do
|
|
105
|
+
echo -en " type ${green}i understand${reset} to continue ${dim}(esc to exit)${reset}: "
|
|
106
|
+
confirm=""
|
|
107
|
+
while IFS= read -rsn1 char </dev/tty; do
|
|
108
|
+
if [ "$char" = $'\x1b' ]; then
|
|
109
|
+
read -rsn2 -t 0.1 _ </dev/tty 2>/dev/null
|
|
110
|
+
echo ""
|
|
111
|
+
echo ""
|
|
112
|
+
info "installation cancelled"
|
|
113
|
+
echo ""
|
|
114
|
+
exit 0
|
|
115
|
+
elif [ "$char" = "" ]; then
|
|
116
|
+
echo ""
|
|
117
|
+
break
|
|
118
|
+
elif [ "$char" = $'\x7f' ] || [ "$char" = $'\b' ]; then
|
|
119
|
+
if [ -n "$confirm" ]; then
|
|
120
|
+
confirm="${confirm%?}"
|
|
121
|
+
printf '\b \b'
|
|
122
|
+
fi
|
|
123
|
+
else
|
|
124
|
+
confirm="${confirm}${char}"
|
|
125
|
+
printf '%s' "$char"
|
|
126
|
+
fi
|
|
127
|
+
done
|
|
128
|
+
normalized=$(echo "$confirm" | tr '[:upper:]' '[:lower:]')
|
|
129
|
+
if [ "$normalized" = "i understand" ]; then
|
|
130
|
+
break
|
|
131
|
+
fi
|
|
132
|
+
done
|
|
133
|
+
|
|
134
|
+
step "xcode command line tools"
|
|
135
|
+
if xcode-select -p &>/dev/null; then
|
|
136
|
+
ok "already installed"
|
|
137
|
+
else
|
|
138
|
+
xcode-select --install 2>/dev/null || true
|
|
139
|
+
warn "a dialog may appear — click install and wait"
|
|
140
|
+
elapsed=0
|
|
141
|
+
timeout=1800
|
|
142
|
+
chars="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
|
|
143
|
+
i=0
|
|
144
|
+
while ! xcode-select -p &>/dev/null; do
|
|
145
|
+
c="${chars:i%10:1}"
|
|
146
|
+
printf "\r \033[92m%s\033[0m waiting for xcode cli tools..." "$c"
|
|
147
|
+
i=$((i + 1))
|
|
148
|
+
sleep 5
|
|
149
|
+
elapsed=$((elapsed + 5))
|
|
150
|
+
if [ "$elapsed" -ge "$timeout" ]; then
|
|
151
|
+
printf "\r"
|
|
152
|
+
fail "timed out waiting for xcode cli tools"
|
|
153
|
+
fi
|
|
154
|
+
done
|
|
155
|
+
printf "\r"
|
|
156
|
+
ok "xcode cli tools installed"
|
|
157
|
+
fi
|
|
158
|
+
|
|
159
|
+
step "homebrew"
|
|
160
|
+
if command -v brew &>/dev/null; then
|
|
161
|
+
ok "already installed"
|
|
162
|
+
else
|
|
163
|
+
info "installing homebrew..."
|
|
164
|
+
NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" >/tmp/claudity-install.log 2>&1
|
|
165
|
+
if [ -f /opt/homebrew/bin/brew ]; then
|
|
166
|
+
eval "$(/opt/homebrew/bin/brew shellenv)"
|
|
167
|
+
elif [ -f /usr/local/bin/brew ]; then
|
|
168
|
+
eval "$(/usr/local/bin/brew shellenv)"
|
|
169
|
+
fi
|
|
170
|
+
ok "homebrew installed"
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
BREW_PREFIX="$(brew --prefix 2>/dev/null || echo "/opt/homebrew")"
|
|
174
|
+
SHELLENV_LINE="eval \"\$(${BREW_PREFIX}/bin/brew shellenv)\""
|
|
175
|
+
ZPROFILE="$HOME/.zprofile"
|
|
176
|
+
if [ -f "$ZPROFILE" ]; then
|
|
177
|
+
if ! grep -qF "brew shellenv" "$ZPROFILE"; then
|
|
178
|
+
echo "$SHELLENV_LINE" >> "$ZPROFILE"
|
|
179
|
+
info "added brew to ~/.zprofile"
|
|
180
|
+
fi
|
|
181
|
+
else
|
|
182
|
+
echo "$SHELLENV_LINE" > "$ZPROFILE"
|
|
183
|
+
info "created ~/.zprofile with brew path"
|
|
184
|
+
fi
|
|
185
|
+
|
|
186
|
+
step "node.js"
|
|
187
|
+
need_node=false
|
|
188
|
+
if command -v node &>/dev/null; then
|
|
189
|
+
NODE_VER=$(node -v | cut -d. -f1 | tr -d 'v')
|
|
190
|
+
if [ "$NODE_VER" -ge 18 ]; then
|
|
191
|
+
ok "$(node -v)"
|
|
192
|
+
else
|
|
193
|
+
warn "found node $(node -v), need 18+"
|
|
194
|
+
need_node=true
|
|
195
|
+
fi
|
|
196
|
+
else
|
|
197
|
+
need_node=true
|
|
198
|
+
fi
|
|
199
|
+
if [ "$need_node" = true ]; then
|
|
200
|
+
spin "installing node.js" brew install node
|
|
201
|
+
ok "$(node -v)"
|
|
202
|
+
fi
|
|
203
|
+
|
|
204
|
+
step "claude code cli"
|
|
205
|
+
if command -v claude &>/dev/null; then
|
|
206
|
+
ok "already installed"
|
|
207
|
+
else
|
|
208
|
+
spin "installing claude code cli" npm install -g @anthropic-ai/claude-code
|
|
209
|
+
fi
|
|
210
|
+
|
|
211
|
+
step "downloading claudity"
|
|
212
|
+
INSTALL_DIR="$HOME/claudity"
|
|
213
|
+
REPO_URL="https://github.com/flavormingo/claudity.git"
|
|
214
|
+
if [ -d "$INSTALL_DIR/.git" ]; then
|
|
215
|
+
spin "updating claudity" git -C "$INSTALL_DIR" pull --ff-only
|
|
216
|
+
elif [ -d "$INSTALL_DIR" ]; then
|
|
217
|
+
ok "already installed"
|
|
218
|
+
else
|
|
219
|
+
spin "cloning claudity" git clone "$REPO_URL" "$INSTALL_DIR"
|
|
220
|
+
fi
|
|
221
|
+
|
|
222
|
+
step "installing dependencies"
|
|
223
|
+
spin "npm install" bash -c "cd '$INSTALL_DIR' && npm install"
|
|
224
|
+
|
|
225
|
+
step "configuring environment"
|
|
226
|
+
ENV_FILE="$INSTALL_DIR/.env"
|
|
227
|
+
if [ ! -f "$ENV_FILE" ]; then
|
|
228
|
+
echo "PORT=6767" > "$ENV_FILE"
|
|
229
|
+
echo "RELAY_SECRET=$(openssl rand -hex 24)" >> "$ENV_FILE"
|
|
230
|
+
ok "created .env"
|
|
231
|
+
else
|
|
232
|
+
if ! grep -q '^RELAY_SECRET=' "$ENV_FILE" || grep -q 'change-me' "$ENV_FILE"; then
|
|
233
|
+
SECRET=$(openssl rand -hex 24)
|
|
234
|
+
if grep -q '^RELAY_SECRET=' "$ENV_FILE"; then
|
|
235
|
+
sed -i '' "s|^RELAY_SECRET=.*|RELAY_SECRET=$SECRET|" "$ENV_FILE"
|
|
236
|
+
else
|
|
237
|
+
echo "RELAY_SECRET=$SECRET" >> "$ENV_FILE"
|
|
238
|
+
fi
|
|
239
|
+
info "generated relay secret"
|
|
240
|
+
fi
|
|
241
|
+
ok ".env already exists"
|
|
242
|
+
fi
|
|
243
|
+
|
|
244
|
+
step "authentication"
|
|
245
|
+
KEYCHAIN_CREDS=$(security find-generic-password -s "Claude Code-credentials" -w 2>/dev/null || true)
|
|
246
|
+
if [ -n "$KEYCHAIN_CREDS" ]; then
|
|
247
|
+
ok "found oauth credentials in keychain"
|
|
248
|
+
else
|
|
249
|
+
HAS_API_KEY=""
|
|
250
|
+
if [ -f "$ENV_FILE" ]; then
|
|
251
|
+
HAS_API_KEY=$(grep '^API_KEY=' "$ENV_FILE" 2>/dev/null | cut -d= -f2-)
|
|
252
|
+
fi
|
|
253
|
+
if [ -n "$HAS_API_KEY" ]; then
|
|
254
|
+
ok "using api key from .env"
|
|
255
|
+
else
|
|
256
|
+
warn "no authentication found"
|
|
257
|
+
echo ""
|
|
258
|
+
echo -e " ${green}1${reset}) run ${green}claude login${reset} now ${dim}(recommended)${reset}"
|
|
259
|
+
echo -e " ${green}2${reset}) skip — configure later via web ui"
|
|
260
|
+
echo ""
|
|
261
|
+
echo -en " choice ${dim}[1/2]${reset}: "
|
|
262
|
+
read -r auth_choice </dev/tty
|
|
263
|
+
if [ "$auth_choice" != "2" ]; then
|
|
264
|
+
echo ""
|
|
265
|
+
info "launching claude login..."
|
|
266
|
+
echo ""
|
|
267
|
+
claude login </dev/tty
|
|
268
|
+
echo ""
|
|
269
|
+
KEYCHAIN_CREDS=$(security find-generic-password -s "Claude Code-credentials" -w 2>/dev/null || true)
|
|
270
|
+
if [ -n "$KEYCHAIN_CREDS" ]; then
|
|
271
|
+
ok "authenticated successfully"
|
|
272
|
+
else
|
|
273
|
+
warn "credentials not detected — you can authenticate later"
|
|
274
|
+
fi
|
|
275
|
+
else
|
|
276
|
+
info "skipped — authenticate at http://localhost:6767"
|
|
277
|
+
fi
|
|
278
|
+
fi
|
|
279
|
+
fi
|
|
280
|
+
|
|
281
|
+
step "imessage relay"
|
|
282
|
+
echo -e " ${dim}chat with your agents over imessage by texting yourself${reset}"
|
|
283
|
+
echo ""
|
|
284
|
+
echo -en " enable imessage relay? ${dim}[y/n]${reset} "
|
|
285
|
+
read -r imsg_choice </dev/tty
|
|
286
|
+
if [[ "$imsg_choice" =~ ^[yY] ]]; then
|
|
287
|
+
CHAT_DB="$HOME/Library/Messages/chat.db"
|
|
288
|
+
if ! sqlite3 "$CHAT_DB" "select 1 limit 1" &>/dev/null; then
|
|
289
|
+
echo ""
|
|
290
|
+
warn "terminal needs full disk access to read imessages"
|
|
291
|
+
warn "system settings → privacy & security → full disk access → enable your terminal app"
|
|
292
|
+
echo ""
|
|
293
|
+
info "after granting access, run setup again"
|
|
294
|
+
else
|
|
295
|
+
info "full disk access: ok"
|
|
296
|
+
fi
|
|
297
|
+
|
|
298
|
+
echo -en " your phone number ${dim}(e.g. +15551234567)${reset}: "
|
|
299
|
+
read -r PHONE </dev/tty
|
|
300
|
+
if [ -z "$PHONE" ]; then
|
|
301
|
+
warn "no phone number provided, skipping imessage relay"
|
|
302
|
+
else
|
|
303
|
+
if grep -q '^IMESSAGE_PHONE=' "$ENV_FILE"; then
|
|
304
|
+
sed -i '' "s|^IMESSAGE_PHONE=.*|IMESSAGE_PHONE=$PHONE|" "$ENV_FILE"
|
|
305
|
+
else
|
|
306
|
+
echo "IMESSAGE_PHONE=$PHONE" >> "$ENV_FILE"
|
|
307
|
+
fi
|
|
308
|
+
if grep -q '^IMESSAGE_RELAY=' "$ENV_FILE"; then
|
|
309
|
+
sed -i '' "s|^IMESSAGE_RELAY=.*|IMESSAGE_RELAY=true|" "$ENV_FILE"
|
|
310
|
+
else
|
|
311
|
+
echo "IMESSAGE_RELAY=true" >> "$ENV_FILE"
|
|
312
|
+
fi
|
|
313
|
+
ok "imessage relay enabled"
|
|
314
|
+
fi
|
|
315
|
+
else
|
|
316
|
+
if [ -f "$ENV_FILE" ] && grep -q '^IMESSAGE_RELAY=' "$ENV_FILE"; then
|
|
317
|
+
sed -i '' "s|^IMESSAGE_RELAY=.*|IMESSAGE_RELAY=false|" "$ENV_FILE"
|
|
318
|
+
fi
|
|
319
|
+
info "skipped"
|
|
320
|
+
fi
|
|
321
|
+
|
|
322
|
+
echo ""
|
|
323
|
+
info "for signal support: ${green}brew install signal-cli${reset}"
|
|
324
|
+
|
|
325
|
+
step "starting claudity..."
|
|
326
|
+
cd "$INSTALL_DIR" && node src/index.js &
|
|
327
|
+
CLAUDITY_PID=$!
|
|
328
|
+
sleep 2
|
|
329
|
+
|
|
330
|
+
if kill -0 "$CLAUDITY_PID" 2>/dev/null; then
|
|
331
|
+
ok "claudity is running"
|
|
332
|
+
else
|
|
333
|
+
warn "failed to start — run manually with: cd ~/claudity && npm start"
|
|
334
|
+
fi
|
|
335
|
+
|
|
336
|
+
boxlines \
|
|
337
|
+
"${bold}${green}claudity is ready${reset}" \
|
|
338
|
+
"" \
|
|
339
|
+
"${green}http://localhost:6767${reset}" \
|
|
340
|
+
"" \
|
|
341
|
+
"${dim}next time: cd ~/claudity && npm start${reset}"
|
|
342
|
+
|
|
343
|
+
echo ""
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "claudity",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "evolving agents that live where you chat ★ powered by claude code",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"claudity": "src/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"setup": "bash setup.sh",
|
|
11
|
+
"start": "node src/index.js",
|
|
12
|
+
"dev": "node --watch src/index.js"
|
|
13
|
+
},
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=18.0.0"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@slack/bolt": "^4.6.0",
|
|
19
|
+
"better-sqlite3": "^11.7.0",
|
|
20
|
+
"discord.js": "^14.25.1",
|
|
21
|
+
"dotenv": "^16.4.7",
|
|
22
|
+
"express": "^4.21.2",
|
|
23
|
+
"node-telegram-bot-api": "^0.67.0",
|
|
24
|
+
"qrcode": "^1.5.4",
|
|
25
|
+
"uuid": "^11.0.5",
|
|
26
|
+
"whatsapp-web.js": "^1.34.6"
|
|
27
|
+
}
|
|
28
|
+
}
|