# 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: ```powershell git clone https://tea.karlcom.de/karl/whatsapp_injector.git cd whatsapp_injector 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](docs/CLI.md#optional-research-commands) only when working on those research tools. After changing Python, JavaScript, runtime assets or tests: ```powershell 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](docs/ARCHITECTURE.md). For demonstrated behavior, read [validation](docs/VALIDATION.md). ## Add a Python command 1. Add a module under `whatsapp_suite/` with `main(argv=None)`. Parse its own options with `argparse` and return an integer exit code. 2. Register the command name, module and help description in `cli.COMMANDS`. Existing commands show the dispatch pattern. 3. 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. 4. Add meaningful synthetic fixtures for new parsing, paging, response or lifecycle behavior. Keep live actions out of default tests. 5. 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](docs/WEBHOOKS.md) 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: ```bat 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. ```powershell 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](AGENTS.md) and the [development skill](skills/whatsapp-suite-development/SKILL.md).