anthropics / anthropics/claude-code

[FEATURE] Add plugin.version to the skill_activated OTel event (already emitted on plugin_loaded)

Aperta
#94,359 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub
area:plugins enhancement
Lingua principale
Python
Stelle
145k
Fork
23.1k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

### Preflight Checklist

- [x] I have searched [existing requests](https://github.com/anthropics/claude-code/issues?q=is%3Aissue%20label%3Aenhancement) and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)

### Problem Statement

The `skill_activated` OTel event carries `plugin.name` and `marketplace.name`, but not
`plugin.version`. The emitter already produces that field — it's on `plugin_loaded` — so two
of the three plugin identity attributes are present on activation and the third is missing.

Observed on 2.1.270:

- `plugin_loaded` → `plugin_name`, `plugin_version`, `marketplace_name`, `plugin_scope`,
`enabled_via`, `plugin_id_hash`, `session_id`, `user_email`
- `skill_activated` → `skill_name`, `skill_source`, `plugin_name`, `marketplace_name`,
`invocation_trigger`, `session_id`, `user_email` — no `plugin_version`

We run Claude Code across a ~260-person org and publish internal plugins through our own
marketplace. Multiple versions of the same plugin are live at any moment: for one plugin over
24h we see five (1.0.0, 1.3.0, 1.6.0, 1.7.0, 1.8.0).

Without the field we can answer "who has which version installed" but not "which version
actually ran" — the difference between a release being adopted and merely downloaded. When a
skill starts failing we also can't split invocations by plugin version to attribute the
regression.

### Proposed Solution

Add `plugin.version` to the `skill_activated` event, populated the same way as on
`plugin_loaded`.

Absent for skills that don't come from a plugin (`skill_source` of `userSettings` or
`projectSettings`) is fine — that's already how `plugin.name` behaves today.

### Alternative Solutions

Both events share `session_id`, so the version can in principle be recovered by joining
`skill_activated` to `plugin_loaded` within a session. We tried it against real data. It works
mechanically but not at a useful scale:

- `plugin_loaded` fires at session start, so any query window shorter than the session misses
the load while catching the activations.
- Widening the window blows up cardinality: grouping by `session_id` (or by `user_email` ×
plugin × version) exceeds Loki's 500-series limit.
- Filtering to a single plugin fits under the limit, but a 7-day query took over 2 minutes and
the equivalent 30-day query scans 4.4M log lines.

Joining by user instead of by session is cheaper but only approximate: every invocation gets
attributed to whatever version that person had during the window, which is wrong for anyone who
upgraded mid-window.

### Priority

Medium - Would be very helpful

### Feature Category

Other

### Use Case Example

1. We ship version 1.8.0 of an internal plugin with a fix to one of its skills.
2. A week later we want to know whether the fix is actually reaching people: of all the
invocations of that skill, how many ran on 1.8.0 and how many still ran on 1.6.0.
3. Today we can only see that 21 people have 1.8.0 installed and 12 are on older versions —
we can't connect that to the invocations themselves.
4. With `plugin.version` on `skill_activated` this is a single `sum by (plugin_version)` query.

### Additional Context

Related: #85555 asks for SKILL.md frontmatter metadata on the same events. Different ask, same
surface — that one is about attributing skills that don't come from plugins, this one is about
versioning the ones that do.

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.