@moengage/sdk-cli
v0.0.3
Published
MoEngage SDK integration validator — moengage doctor <platform> <path>.
Downloads
361
Maintainers
Keywords
Readme
@moengage/sdk-cli
Validate a MoEngage SDK integration from the command line. The CLI reads your project statically — no Gradle invocation, no Xcode, no JVM, no custom lint JAR — and reports what's wrong, why it matters, and how to fix it.
moengage doctor android <path-to-project>
moengage doctor ios <path-to-project>Requirements
Node 18 or newer (the CLI uses the built-in global
fetch).Network access, for the full picture. Version and compatibility checks resolve live rather than from a bundled snapshot, so a CLI installed last year still understands a release published this morning. Offline, those checks degrade to "could not tell" and say so; everything read from the project alone is unaffected.
| Platform | Reads | |---|---| | Android | Maven Central and GitHub, for BOM and module compatibility | | iOS |
package.jsonat each release tag ofmoengage/apple-sdk, cached on disk |Android only: the project built once for the
releasevariant. The CLI reads AGP's own merged manifest and resolved-dependency metadata rather than guessing at what your build script means, and AGP only writes those once a build has run:./gradlew assembleReleaseWithout them the run stops with a message naming the paths it looked for.
iOS needs no build. It parses
project.pbxproj,Podfile.lockandPackage.resolveddirectly, so it works on a fresh clone. Runningpod installfirst widens coverage — a few checks read what is actually installed underPods/— but its absence is reported as reduced coverage, never as a defect.
Install
Run it without installing anything:
npx @moengage/sdk-cli doctor android
npx @moengage/sdk-cli doctor ios ./MyAppOr install it globally, which gives you the shorter moengage command:
npm install -g @moengage/sdk-cli
moengage --versionIf your npm prefix is a system directory, either use sudo, or point -g at a
directory you own:
npm install -g --prefix "$HOME/.local" @moengage/sdk-cli
export PATH="$HOME/.local/bin:$PATH" # add to ~/.zshrc to make it stickTo pin a version, install @moengage/sdk-cli@<version>.
Usage
moengage doctor android # scan the current directory
moengage doctor android ~/work/my-app # or an explicit project path
moengage doctor android --help # every flag
moengage doctor ios ~/work/MyApp # same shape, iOS validator
moengage doctor --help # every platform the build supportsThe path is optional — run the command from inside the project you're working on and it scans the current directory.
What counts as a valid target differs, because the two platforms read different things:
| Platform | Point it at | If you point it higher up |
|---|---|---|
| android | the Gradle project root — the directory holding settings.gradle, build.gradle or gradlew — not the app module | exits 2 and names the project roots it found below |
| ios | the directory containing the .xcodeproj (a .xcworkspace beside it is used when present) | exits 2 and names the projects it found below |
Multi-module Android projects are fine, but the root must contain exactly one
com.android.application module — the CLI says so explicitly if it finds none or
several.
On iOS, a project generated by Tuist has no .xcodeproj until its
generator has run. The CLI refuses rather than reporting a clean run, and names
the command:
error: …/MyTuistApp has no .xcodeproj — the project is generated from Project.swift
hint: run `tuist generate` first, then run this againOptions
| Flag | What it does |
|------------------|---------------------------------------------------------------------|
| --json | Emit the report as JSON on stdout instead of the console report |
| -v, --verbose | Include the evidence behind each finding, plus documentation links |
| --strict | Treat warnings as blocking, so a warning-only run exits 1 |
| --no-color | Disable coloured output (also off automatically when not a TTY) |
| -V, --version | Print the installed version |
A scan takes a few seconds. It only reads your project — no source is uploaded, and the only network calls are the public metadata lookups described above.
What you get
Every run prints a console summary and writes a full Markdown report into the
scanned project's root, named moengage-doctor-report-<timestamp>.md. The
timestamp means an earlier run's report is never overwritten; add the pattern to
.gitignore if you'd rather not commit them.
With --json, the machine-readable report goes to stdout — the shape to consume
in CI — while the Markdown file is still written.
The report is grouped by area.
Android
- Installation — is the SDK declared, at compatible module versions, with its AndroidX prerequisites, a supported Java level and auto-backup handled; which MoEngage modules and product features the build actually pulls in.
- Initialisation — is the SDK initialised correctly and in the right place, is it configured properly, and — when push is in use — is the notification runtime permission requested and Firebase delivery wired up (config file, receiving service, token and payload hand-off).
- In-App — is
showInApp()reachable from the activities and fragments that need it. - Geofence — location permissions and
startGeofenceMonitoring(), when the geofence module is integrated.
iOS
- Installation & Toolchain — is MoEngage integrated at all, are its modules on one release train, is the deployment target and architecture configuration one that will link, and is the toolchain one the App Store accepts.
- Initialisation & Config — is the SDK initialised on the launch path, with a well-formed configuration, against the environment the build configuration implies.
- Capabilities & Entitlements — push, App Groups and background modes declared consistently across the app and its extensions, and authorised by the provisioning profile they sign with.
- Notification Extensions — does a notification service extension exist, is it embedded and signed correctly, does it reach the SDK's handler, and do the app and extension agree on their shared container.
- Push wiring — swizzling on or off, and whether the five push callbacks are forwarded accordingly.
- URL & deeplink handling — declared URL schemes, associated domains, and whether an arriving URL reaches the SDK.
- Geofence and Ecosystem conflicts — geofence start-up, and other SDKs competing for the same AppDelegate.
Each finding carries a severity, the reason it matters, a concrete
recommendation, and (with -v) the file and line it was read from.
Exit codes
| Code | Meaning |
|------|---------------------------------------------------------------------------|
| 0 | No errors — warnings may still be present unless --strict is passed |
| 1 | At least one error, or a warning while --strict is on |
| 2 | Couldn't run — unknown platform, the path isn't a directory or project root, an Android project not built for the release variant, or an iOS project whose .xcodeproj has not been generated yet |
That makes it usable as a CI gate:
moengage doctor android --strict
moengage doctor ios --strictPlatforms
android and ios are available today. React Native and Flutter plug into the
same command shape and will appear as additional doctor subcommands;
moengage doctor --help always lists what the installed version supports.
