Package Exports
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (capgo-update-lite-cli) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
capgo-update-lite-cli
CLI for publishing Capacitor OTA bundles to a capgo-update-lite server, plus admin commands to inspect apps, bundles, and client telemetry.
It runs a full set of preflight checks before touching the server: semver sanity, package.json alignment, capacitor.config match, server reachability, duplicate/downgrade detection, notifyAppReady() source scan, dist-dir validation, and zip size/integrity.
Install-free usage
pnpx capgo-update-lite-cli <subcommand> [...args]
# or
npx capgo-update-lite-cli <subcommand> [...args]The package name on npm is capgo-update-lite-cli. If you install it globally, the installed binary is capgo-update-lite.
Quick start
# 1. scaffold a config file in your Capacitor project root
pnpx capgo-update-lite-cli init
# 2. set the admin token once per shell
export CAPGO_ADMIN_TOKEN=<bearer-token>
# 3. register the app (one-time)
pnpx capgo-update-lite-cli apps add com.example.app --name "Example"
# 4. publish a bundle (version sourced from package.json)
pnpx capgo-update-lite-cli publishWith a capgo-update.config.json in place, the only thing the publish flow needs at runtime is the admin token (env). The bundle version is read from package.json; if it matches the active bundle on the channel, the CLI prompts for a patch/minor/major bump and writes the result back.
Shell completions
The CLI ships a complete <shell> subcommand that emits a tab-completion script for bash, zsh, fish, and powershell. The init wizard offers to install completions automatically; to install or re-install manually:
# bash
echo 'eval "$(capgo-update-lite complete bash)"' >> ~/.bashrc
# zsh
echo 'eval "$(capgo-update-lite complete zsh)"' >> ~/.zshrc
# fish
capgo-update-lite complete fish > ~/.config/fish/completions/capgo-update-lite.fish
# powershell
capgo-update-lite complete powershell >> $PROFILEWhat gets completed:
- Static enums —
--platforms,--platform,--state,--disable-auto-update. - App IDs —
--app/--app-id(and the positional onapps get/apps set-policy) hitGET /admin/apps. - Channels —
--channelenumerates distinct channels seen on the resolved app's bundles. - Bundle versions — the positional on
bundles promote <version>listsstate=activerows for the resolved(appId, channel)scope.
Dynamic completions need CAPGO_SERVER_URL + CAPGO_ADMIN_TOKEN available at TAB time (env or in capgo-update.config.json in the cwd). They use a 5-minute on-disk cache at ${XDG_CACHE_HOME:-~/.cache}/capgo-update-lite/; CLI write commands (apps add / set-policy, bundles delete / edit / promote, publish) invalidate the matching entries automatically. Each completion fetch has a 1.5 s timeout and falls back silently to "no completions" on any error — TAB never hangs the shell prompt.
Subcommands
Every subcommand inherits the three global flags (--server-url, --admin-token, --config). They also honour the matching CAPGO_* env vars and the keys in the config file.
publish
Zip a dist directory and upload it as a new bundle.
pnpx capgo-update-lite-cli publish [options]The bundle version defaults to package.json's version field. If it matches the active bundle on the target channel, the CLI prompts for a patch/minor/major bump and writes the new value back to package.json before publishing. Pass --bundle-version (or set CAPGO_VERSION) to override.
Options specific to publish:
| Flag | Purpose |
|---|---|
--app-id <id> |
Reverse-domain app identifier (or set in config / CAPGO_APP_ID) |
--bundle-version <semver> |
Bundle version (defaults to package.json version) |
--dist-dir <path> |
Built web bundle directory (or set in config / CAPGO_DIST_DIR) |
-c, --channel <name> |
Release channel (default production) |
-p, --platforms <list> |
Comma-separated list of ios,android,electron |
--link <url> |
Release notes / changelog URL |
--comment <text> |
Operator-authored note |
--activate / --no-activate |
Activate on commit (default: activate) |
--dry-run |
Run preflight and build the zip, skip all server writes |
--skip-preflight |
Bypass preflight checks (escape hatch) |
--no-code-check |
Skip the notifyAppReady() source scan |
--version-exists-ok |
Exit 0 if the version is already published (CI-friendly) |
--package-json <path> |
Override auto-detection of package.json |
--capacitor-config <path> |
Override auto-detection of capacitor.config.(ts|js|json) |
--min-android-build <semver> |
Minimum native Android versionName required by this bundle |
--min-ios-build <semver> |
Minimum native iOS CFBundleShortVersionString required by this bundle |
--auto-min-update-build |
Inherit min builds from the previous bundle when native deps are unchanged; bump to detected native versions when they changed |
--android-project <path> |
Path to Android project root (default ./android) |
--ios-project <path> |
Path to iOS project root (default ./ios) |
init
Interactive wizard that scaffolds capgo-update.config.json in the current directory.
pnpx capgo-update-lite-cli init [--force] [--path <path>] \
[--app-id <id>] [--server-url <url>] [--channel <name>] [--dist-dir <path>] \
[--no-validate]Prompts (each is skipped when the matching value is already provided via flag, env, or an existing config file):
- App ID — reverse-domain identifier (
com.example.app). - Server URL — public URL of your deployed worker.
- Channel — defaults to
production. - Dist directory — auto-detects
./build,./dist,./www,./out,./publicin the cwd; each option's hint says whether it containsindex.html. Falls back to a free-form path prompt if no candidates exist.
Then verifies the configuration against the server:
- Asks for an admin token at a hidden password prompt. Leave empty to fall back to a public health check only —
GET /health, no admin endpoints touched. - With a token: pings
/health, thenGET /admin/appswith the bearer token to verify auth. If yourappIdisn't registered yet, the wizard offers to register it inline (same path asapps add) — confirm + display-name prompt +POST /admin/apps. The display-name default is derived from the appId's last segment (com.example.member_app→Member App), editable. - The token is used once and discarded; it is never written to
capgo-update.config.json. IfCAPGO_ADMIN_TOKEN(or--admin-token) is already set, the wizard reuses that and skips the password prompt. - Pass
--no-validateto skip the verification step entirely (e.g. when scripting init in a context with no network access).
The template includes appId, serverUrl, channel, distDir, platforms (default ["ios", "android"]), and autoMinUpdateBuild: true. The admin token is intentionally absent — keep it in CAPGO_ADMIN_TOKEN.
apps list
List apps registered on the server.
pnpx capgo-update-lite-cli apps list [--json]apps add
Register a new app.
pnpx capgo-update-lite-cli apps add <app-id> --name <display-name>apps set-policy
Update an app's compatibility policy. Only the flags you pass are changed; omit a flag to leave that field untouched.
pnpx capgo-update-lite-cli apps set-policy <app-id> \
[--name <display-name>] \
[--disable-auto-update none|patch|minor|major] \
[--disable-auto-update-under-native | --no-disable-auto-update-under-native] \
[--min-plugin-version <semver>|null] \
[--fail-min-devices <n>|null] \
[--fail-warn-rate <0..1>|null] \
[--fail-risk-rate <0..1>|null] \
[--fail-rate-threshold <0..1>|null]--min-plugin-version null clears the floor. Without --no-disable-auto-update-under-native the under-native guard stays at whatever value the server holds. The --fail-* flags override the broken-bundle severity ladder per-app — pass null to clear an override and fall back to env / server default. Order is enforced server-side: warn ≤ risk ≤ disable. Set --fail-rate-threshold 0 (or --fail-min-devices 0) to disable auto-disable for this app while keeping severity classification for the dashboard / bundles health.
bundles list
List bundles, optionally filtered.
pnpx capgo-update-lite-cli bundles list [--app <id>] [-c <channel>] [-s <state>] [--active | --no-active] [--json]bundles delete
Delete a bundle. Soft-delete by default (row stays, marked deleted). Pass --purge to also remove the R2 object. Purge is unrecoverable.
pnpx capgo-update-lite-cli bundles delete <bundle-id> [--purge]bundles promote
Activate an existing bundle for an (app, channel) pair, with no re-upload.
pnpx capgo-update-lite-cli bundles promote <version> --app <id> [-c <channel>]Errors if zero or multiple bundles match the version on the channel.
bundles health
Show the broken-bundle severity ladder. Without an app-id, summarises every app that has at least one non-healthy bundle (most-urgent first). With an app-id, lists each bundle of that app classified into healthy | noisy | warning | at_risk | auto_disabled | manually_disabled, alongside the resolved per-app thresholds.
pnpx capgo-update-lite-cli bundles health [app-id] [--json]bundles reactivate
Restore an auto-disabled (or manually-disabled) bundle: flips state=active + active=true, atomically deactivates siblings on the same channel, and stamps blacklist_reset_at = now() so previously-failed devices get another chance via the /updates blacklist gate.
pnpx capgo-update-lite-cli bundles reactivate <bundle-id>stats
List recent client telemetry events.
pnpx capgo-update-lite-cli stats [--app <id>] [--action <name>] [--since <iso>] [--until <iso>] [--limit <n>] [--offset <n>] [--json]Actions include update, set, and other events the plugin reports. --limit accepts 1..1000 (default 100).
probe
Send a synthetic POST /updates to smoke-test the server end-to-end from the client perspective.
pnpx capgo-update-lite-cli probe [--app <id>] [--platform ios|android|electron] [--current-version <semver>] [--device-id <uuid>] [-c <channel>]Defaults to platform ios and current version 0.0.0 (which forces an update-available response if a bundle exists). When --app is absent, the command falls back to the config or reads appId out of capacitor.config.*.
Configuration layers
Every value resolves via four routes. Precedence, highest wins:
- CLI flag
- Environment variable (
CAPGO_*) - JSON config file (
./capgo-update.config.jsonauto-loaded, or--config <path>) - Built-in defaults (
channel=production,activate=true,codeCheck=true)
For publish specifically, when --bundle-version / CAPGO_VERSION / version are all absent, the bundle version is sourced from package.json's version field. If that version matches the bundle currently active on the channel, the CLI prompts (Cancel / Increase patch version / Increase minor version / Increase major version) and writes the bumped value back to package.json before publishing. In non-interactive contexts (no TTY, e.g. CI), the prompt is replaced by a hard fail — bump package.json ahead of time or pass --bundle-version / --version-exists-ok explicitly.
The admin token follows the same three-route rule. Prefer the environment variable:
--admin-tokenon the command line is visible inpsoutput."adminToken"in the config file is fine if the file is gitignored.CAPGO_ADMIN_TOKENis the safest default.
Config file example
Drop capgo-update.config.json in the directory where you run the CLI (typically your mobile app's project root). The CLI auto-loads it; pass --config <path> to point at a different file.
{
"appId": "com.example.app",
"serverUrl": "https://ota.example.com",
"distDir": "./build",
"channel": "production",
"platforms": ["ios", "android"],
"activate": true
}With the config file present and CAPGO_ADMIN_TOKEN exported, publish shortens to:
pnpx capgo-update-lite-cli publishThe bundle version is sourced from package.json automatically; the bump prompt handles the case where it matches the active bundle.
Full option reference
Rows marked "publish-only" are only read by the publish subcommand. Everything else is global.
| CLI flag | Env var | Config key | Scope | Notes |
|---|---|---|---|---|
--server-url <url> |
CAPGO_SERVER_URL |
serverUrl |
global | OTA server base URL |
--admin-token <token> |
CAPGO_ADMIN_TOKEN |
adminToken |
global | Bearer token for /admin/* |
--config <path> |
CAPGO_CONFIG |
n/a | global | JSON config path |
--app-id <id> |
CAPGO_APP_ID |
appId |
publish-only | Reverse-domain app identifier |
--bundle-version <semver> |
CAPGO_VERSION |
version |
publish-only | Bundle version. Defaults to package.json version. Named to avoid commander's reserved root --version flag. |
--dist-dir <path> |
CAPGO_DIST_DIR |
distDir |
publish-only | Built web bundle directory (must contain index.html) |
-c, --channel <name> |
CAPGO_CHANNEL |
channel |
most | Default production |
-p, --platforms <list> |
CAPGO_PLATFORMS |
platforms |
publish-only | ios,android,electron (comma-separated on CLI and env) |
--link <url> |
CAPGO_LINK |
link |
publish-only | Release notes / changelog URL |
--comment <text> |
CAPGO_COMMENT |
comment |
publish-only | Operator-authored note |
--activate / --no-activate |
CAPGO_ACTIVATE |
activate |
publish-only | Default true; env accepts true/false/1/0/yes/no/on/off |
--dry-run |
CAPGO_DRY_RUN |
dryRun |
publish-only | Run preflight and zip, skip all server writes |
--skip-preflight |
CAPGO_SKIP_PREFLIGHT |
skipPreflight |
publish-only | Bypass preflight checks |
--no-code-check |
n/a | codeCheck |
publish-only | Skip notifyAppReady() source scan (config key defaults to true) |
--version-exists-ok |
n/a | n/a | publish-only | Exit 0 if the version is already published |
--package-json <path> |
CAPGO_PACKAGE_JSON |
packageJson |
publish-only | Override auto-detection of package.json |
--capacitor-config <path> |
CAPGO_CAPACITOR_CONFIG |
capacitorConfig |
publish-only | Override auto-detection of capacitor.config.(ts|js|json) |
--min-android-build <semver> |
CAPGO_MIN_ANDROID_BUILD |
minAndroidBuild |
publish-only | Minimum native Android versionName required by this bundle |
--min-ios-build <semver> |
CAPGO_MIN_IOS_BUILD |
minIosBuild |
publish-only | Minimum native iOS CFBundleShortVersionString required by this bundle |
--auto-min-update-build |
CAPGO_AUTO_MIN_UPDATE_BUILD |
autoMinUpdateBuild |
publish-only | Inherit min builds from prev bundle if native deps unchanged; bump otherwise |
--android-project <path> |
CAPGO_ANDROID_PROJECT |
androidProject |
publish-only | Native Android project root (default ./android) |
--ios-project <path> |
CAPGO_IOS_PROJECT |
iosProject |
publish-only | Native iOS project root (default ./ios) |
-V, --version |
n/a | n/a | global | Print CLI version |
-h, --help |
n/a | n/a | global | Show help (supported on every subcommand) |
Preflight checks (publish only)
All of these can be bypassed with --skip-preflight. Checks that rely on local files auto-detect from the current working directory and silently skip if the file is absent.
- Version autoresolve. When
--bundle-versionis absent, sources the version frompackage.json. Compares against the active bundle on the channel: newer ⇒ continue; older ⇒ fail (downgrade); equal + sourced ⇒ prompt forpatch/minor/majorbump and write back topackage.json; equal + explicit ⇒ fail unless--version-exists-ok. - Version validity. The resolved version must parse as
MAJOR[.MINOR[.PATCH]](Apple'sCFBundleShortVersionStringrules —110,110.0,1.2.3are all accepted; missing segments default to0). package.jsonalignment. Bundle version must be>=thepackage.jsonversion. Major bumps emit a warning so you can confirm the native shell supports the new bundle.capacitor.config.(ts|js|json)alignment. ItsappIdmust match the configuredappId. TheCapacitorUpdater.updateUrl, if set, should start with the server URL (warning only).- Native build resolution. Reads
versionNamefromandroid/app/build.gradle(.kts)to defaultmin_android_build. For iOS, walks Info.plist →project.pbxproj→.xcconfig→xcodebuild(macOS only) to resolveCFBundleShortVersionString, even when it's a$(MARKETING_VERSION)placeholder. Explicit--min-android-build/--min-ios-buildoverride. Fails if neither explicit value nor a native project is available, with a layer-by-layer trace of what was tried. - Server ping.
GET /with a 5s timeout. - App registered.
GET /admin/appsmust include the configuredappId(requires an admin token). - Dist validation.
distDir/index.htmlmust exist. Cloudflare adapter artifacts (_worker.js,_routes.json) must not, which catches accidental web builds. notifyAppReady()source scan. At least one.jsfile underdistDirmust referencenotifyAppReady. Without that call the plugin rolls back after 10 seconds. Disable with--no-code-checkif your build minifies the symbol away.- Zip integrity. The generated ZIP is re-parsed to verify structural validity.
- Size bounds. Less than 1 KB fails (likely an empty build). Over 50 MB warns (slow on cellular). Over 500 MB fails.
Compatibility guards
Every uploaded bundle carries three pieces of native-compatibility metadata. The server uses them to decide whether a given device should receive the bundle:
min_android_build: minimum AndroidversionNamethe native shell must report.min_ios_build: minimum iOSCFBundleShortVersionStringthe native shell must report.native_packages: fingerprint of@capacitor/*,@capacitor-community/*,@ionic-enterprise/*,cordova-plugin-*, andcapacitor-*/capacitor-plugin-*deps frompackage.json, with resolved versions at publish time.
If the device's version_build (what the plugin reports from the native project) is lower than the matching min_*_build, /updates returns below_min_native_build and the plugin keeps its current bundle.
How --auto-min-update-build decides
With --auto-min-update-build (or autoMinUpdateBuild: true in config), the CLI queries the previously-active bundle on (appId, channel) and compares its native_packages fingerprint with the current one:
- Fingerprint unchanged: inherit
min_android_build/min_ios_buildfrom the previous bundle. No native shell reship needed. - Fingerprint changed (added, removed, or version-bumped native dep): set the min builds to the detected native versions (
android/app/build.gradleandios/App/App/Info.plist) and print which packages changed. - No previous bundle: use the detected native versions.
Per-app policies
The server also enforces three per-app policies stored on the apps row. Configure them via PATCH /admin/apps/<app-id>:
disable_auto_update:none(default),patch,minor, ormajor. Blocks auto-updates at or above the configured class.disable_auto_update_under_native: boolean (defaulttrue). Refuses to serve a bundle whose semver is lower than the device's nativeversion_build.min_plugin_version: semver string or null. Devices running an older@capgo/capacitor-updaterplugin are rejected withunsupported_plugin_version.
Publish flow
- Resolve config from CLI, env, and file.
- Run preflight.
- Zip
<dist-dir>in memory with DEFLATE compression (cross-platform, nozipbinary required). POST /admin/bundles/init, receive a presigned R2 URL.PUTthe zip directly to R2.POST /admin/bundles/commitwith{ bundle_id, checksum, activate }.
On --dry-run, steps 4 through 6 are printed as a preview and skipped.
Exit codes
0on success, or when--version-exists-okshort-circuits a duplicate.1on any error: missing config, preflight failure, non-2xx response, IO failure, and so on.