Files
ghostwire/docs/CLI.md
T

182 lines
9.5 KiB
Markdown

# WhatsApp test suite
## Portable single-file bundle
Copy **`whatsapp.py`** to another writable folder. That one Python file includes
all tools, the native helpers and the regression fixtures. No adjacent source
package, DLLs, C++ compiler or build script is needed to run it.
```powershell
python whatsapp.py --help
python whatsapp.py test
python whatsapp.py live --suite history-read
python whatsapp.py contacts-export --output contacts.json
python whatsapp.py export-zip --output messages.zip
python whatsapp.py send-self
```
The bundle compresses the original modules and resources together with LZMA.
It verifies its embedded payload and imports Python modules directly from memory.
Only a native helper needed for a live command is materialized in a hash-verified
cache beside the bundle. Keep the containing folder writable. Native helper
bytes, native object checks, batch sizes and message read/send paths are unchanged.
Core WebView commands use the standard library. Python 3.11+, Windows x64,
64-bit Python are required for live Desktop operations. Other Desktop versions
are attempted with a compatibility warning; only the recorded version was tested. Optional legacy CDP, Frida and QR tools retain the packages
listed below. Node.js remains optional for JavaScript fixture tests.
The development package below remains the editable source. Rebuild the generated
single-file distribution after changing it:
```powershell
python build_whatsapp_bundle.py
```
The build is deterministic and records size and SHA-256 in
`analysis/whatsapp-suite/bundle-build.json`. The build file is not needed on a
machine running the bundle.
The WhatsApp scripts are consolidated in `whatsapp_suite/`, with one CLI and
offline regression tests in `tests/`. Run commands from this workspace.
```powershell
python -m whatsapp_suite
python -m whatsapp_suite --help
python -m whatsapp_suite test --output analysis/whatsapp-suite/results.json
```
`python whatsapp_tests.py` is an equivalent entry point. The default run uses
fixtures and temporary files. It verifies saved-export parsing, Unicode search,
chat filtering, text redaction, history pagination/decryption contracts, fixed
probe responses, command dispatch, and bundled DLL hashes. Node.js runs the
JavaScript history fixtures; that test is reported as skipped if Node is absent.
Python 3.11 or newer is required.
To test an already running WhatsApp Desktop installation:
```powershell
python -m whatsapp_suite test --live
python -m whatsapp_suite test --capabilities
python -m whatsapp_suite live --suite math
python -m whatsapp_suite live --suite capabilities
python -m whatsapp_suite live --suite history-read --output analysis/whatsapp-suite/js-history-read.json
python -m whatsapp_suite export-zip --output exports/whatsapp-messages.zip
python -m whatsapp_suite contacts-export --output exports/contacts.json
python -m whatsapp_suite send-self
```
Live WebView probes require Windows x64 and 64-bit Python. Desktop build
`2.2639.100.0` and its recorded WebView2 Core DLL were tested. Other versions or
DLL hashes produce a warning and are attempted. The helper discovers function and vtable locations from binary fingerprints and checks native
objects and methods before executing JavaScript; changed layouts can
cause failure or process instability. The JSON report includes detected/tested
compatibility metadata and cleanup status. `--pid` selects a Desktop host.
## Tools
Every command supports `--help` for its options.
| Command | Purpose |
| --- | --- |
| `inventory` | List local Desktop storage files and sizes |
| `stats EXPORT` | Summarize a saved JSON or JSONL export |
| `search EXPORT QUERY` | Unicode-aware literal search of saved messages |
| `desktop-search QUERY` | Bounded native app search through WebView2; metadata output |
| `live --suite math\|capabilities\|all` | Fixed live WebView test suites |
| `live --suite message-json\|contacts` | Explicit fixed message search/contact sample; saves private data |
| `live --suite history-read` | Read the five oldest local message records through the JS database getter and decoder, without CDP |
| `webview-test` | Arithmetic check in a separate WebView2 host; may download its SDK |
| `analyze` | Storage analysis, optionally using an existing loopback CDP endpoint |
| `history-export` | Export local history through Desktop's own database decryption |
| `export-zip` | Export all local message rows to ZIP through JavaScript on WebView, without CDP or UI automation |
| `webhook` | Install/status/stop, direct HTTPS or loopback relay, ensure/auto-restore and optional watch/serve; see [webhook guide](WEBHOOKS.md) |
| `contacts-export` | Export all local contact rows to JSON through the app's JS database getter |
| `send-self` | Send one fixed test message to the signed-in account itself and verify stored plaintext |
| `ram-read` | Read loaded V8 message objects from process memory |
| `ram-search QUERY` | Search RAM models with verified collection membership |
| `native-search [QUERY]` | Experimental injected SQLite search, `--oldest --limit 5`, or `--export-index` |
| `qr-memory` | Recover candidate Desktop pairing QR payloads from RAM |
| `qr-window` | Save an already displayed Desktop linking QR |
| `pairing` | Start an isolated browser and request an official linking QR |
```powershell
python -m whatsapp_suite search export.jsonl "keyword" --redact-text
python -m whatsapp_suite desktop-search "keyword" --limit 10
python -m whatsapp_suite history-export --help
```
`history-read` uses the native WebView bridge to execute JavaScript in the running
app. It scans at most 100,000 local record timestamps in a read-only transaction,
then calls `WAWebSchemaMessage.getMessageTable().get` and
`WAWebDBMessageSerialization.messageFromDbRow` for the five oldest records.
It saves decoded body/caption text when present, including messages absent from
the loaded conversation models. System events and media-only records can have
no text. The live result includes page-state and native bridge cleanup status.
This command requires neither CDP nor optional Python packages.
`export-zip` uses the same native bridge and the app's JavaScript database getter
and decoder. It paginates all local rows up to the initial upper primary key,
streams them into `messages.jsonl`, and includes a `manifest.json` with row counts,
decoding errors, scope, and bridge cleanup status. Rows include message IDs,
chat IDs, timestamps, types, body and caption text; media files are not downloaded.
This is a live scan, not an atomic database snapshot. Row decoding failures are
preserved as error records and make the command return a failure status.
`--batch-size` controls bounded reads (default 100); `--redact-text` omits body and
caption text. Existing outputs are refused. Interrupted exports retain a
`.zip.partial` file and a `.zip.report.json` diagnostic report. A completed ZIP
is checked for CRC errors before publication.
`contacts-export` reads the local contact table rather than the five-contact
loaded-model sample. It exports selected identity, name, phone and business
fields. Local records can include separate PN/LID entries and contacts outside
the phone address book; this is not a deduplicated phone address-book export.
`send-self` resolves the signed-in account and checks both the selected chat and
outgoing message recipient before invoking the app's text-send action. It sends
one identifiable test message and reads it back through the message database
decoder, recording ACK and exact plaintext equality in a receipt. An existing
receipt is refused and sending is never retried automatically. Unlike the
offline test suite, this command actually sends a WhatsApp message.
The separate bulk `history-export` command requires an existing Desktop CDP endpoint. RAM tools only see
loaded objects and cannot retrieve all history. Pairing commands are separate
from the automated test run. The `runtime` module preserves the explicit
temporary CDP context manager for research scripts; entering that context
restarts Desktop and is never part of the default tests.
## Optional dependencies
The default suite, saved-export tools, and native WebView probes need only the
Python standard library (plus Node.js for the history fixture test).
| Tools | Additional Python packages |
| --- | --- |
| CDP analysis and history export | `websockets` |
| Injected SQLite search | `frida` |
| QR from RAM | `qrcode[pil]` |
| QR from Desktop window | `Pillow`, `zxing-cpp` |
| Isolated browser pairing | `websockets`, `qrcode[pil]`; installed Chrome |
Install all optional packages into a virtual environment with:
```powershell
python -m pip install -r requirements-whatsapp-optional.txt
```
## Layout and migration
- `whatsapp_suite/`: canonical tool implementations, common normalization,
storage paths, Desktop discovery, CLI, and test runner.
- `whatsapp_suite/assets/`: verified native DLLs and the native SQLite agent.
- `tests/`: synthetic Python regressions and the JavaScript history fixture.
- `analysis/whatsapp-suite/results.json`: latest automated test result.
The former `whatsapp_tool.py` commands now use `python -m whatsapp_suite`;
`whatsapp-search` is named `desktop-search`, and `whatsapp-test` is
`live --suite math`. The former `whatsapp_math.py` options are available under
`live`. Archived scripts have become package modules; the identical Desktop QR
RAM scripts have one implementation (`qr_memory`). Research helpers now import
these modules. Old script archive and portable script copies were removed.
The clean Git project excludes research reports, extracted application code and browser profiles. The surrounding original workspace retains those local files.