Files
Jobs_Applier_AI_Agent/apps/cli/package.json
T
feder-cr e7b80098e1 host: WhatsApp through Baileys, opt-in
WhatsApp becomes the second channel of the hub, as an explicit opt-in adapter
over Baileys (7.0.0-rc14, pinned exactly), after the owner's decision to take
Telegram first and Baileys next (Q3). It is off unless the server is started
with INVISIBLE_DOTS_WHATSAPP=1: otherwise the type does not exist, GET
.../channels lists only the kinds the server runs (`available`) and linking is a
400 that says how to turn it on. It is not an official way to use WhatsApp and
the account can be banned; README, architecture 9.8 and the CLI say so.

Adapter (packages/channels/src/whatsapp-baileys/)
- port.ts: what the channel needs of a connection. baileys.ts is the only glue
  (types plus one dynamic import() when a connection opens, so a server that never
  links WhatsApp never loads it); FakeWhatsAppConnector implements the port for
  tests. whatsapp.ts holds the decisions, tested against the fake.
- auth-state.ts: Baileys' AuthenticationState over the encrypted secrets of the
  Dot, one secret for the credentials and one per key group (a Record over the
  library's own group list), written in order before Baileys is told, never
  plaintext files, never sent to the guest, deleted with the channel and the Dot.
- Who is who: the phone number when known (address, twin address, or what the
  account learned, locally), else the LID, so one person is one peer. Reply-only:
  nothing to a chat that did not write first, no groups, no own messages, no
  attachments; a stranger gets no reply, no read receipt, no typing; a read
  receipt, a typing indicator and a short pause go before each send.
- Approvals in words: the prompt ends with `Reply "yes ap-xxxxxx" ...`; the hub
  reads exactly that from a paired owner (ChannelCapabilities.approvalByText) with
  the same checks and the same resolveApproval as a button. A bare yes is a message.

Hub and host
- ChannelHub.link/watchLink/kinds, LinkSessions (the code to scan lives in memory
  only: not stored, not logged, not an event), ChannelSink.linkCode, ChannelType
  scanned/scrubNames/pairingMessage, create() gets put/delete on the secrets.
- Routes POST .../whatsapp/link (202) and GET .../whatsapp/qr (SSE of
  ChannelLinkFrame, no-store), the SSE framing of /api/stream moved to one helper.
  SDK linkWhatsApp/whatsappLink/channelsOverview. CLI `channel link whatsapp`
  (risk text, QR in the terminal, --json frames).
- A binding that needs its person is no longer started when the server starts:
  connecting with what is known to be refused only gets it refused again, which
  counts against a WhatsApp account.
- ChannelRecord.bot_username is renamed `account` (it now holds a phone number
  too); ChannelPairingAnswer gains `message` (what to send to pair).
- ApprovalsRepository.endingWith, ChannelsRepository.setStatus can clear the
  account. No migration: the kind column already allowed 'whatsapp'.

License: Baileys depends on libsignal, which is GPL-3.0. Nothing of it is in the
repository, and the command bundle now leaves baileys out (external in
apps/cli/scripts/build.mjs), so no build of ours embeds GPL code; a test keeps
that, and THIRD_PARTY_NOTICES.md and the README say what it means.

Tests (new): whatsapp.test.ts (channel on the fake: identity, policy, sending,
how a connection ends), hub-whatsapp.test.ts (linking, pairing, talking, strangers,
approvals in words, status), whatsapp-auth.test.ts (the state on real encrypted
secrets with the real Baileys helpers), baileys.test.ts (message reading over
Baileys' own protobuf, close codes, a socket that cannot connect), apps/api
whatsapp.test.ts (routes, SSE), SDK and CLI tests, LinkSessions, the reply words,
repository tests, tests/repo/whatsapp-optin.test.ts (exact pin, one glue file, lazy
import, out of the bundle). The real WhatsApp network is not reached by any test.

Removed tests: none.

Existing tests changed, none weakened: bot_username -> account (hub, hub-telegram,
api, cli, sdk); the Telegram test sink and FakeChannelType gained the new members
(linkCode, scrubNames, approvalByText, pairingMessage); the CLI usage-error
assertions name `link` ("use add, link, list, pair or remove"); the CLI pair
fixtures carry `message`. Two hub tests were racy on pg (a status row is written
before its event; the deep link needs the account the channel reported) and now
wait for the condition they assert.

Floors (.github/test-floors.json), raised for the added tests: vitest linux
851 -> 948, win32 854 -> 951; postgres min_passed 405 -> 535 and the pg require
167 -> 213. No floor lowered.
2026-10-06 03:03:02 +02:00

31 lines
773 B
JSON

{
"name": "@invisible-dots/cli",
"version": "0.0.0",
"private": true,
"description": "The invisible-dots command: setup, doctor, image build, server, and the API client commands.",
"license": "MIT",
"type": "module",
"exports": {
".": "./src/index.ts"
},
"scripts": {
"typecheck": "tsc -p tsconfig.json",
"build": "node scripts/build.mjs",
"dev": "tsx src/main.ts"
},
"dependencies": {
"@invisible-dots/api": "0.0.0",
"@invisible-dots/image-builder": "0.0.0",
"@invisible-dots/sdk": "0.0.0",
"@invisible-dots/shared": "0.0.0",
"@invisible-dots/vm-manager": "0.0.0",
"qrcode": "1.5.4"
},
"bin": {
"invisible-dots": "dist/invisible-dots.mjs"
},
"devDependencies": {
"@types/qrcode": "1.5.6"
}
}