cli/cli
Telemetry, agent detection, and skills
Active contributors: Sam Morrow, William Martin, tommaso-moro, Mislav
Purpose
Three closely related subsystems share this page because they were built together and reference each other's primitives:
- Telemetry (
internal/telemetry/,internal/barista/): opt-in, sampled usage events sent over Twirp to GitHub's internal observability service. - Agent detection (
internal/agents/): identifies which AI coding tool launchedgh, used both for telemetry attribution and for skill placement. - Skills (
internal/skills/): the runtime support forgh skill(see Copilot, skills, and agent-task).
Directory layout
internal/telemetry/
telemetry.go # NewService, NoOpService, LogFlusher
state.go # ParseTelemetryState
flush.go # Background flush goroutine
internal/barista/
observability/
telemetry.twirp.go # ~40 KB: generated Twirp client
*.go # transport + helpers
internal/gh/ghtelemetry/ # Public types: Service, CommandRecorder, Dimensions
internal/agents/
detect.go # Detect() based on environment variables
detect_test.go # Table-driven tests for every supported agent
internal/skills/
installer/ # Place files into agent skill dirs
discovery/ # Walk a source repo to find skill manifests
registry/ # Remote registry client (search, download)
source/ # Source abstraction (github, local)
frontmatter/ # YAML frontmatter
lockfile/ # Per-host installed-skills lockfileKey abstractions
| Symbol | File | Role |
|---|---|---|
telemetry.Service |
telemetry.go |
The runtime service that batches events. |
telemetry.NoOpService |
telemetry.go |
Used when telemetry is disabled or config is unreadable. |
telemetry.LogFlusher |
flush.go |
Writes a human-readable summary to stderr in log mode. |
ghtelemetry.Service / CommandRecorder |
internal/gh/ghtelemetry/ |
Public interfaces consumed by command code. |
agents.Detect |
internal/agents/detect.go |
Returns a validated AgentName like claude-code or codex. |
skills.Installer |
internal/skills/installer/ |
Places skill files into the per-agent target directory. |
skills.Discovery |
internal/skills/discovery/ |
Walks a source repo to enumerate skill manifests; ~33 KB. |
skills.Registry |
internal/skills/registry/ |
Remote registry client used by gh skill search. |
skills.Lockfile |
internal/skills/lockfile/ |
Records installed skills so updates and removals are coherent. |
How it works
Telemetry boot
graph TD
A[ghcmd.Main] --> B{Config readable?}
B -->|no| C[NoOpService]
B -->|yes| D[ParseTelemetryState]
D -->|Disabled| C
D -->|Logged| E[NewService with LogFlusher]
D -->|Enabled & not GHES heuristic| F[NewService with Twirp client]
D -->|GHES suspected| CEach command emits a command_invoked event tagged with version, TTY status, agent name, CI signal, and dimensions specific to the command. cmdutil.RecordTelemetryForSubcommands walks the Cobra tree once at startup so commands do not need explicit instrumentation.
Agent detection
internal/agents/detect.go checks environment variables in a deliberate order:
- Generic
AI_AGENT=<name>(validated against[a-zA-Z0-9_-]+). - Tool-specific signals:
AGENT=amp,CODEX_*,GEMINI_CLI,COPILOT_CLI,OPENCODE. CLAUDECODElast, because Amp also setsCLAUDECODE=1.
The result is sent both as a telemetry dimension and as part of the outgoing User-Agent header.
Skills
gh skill install <repo> <skill> resolves the source via internal/skills/source, walks the repo with discovery, validates the manifest with frontmatter, copies the contents through installer into the target directory for the detected agent, and updates the lockfile. The skills tree opts into SAMPLE_ALL telemetry in its PersistentPreRunE so signal flows back during the preview phase.
Integration points
- Telemetry headers are added by the API transport stack (
pkg/cmd/factory/default.go). - Agent detection is reused by both telemetry and the skills installer.
- Skills depends on
git.Client(clone source repos), the API client (registry calls), and the prompter (interactive selection).
Entry points for modification
- New telemetry dimension: add it to
additionalCommonDimensionsininternal/ghcmd/cmd.goor to the per-command annotations inpkg/cmdutil/telemetry.go. - New agent: append a heuristic to
agents/detect.goand a row to the table-driven test. Document the source URL the way the existing entries do. - New skill source backend: implement
Sourceininternal/skills/source/and add coverage.
Key source files
| File | Purpose |
|---|---|
internal/telemetry/telemetry.go |
Service. |
internal/telemetry/flush.go |
Background flush. |
internal/barista/observability/telemetry.twirp.go |
Generated client (~40 KB). |
internal/agents/detect.go |
Agent detection. |
internal/skills/discovery/discovery.go |
Skill enumeration. |
internal/skills/installer/installer.go |
File placement. |
internal/skills/registry/registry.go |
Registry client. |
internal/skills/lockfile/lockfile.go |
Per-host install state. |
Related pages
- Copilot, skills, and agent-task.
- API client for how the telemetry and registry HTTP traffic flows.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.