First-run events
The hook reports one of three event types. Two of them are conversions, counted once per installation.
| Event | Report it | Counted |
|---|---|---|
install_completed | After every installation step succeeded. | Once per installation ID. The default. |
first_run | From your CLI's entry point, on launch. | Once per installation ID. |
install_started | Before installing, to measure attempts. | Once per installation ID. Not a conversion: only webhooks receive it. |
#Installation IDs
On its first run, the hook creates a random 128-bit installation ID and keeps it in <state dir>/, where the state dir defaults to ~/.local/state/clitrail. Later reports from the same user, website and scope reuse it, so launching your CLI a hundred times still produces one first_run. Updating the hook you bundle keeps existing IDs: in the default folder, a hook with no ID yet reuses the one an older copy kept under ~/.local/.
- A repeated report of the same event type for the same installation,
install_startedincluded, returns the original result with"duplicate": true. A pre-install hook that runs several times counts one attempt. - Reusing an
event_idwith the same installation and type is idempotent. Reusing it for anything else is refused withevent_id_conflict. - Destinations receive one conversion per installation and event type, identified by a stable event ID the platforms deduplicate on.
#Installation scopes
Use --installation-scope (or CLITRAIL_INSTALLATION_SCOPE) when one website ships several products, or one product can be installed several independent times on a machine. Each scope gets its own installation ID.
#Choosing the event
- Use
install_completedwhere your code runs at the end of a real install: a shell installer or an npmpostinstall. - Use
first_runwhere there is no install step you control: npx, Homebrew launchers, Python entry points and single binaries. It counts people who actually launch the CLI, not downloads.
Google Ads, Meta, TikTok and X Ads destinations send install_completed only until you tick first_run in their events; GA4 and webhooks send both by default. X Ads sends first runs to a second event of your pixel, so they never count as installs.
#Late receipts
An install is resolved when it is first reported. If it was unmatched, reporting it again does not attach a receipt that became readable later.