6.2 KiB
Develop and extend Ghostwire
The editable implementation is whatsapp_suite/. The single-file whatsapp.py is a generated distribution. Changes to the encoded payload will be overwritten by the builder.
Local workflow
Clone the repository and run these commands from its root:
git clone https://tea.karlcom.de/karl/ghostwire.git
cd ghostwire
python -m whatsapp_suite --help
python -m whatsapp_suite test
Python 3.11+ is required. Install Node.js to run all JavaScript fixtures; check the test report for skipped checks. Core commands use Python's standard library. Install optional packages only when working on those research tools.
After changing Python, JavaScript, runtime assets or tests:
python -m whatsapp_suite test
python build_whatsapp_bundle.py
python whatsapp.py test
git diff --check
The builder writes size and hash metadata to ignored analysis/whatsapp-suite/bundle-build.json. An unchanged input set must produce the same bundle hash. Commit maintained source and the regenerated bundle together. Documentation-only changes do not require rebuilding.
To verify portability, copy only whatsapp.py into an otherwise empty writable folder and run python -I whatsapp.py test there.
Find the extension point
| Change | Start here |
|---|---|
| Register a command | whatsapp_suite/cli.py → COMMANDS |
| Saved-export parsing/search | whatsapp_suite/exports.py |
| Message ZIP export | whatsapp_suite/zip_export.py; shared database expression in history.py |
| Contact export | whatsapp_suite/contacts_export.py |
| Fixed self-message test | whatsapp_suite/self_message.py |
| Listener configuration/restoration/receiver | whatsapp_suite/webhook.py |
| Message event observation and decoding | whatsapp_suite/assets/webhook_listener.js |
| Windows bridge orchestration and cleanup | whatsapp_suite/live.py |
| App detection and advisory compatibility | whatsapp_suite/desktop.py |
| Native address discovery | native/core_discovery.h |
| Resident HTTP relay | native/webhook_probe.cpp |
| Packaging | build_whatsapp_bundle.py and asset hashes |
For detailed transport behavior, read architecture. For demonstrated behavior, read validation.
Add a Python command
- Add a module under
whatsapp_suite/withmain(argv=None). Parse its own options withargparseand return an integer exit code. - Register the command name, module and help description in
cli.COMMANDS. Existing commands show the dispatch pattern. - Reuse the existing bridge/export helpers when the operation needs Desktop JavaScript. Define a bounded operation with an explicit result contract; do not expose an arbitrary-script execution CLI as a shortcut.
- Add meaningful synthetic fixtures for new parsing, paging, response or lifecycle behavior. Keep live actions out of default tests.
- Update the CLI documentation, rebuild and verify the portable command's
--help.
Top-level Python modules are embedded automatically. New runtime assets need an explicit entry in the builder's asset list; new fixture types may also need packaging support. JavaScript .cjs fixtures already have a packaging rule.
Change listener JavaScript
The producer is assets/webhook_listener.js. Python substitutes the __CONFIG__ placeholder with listener settings; transport credentials are kept out of the injected JavaScript. The producer observes collection events, decodes stored rows and queues bounded records.
Use tests/webhook_listener.cjs for synthetic collection/database fixtures. Preserve event IDs, sequence-based acknowledgements, text/queue bounds and stop behavior. If changing payload fields, update the webhook schema and receiver validation together.
The native relay polls the queue and removes entries only after HTTP 2xx. A target should deduplicate message IDs. Keep retry behavior distinguishable from exactly-once delivery.
Change native code
Ordinary Python/JavaScript changes do not require compiling C++. Native changes need an x64 MSVC Native Tools prompt and the Windows SDK:
native\build.cmd
native\build_webhook.cmd
The recipes write compiler output into ignored native/build/. Copy the rebuilt runtime DLLs into whatsapp_suite/assets/, then update:
| DLL | Expected hash |
|---|---|
math_probe.dll |
live.EMBEDDED_SHA256 |
search_probe.dll |
native_search.EMBEDDED_PROBE_SHA256 |
webhook_probe.dll |
webhook.HELPER_SHA256 |
Also update docs/runtime-assets.json. The Python builder packages existing DLLs; it does not compile them. PE files are not promised to be byte-identical across compiler versions or build timestamps.
Native live validation must use the intended Desktop build and verify the operation and cleanup. A resident webhook DLL remains loaded after stop to protect pending callbacks; restart WhatsApp before testing a replacement helper. Preserve completed packet states when duplicate wake messages arrive.
Address fingerprints, object fields and ABI checks are deliberate compatibility boundaries. Do not replace an unsupported-layout failure with guessed addresses.
Tests and live checks
Tests live in tests/test_whatsapp_suite.py and synthetic .cjs fixtures. The runner packages the Python tests as _regression.py for the portable file.
python whatsapp.py test
python whatsapp.py test --live
python whatsapp.py test --capabilities
The latter two explicitly use running WhatsApp. Sending, exporting real data and installing a listener are separate actions; they are never implied by an offline test. Use the user's authorized scope for live validation. An uncertain self-send is inspected through its reserved receipt before any retry.
Before submitting
Describe the concrete behavior change, relevant tests and remaining limits. Review git diff --cached and ensure no exports, real message/contact fixtures, profiles, session material, credentials or research captures are staged. Preserve the tested-versus-unverified distinction. No license change or external deployment is implied by a source change.
Coding agents should start with AGENTS.md and the development skill.