agent-nuvira 1.63.0 → 1.63.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/whatsapp.d.ts +3 -2
- package/dist/cli/whatsapp.d.ts.map +1 -1
- package/dist/cli/whatsapp.js +37 -8
- package/dist/cli/whatsapp.js.map +1 -1
- package/dist/gateway/whatsapp/baileys-bridge.d.ts +43 -4
- package/dist/gateway/whatsapp/baileys-bridge.d.ts.map +1 -1
- package/dist/gateway/whatsapp/baileys-bridge.js +79 -8
- package/dist/gateway/whatsapp/baileys-bridge.js.map +1 -1
- package/package.json +3 -1
package/dist/cli/whatsapp.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WhatsAppCommand — I8 WhatsApp bridge CLI (Hermes `hermes whatsapp` parity).
|
|
3
3
|
*
|
|
4
|
-
* buff whatsapp pair
|
|
5
|
-
* buff whatsapp
|
|
4
|
+
* buff whatsapp pair — QR-pair a personal number (Baileys bridge, no paid API)
|
|
5
|
+
* buff whatsapp pair --phone 91… — pair by entering an 8-char code on the phone instead
|
|
6
|
+
* buff whatsapp status — show the bridge session + pairing state
|
|
6
7
|
*
|
|
7
8
|
* The default `whatsapp` platform is the personal Baileys bridge; the paid
|
|
8
9
|
* Meta Business API stays available as the separate `whatsapp_cloud` platform
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"whatsapp.d.ts","sourceRoot":"","sources":["../../src/cli/whatsapp.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"whatsapp.d.ts","sourceRoot":"","sources":["../../src/cli/whatsapp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,qBAAa,eAAe;IAC1B,MAAM,IAAI,OAAO;CA4ElB"}
|
package/dist/cli/whatsapp.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WhatsAppCommand — I8 WhatsApp bridge CLI (Hermes `hermes whatsapp` parity).
|
|
3
3
|
*
|
|
4
|
-
* buff whatsapp pair
|
|
5
|
-
* buff whatsapp
|
|
4
|
+
* buff whatsapp pair — QR-pair a personal number (Baileys bridge, no paid API)
|
|
5
|
+
* buff whatsapp pair --phone 91… — pair by entering an 8-char code on the phone instead
|
|
6
|
+
* buff whatsapp status — show the bridge session + pairing state
|
|
6
7
|
*
|
|
7
8
|
* The default `whatsapp` platform is the personal Baileys bridge; the paid
|
|
8
9
|
* Meta Business API stays available as the separate `whatsapp_cloud` platform
|
|
@@ -11,7 +12,7 @@
|
|
|
11
12
|
*/
|
|
12
13
|
import { Command } from 'commander';
|
|
13
14
|
import { logger } from '../utils/logger.js';
|
|
14
|
-
import { BaileysBridge } from '../gateway/whatsapp/baileys-bridge.js';
|
|
15
|
+
import { BaileysBridge, normalizePairingPhone } from '../gateway/whatsapp/baileys-bridge.js';
|
|
15
16
|
import { whatsappSessionDir, hasWhatsAppSession } from '../gateway/whatsapp/session.js';
|
|
16
17
|
import { guardRbacAction } from './rbac-guard.js';
|
|
17
18
|
export class WhatsAppCommand {
|
|
@@ -20,7 +21,8 @@ export class WhatsAppCommand {
|
|
|
20
21
|
.description('WhatsApp bridge (Baileys) — pair a personal number via QR and check status (I8)');
|
|
21
22
|
cmd
|
|
22
23
|
.command('pair')
|
|
23
|
-
.description('Pair WhatsApp
|
|
24
|
+
.description('Pair WhatsApp (personal number — no Meta Business account, no paid API)')
|
|
25
|
+
.option('--phone <number>', 'Pair via phone number instead of a QR: enter the 8-char code under WhatsApp → Linked devices → Link with phone number instead (full international format, no +, e.g. 918800663237)')
|
|
24
26
|
.option('--timeout <seconds>', 'Pairing window in seconds', '90')
|
|
25
27
|
.action(async (opts) => {
|
|
26
28
|
// Pairing writes a session under ~/.buff/whatsapp/session — treat it
|
|
@@ -29,18 +31,45 @@ export class WhatsAppCommand {
|
|
|
29
31
|
return;
|
|
30
32
|
const dir = whatsappSessionDir();
|
|
31
33
|
const timeoutMs = Math.max(15, parseInt(opts.timeout ?? '90', 10) || 90) * 1000;
|
|
34
|
+
const phone = opts.phone ? normalizePairingPhone(opts.phone) : '';
|
|
35
|
+
if (opts.phone && !phone) {
|
|
36
|
+
logger.error(`Invalid phone number '${opts.phone}' — use full international format with country code (no + or spaces), e.g. 918800663237`);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (phone && phone.length === 10) {
|
|
40
|
+
logger.warn(`'${phone}' looks like a local number without its country code — WhatsApp needs the full international format (e.g. 91${phone} for India). Proceeding with '${phone}' as-is; re-run with --phone 91${phone} if pairing fails.`);
|
|
41
|
+
}
|
|
32
42
|
if (hasWhatsAppSession(dir)) {
|
|
33
43
|
logger.warn(`A paired session already exists at ${dir} — pairing again will replace it.`);
|
|
34
44
|
}
|
|
35
45
|
const bridge = new BaileysBridge(dir);
|
|
36
|
-
|
|
46
|
+
if (phone) {
|
|
47
|
+
logger.info('Pairing by phone number. On the phone with that WhatsApp number:');
|
|
48
|
+
logger.info(' 1. WhatsApp → Linked devices → Link a device');
|
|
49
|
+
logger.info(' 2. Tap "Link with phone number instead"');
|
|
50
|
+
logger.info(' 3. Enter the 8-character code shown below');
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
logger.info('Scan the QR code below with your phone:');
|
|
54
|
+
logger.info(' WhatsApp → Linked devices → Link a device → scan the QR');
|
|
55
|
+
logger.info('The QR refreshes automatically — scan it within the pairing window.');
|
|
56
|
+
}
|
|
37
57
|
logger.info(`Session will be stored at: ${dir}`);
|
|
38
|
-
const result = await bridge.pair(
|
|
58
|
+
const result = await bridge.pair({
|
|
59
|
+
phoneNumber: phone || undefined,
|
|
60
|
+
timeoutMs,
|
|
61
|
+
// Raw payload at debug — some people feed it into external QR tools.
|
|
62
|
+
onQr: (qr) => logger.debug(`QR payload: ${qr}`),
|
|
63
|
+
// The scannable QR must print raw (no logger prefix/redaction) or
|
|
64
|
+
// scanning breaks.
|
|
65
|
+
onQrRendered: (rendered) => console.log(`\n${rendered}\n`),
|
|
66
|
+
onPairingCode: (code) => console.log(`\n🔑 Pairing code: ${code}\n`),
|
|
67
|
+
});
|
|
39
68
|
if (result.ok) {
|
|
40
|
-
logger.success('
|
|
69
|
+
logger.success('Paired — the WhatsApp bridge is ready. Run `buff whatsapp status` to confirm.');
|
|
41
70
|
}
|
|
42
71
|
else {
|
|
43
|
-
logger.error(
|
|
72
|
+
logger.error(result.reason);
|
|
44
73
|
}
|
|
45
74
|
});
|
|
46
75
|
cmd
|
package/dist/cli/whatsapp.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"whatsapp.js","sourceRoot":"","sources":["../../src/cli/whatsapp.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"whatsapp.js","sourceRoot":"","sources":["../../src/cli/whatsapp.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,35 @@
|
|
|
11
11
|
* `useMultiFileAuthState` — the same layout Hermes' bridge uses.
|
|
12
12
|
*/
|
|
13
13
|
import { type WhatsAppBridge } from './bridge.js';
|
|
14
|
+
/** Options for {@link BaileysBridge.pair}. */
|
|
15
|
+
export interface PairOptions {
|
|
16
|
+
/** Called with the raw QR payload (Baileys `connection.update.qr`). */
|
|
17
|
+
onQr?: (qr: string) => void;
|
|
18
|
+
/** Called with a pre-rendered, scannable terminal QR (qrcode blocks). */
|
|
19
|
+
onQrRendered?: (rendered: string) => void;
|
|
20
|
+
/** Called with the 8-char "link with phone number instead" pairing code. */
|
|
21
|
+
onPairingCode?: (code: string) => void;
|
|
22
|
+
/** Pairing window in ms (default 90s). */
|
|
23
|
+
timeoutMs?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Pair via phone number (Baileys `requestPairingCode`) instead of a QR:
|
|
26
|
+
* the user enters the 8-char code under WhatsApp → Linked devices → Link
|
|
27
|
+
* with phone number instead. Full international format, no leading '+'.
|
|
28
|
+
*/
|
|
29
|
+
phoneNumber?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Render a QR payload to a scannable terminal QR (qrcode block characters).
|
|
33
|
+
* Best-effort: returns '' if `qrcode` can't be loaded. Lazily imported so the
|
|
34
|
+
* rest of the gateway never pays for it.
|
|
35
|
+
*/
|
|
36
|
+
export declare function renderQrToTerminal(qr: string): Promise<string>;
|
|
37
|
+
/**
|
|
38
|
+
* Normalize a user-supplied phone for `requestPairingCode`: digits only, no
|
|
39
|
+
* leading '+', must include the country code (10–15 digits). Returns '' if
|
|
40
|
+
* invalid.
|
|
41
|
+
*/
|
|
42
|
+
export declare function normalizePairingPhone(phone: string): string;
|
|
14
43
|
export declare class BaileysBridge implements WhatsAppBridge {
|
|
15
44
|
private readonly sessionDir;
|
|
16
45
|
private sock;
|
|
@@ -23,11 +52,21 @@ export declare class BaileysBridge implements WhatsAppBridge {
|
|
|
23
52
|
disconnect(): Promise<void>;
|
|
24
53
|
send(target: string, text: string): Promise<boolean>;
|
|
25
54
|
/**
|
|
26
|
-
* Interactive
|
|
27
|
-
*
|
|
28
|
-
*
|
|
55
|
+
* Interactive pairing (the `buff whatsapp pair` flow).
|
|
56
|
+
*
|
|
57
|
+
* QR mode (default): surfaces the raw payload via `onQr` and a scannable
|
|
58
|
+
* terminal QR via `onQrRendered` (qrcode block characters). Baileys 7.x
|
|
59
|
+
* deprecated `printQRInTerminal` — it no longer prints anything — so the
|
|
60
|
+
* QR is rendered here from `connection.update.qr`.
|
|
61
|
+
*
|
|
62
|
+
* Phone mode (`phoneNumber` set): requests an 8-char pairing code via
|
|
63
|
+
* Baileys `requestPairingCode` and surfaces it via `onPairingCode` — the
|
|
64
|
+
* user enters it under WhatsApp → Linked devices → Link with phone number
|
|
65
|
+
* instead (handy on headless/remote hosts where scanning is impossible).
|
|
66
|
+
*
|
|
67
|
+
* Resolves ok once the connection opens.
|
|
29
68
|
*/
|
|
30
|
-
pair(
|
|
69
|
+
pair(opts?: PairOptions): Promise<{
|
|
31
70
|
ok: boolean;
|
|
32
71
|
reason: string;
|
|
33
72
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"baileys-bridge.d.ts","sourceRoot":"","sources":["../../../src/gateway/whatsapp/baileys-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"baileys-bridge.d.ts","sourceRoot":"","sources":["../../../src/gateway/whatsapp/baileys-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAkCxE,8CAA8C;AAC9C,MAAM,WAAW,WAAW;IAC1B,uEAAuE;IACvE,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,yEAAyE;IACzE,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,4EAA4E;IAC5E,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAOpE;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAG3D;AA6BD,qBAAa,aAAc,YAAW,cAAc;IAItC,OAAO,CAAC,QAAQ,CAAC,UAAU;IAHvC,OAAO,CAAC,IAAI,CAA6B;IACzC,OAAO,CAAC,SAAS,CAA0D;gBAE9C,UAAU,GAAE,MAA6B;IAEtE,+EAA+E;IAC/E,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,QAAQ,IAAI,MAAM;IAOZ,OAAO,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAK1E,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAU3B,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAc1D;;;;;;;;;;;;;;OAcG;IACG,IAAI,CAAC,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAiF5E,0EAA0E;YAC5D,YAAY;IAgC1B,yEAAyE;IACzE,OAAO,CAAC,WAAW;CAkBpB"}
|
|
@@ -22,6 +22,29 @@ function sessionHasCreds(dir) {
|
|
|
22
22
|
return false;
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Render a QR payload to a scannable terminal QR (qrcode block characters).
|
|
27
|
+
* Best-effort: returns '' if `qrcode` can't be loaded. Lazily imported so the
|
|
28
|
+
* rest of the gateway never pays for it.
|
|
29
|
+
*/
|
|
30
|
+
export async function renderQrToTerminal(qr) {
|
|
31
|
+
try {
|
|
32
|
+
const mod = await import('qrcode');
|
|
33
|
+
return await mod.toString(qr, { type: 'terminal', small: true });
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return '';
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Normalize a user-supplied phone for `requestPairingCode`: digits only, no
|
|
41
|
+
* leading '+', must include the country code (10–15 digits). Returns '' if
|
|
42
|
+
* invalid.
|
|
43
|
+
*/
|
|
44
|
+
export function normalizePairingPhone(phone) {
|
|
45
|
+
const digits = (phone || '').replace(/\D+/g, '');
|
|
46
|
+
return /^\d{10,15}$/.test(digits) ? digits : '';
|
|
47
|
+
}
|
|
25
48
|
/** Silent pino-shaped logger so Baileys' internal noise never pollutes CLI output. */
|
|
26
49
|
const QUIET_LOGGER = {
|
|
27
50
|
level: 'silent',
|
|
@@ -96,18 +119,42 @@ export class BaileysBridge {
|
|
|
96
119
|
}
|
|
97
120
|
}
|
|
98
121
|
/**
|
|
99
|
-
* Interactive
|
|
100
|
-
*
|
|
101
|
-
*
|
|
122
|
+
* Interactive pairing (the `buff whatsapp pair` flow).
|
|
123
|
+
*
|
|
124
|
+
* QR mode (default): surfaces the raw payload via `onQr` and a scannable
|
|
125
|
+
* terminal QR via `onQrRendered` (qrcode block characters). Baileys 7.x
|
|
126
|
+
* deprecated `printQRInTerminal` — it no longer prints anything — so the
|
|
127
|
+
* QR is rendered here from `connection.update.qr`.
|
|
128
|
+
*
|
|
129
|
+
* Phone mode (`phoneNumber` set): requests an 8-char pairing code via
|
|
130
|
+
* Baileys `requestPairingCode` and surfaces it via `onPairingCode` — the
|
|
131
|
+
* user enters it under WhatsApp → Linked devices → Link with phone number
|
|
132
|
+
* instead (handy on headless/remote hosts where scanning is impossible).
|
|
133
|
+
*
|
|
134
|
+
* Resolves ok once the connection opens.
|
|
102
135
|
*/
|
|
103
|
-
async pair(
|
|
136
|
+
async pair(opts = {}) {
|
|
137
|
+
const timeoutMs = opts.timeoutMs ?? 90_000;
|
|
138
|
+
const phone = opts.phoneNumber ? normalizePairingPhone(opts.phoneNumber) : '';
|
|
139
|
+
if (opts.phoneNumber && !phone) {
|
|
140
|
+
return {
|
|
141
|
+
ok: false,
|
|
142
|
+
reason: `invalid phone number '${opts.phoneNumber}' — use full international format with country code, e.g. 918800663237`,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
104
145
|
try {
|
|
105
146
|
const baileys = await loadBaileys();
|
|
106
147
|
if (!baileys)
|
|
107
148
|
return { ok: false, reason: 'cannot load the Baileys bridge (is `baileys` installed?)' };
|
|
108
149
|
mkdirSync(this.sessionDir, { recursive: true, mode: 0o700 });
|
|
109
150
|
const { state, saveCreds } = await baileys.useMultiFileAuthState(this.sessionDir);
|
|
110
|
-
const sock = baileys.makeWASocket({
|
|
151
|
+
const sock = baileys.makeWASocket({
|
|
152
|
+
auth: state,
|
|
153
|
+
// printQRInTerminal is DEPRECATED and a no-op in baileys ≥6.7 — the QR
|
|
154
|
+
// only arrives via connection.update, and we render it ourselves.
|
|
155
|
+
printQRInTerminal: false,
|
|
156
|
+
logger: QUIET_LOGGER,
|
|
157
|
+
});
|
|
111
158
|
sock.ev?.on('creds.update', () => void saveCreds());
|
|
112
159
|
return await new Promise((resolve) => {
|
|
113
160
|
const timer = setTimeout(() => {
|
|
@@ -117,12 +164,24 @@ export class BaileysBridge {
|
|
|
117
164
|
catch {
|
|
118
165
|
/* best-effort */
|
|
119
166
|
}
|
|
120
|
-
resolve({ ok: false, reason: 'pairing timed out — scan the QR within the window' });
|
|
167
|
+
resolve({ ok: false, reason: 'pairing timed out — scan the QR / enter the code within the window' });
|
|
121
168
|
}, timeoutMs);
|
|
122
169
|
sock.ev?.on('connection.update', (...args) => {
|
|
123
170
|
const u = (args[0] ?? {});
|
|
124
|
-
if (u.qr)
|
|
125
|
-
onQr?.(u.qr);
|
|
171
|
+
if (u.qr) {
|
|
172
|
+
opts.onQr?.(u.qr);
|
|
173
|
+
if (phone) {
|
|
174
|
+
// In phone mode the 8-char code can also arrive here.
|
|
175
|
+
if (/^\d{8}$/.test(u.qr))
|
|
176
|
+
opts.onPairingCode?.(u.qr);
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
void renderQrToTerminal(u.qr).then((rendered) => {
|
|
180
|
+
if (rendered)
|
|
181
|
+
opts.onQrRendered?.(rendered);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
126
185
|
if (u.connection === 'open') {
|
|
127
186
|
clearTimeout(timer);
|
|
128
187
|
this.sock = sock;
|
|
@@ -137,6 +196,18 @@ export class BaileysBridge {
|
|
|
137
196
|
}
|
|
138
197
|
}
|
|
139
198
|
});
|
|
199
|
+
if (phone) {
|
|
200
|
+
// Request the 8-char pairing code; also arrives via connection.update.
|
|
201
|
+
void sock
|
|
202
|
+
.requestPairingCode?.(phone)
|
|
203
|
+
.then((code) => {
|
|
204
|
+
if (code)
|
|
205
|
+
opts.onPairingCode?.(code);
|
|
206
|
+
})
|
|
207
|
+
.catch(() => {
|
|
208
|
+
/* best-effort — connection.update may still carry the code */
|
|
209
|
+
});
|
|
210
|
+
}
|
|
140
211
|
});
|
|
141
212
|
}
|
|
142
213
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"baileys-bridge.js","sourceRoot":"","sources":["../../../src/gateway/whatsapp/baileys-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,oBAAoB,EAAuB,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"baileys-bridge.js","sourceRoot":"","sources":["../../../src/gateway/whatsapp/baileys-bridge.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-nuvira",
|
|
3
|
-
"version": "1.63.
|
|
3
|
+
"version": "1.63.1",
|
|
4
4
|
"description": "Agent-Nuvira: Multi-agent AI coding CLI — plan, write, review, test, and publish code with local models (Ollama) or cloud APIs (Groq, NVIDIA NIM, Google Gemini, OpenRouter)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -80,6 +80,7 @@
|
|
|
80
80
|
"inquirer": "^9.3.0",
|
|
81
81
|
"node-cron": "^4.6.0",
|
|
82
82
|
"ora": "^8.0.0",
|
|
83
|
+
"qrcode": "^1.5.4",
|
|
83
84
|
"react": "^18.3.1",
|
|
84
85
|
"typescript": "^5.3.0",
|
|
85
86
|
"zod": "^4.4.3"
|
|
@@ -92,6 +93,7 @@
|
|
|
92
93
|
"devDependencies": {
|
|
93
94
|
"@types/inquirer": "^9.0.10",
|
|
94
95
|
"@types/node": "^20.11.0",
|
|
96
|
+
"@types/qrcode": "^1.5.6",
|
|
95
97
|
"@types/react": "^18.3.31",
|
|
96
98
|
"ink-testing-library": "^4.0.0",
|
|
97
99
|
"tsx": "^4.7.0",
|