Skip to content

feat: add X-CLI-Event header for analytics tracking#15

Draft
pjcdawkins wants to merge 1 commit intomainfrom
feat/analytics-event-header
Draft

feat: add X-CLI-Event header for analytics tracking#15
pjcdawkins wants to merge 1 commit intomainfrom
feat/analytics-event-header

Conversation

@pjcdawkins
Copy link
Contributor

@pjcdawkins pjcdawkins commented Jan 9, 2026

Summary

  • Add a custom HTTP header (X-CLI-Event) to all API requests for analytics tracking via Pendo
  • Header format: command=<name>; interactive=<bool>
  • Example: X-CLI-Event: command=backup:restore; interactive=true
  • Works across both Go CLI native commands and legacy PHP CLI commands
  • Respects user privacy opt-out settings

Opt-out

Users can disable telemetry via environment variables:

  • DO_NOT_TRACK=1 (or true) - standard opt-out
  • {PREFIX}DISABLE_TELEMETRY=1 (e.g., UPSUN_CLI_DISABLE_TELEMETRY=1)

Changes

Go CLI

  • New EventTransport in internal/auth/event_transport.go that injects X-CLI-Event and User-Agent headers
  • New context helpers: WithEventName, WithInteractive, and corresponding getters
  • Event name and interactive flag passed via context from the root command
  • EVENT_NAME environment variable passed to the legacy PHP CLI
  • Respects DO_NOT_TRACK and {PREFIX}DISABLE_TELEMETRY opt-out settings

Legacy PHP CLI

  • New EventHeaderMiddleware that adds X-CLI-Event header to Guzzle requests
  • New Config::getEventName() and Config::isInteractive() methods
  • Middleware registered in Api::getConnectorOptions()
  • Respects DO_NOT_TRACK and {PREFIX}DISABLE_TELEMETRY opt-out settings

Header Format

X-CLI-Event: command=<command-name>; interactive=<true|false>

Examples:

  • X-CLI-Event: command=backup:restore; interactive=true
  • X-CLI-Event: command=project:info; interactive=false

The interactive flag is false when --no-interaction, -y, or --quiet flags are used, or when the {PREFIX}NO_INTERACTION=1 environment variable is set.

Test plan

  • Run Go tests: make test
  • Run PHP tests: cd legacy && php vendor/bin/phpunit tests/EventHeaderMiddlewareTest.php tests/ConfigTest.php
  • Verify header appears in debug output: upsun project:info -vvv 2>&1 | grep -i "x-cli-event"
  • Verify opt-out works: DO_NOT_TRACK=1 upsun project:info -vvv 2>&1 | grep -i "x-cli-event" (should show nothing)

🤖 Generated with Claude Code

}

// Build the transport chain:
// EventTransport (adds X-CLI-Event + User-Agent)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we already add User-Agent elsewhere so is this right?

@pjcdawkins pjcdawkins force-pushed the feat/analytics-event-header branch from 4a919b8 to 1d110cf Compare January 9, 2026 17:11
Add a custom HTTP header to all API requests that tracks the command
name and interactive mode for analytics purposes via Pendo.

Header format: `X-CLI-Event: command=<name>; interactive=<bool>`

Example: `X-CLI-Event: command=backup:restore; interactive=true`

Users can opt out via:
- DO_NOT_TRACK=1 (or true) - standard opt-out environment variable
- {PREFIX}DISABLE_TELEMETRY=1 (e.g., UPSUN_CLI_DISABLE_TELEMETRY=1)

Go CLI changes:
- Add EventTransport to inject X-CLI-Event and User-Agent headers
- Add WithEventName/WithInteractive context helpers
- Pass event name and interactive flag via context from root command
- Pass EVENT_NAME environment variable to legacy PHP CLI
- Respect DO_NOT_TRACK and DISABLE_TELEMETRY opt-out settings

Legacy PHP CLI changes:
- Add EventHeaderMiddleware to inject X-CLI-Event header
- Add Config::getEventName() and Config::isInteractive() methods
- Register middleware in Api::getConnectorOptions()
- Respect DO_NOT_TRACK and DISABLE_TELEMETRY opt-out settings

The interactive flag is determined by the NO_INTERACTION environment
variable, which is already passed from Go to PHP.

Co-Authored-By: Claude Code <claude-code@anthropic.com>
@pjcdawkins pjcdawkins force-pushed the feat/analytics-event-header branch from 1d110cf to 8873a01 Compare January 9, 2026 20:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant