anthropics / anthropics/claude-code

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

Abierto
#94,359 0 comentarios 0 reacciones 0 asignados Ver en GitHub
area:plugins enhancement
Lenguaje dominante
Python
Estrellas
145k
Forks
23.1k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

### 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.

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.