Skip to content

Commit 2dba6f2

Browse files
committed
add plugin and cc versions to root span metadata
1 parent abe3525 commit 2dba6f2

4 files changed

Lines changed: 72 additions & 2 deletions

File tree

plugins/trace-claude-code/hooks/common.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,44 @@ get_os() {
890890
uname -s 2>/dev/null || echo "unknown"
891891
}
892892

893+
# Version of this plugin, read from its plugin.json manifest. Cached after the
894+
# first lookup. Returns "unknown" if it can't be read.
895+
get_plugin_version() {
896+
if [ -n "${_PLUGIN_VERSION:-}" ]; then
897+
echo "$_PLUGIN_VERSION"
898+
return
899+
fi
900+
local manifest="${SCRIPT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}/../.claude-plugin/plugin.json"
901+
local v=""
902+
[ -f "$manifest" ] && v=$(jq -r '.version // empty' "$manifest" 2>/dev/null)
903+
_PLUGIN_VERSION="${v:-unknown}"
904+
echo "$_PLUGIN_VERSION"
905+
}
906+
907+
# Version of the running Claude Code CLI. Prefers a version found in the
908+
# session transcript (authoritative for the run that produced it); falls back
909+
# to `claude --version`. Cached after the first lookup. Returns "unknown" if
910+
# neither source is available.
911+
#
912+
# Args: [transcript_path] - optional transcript to read `.version` from.
913+
get_claude_code_version() {
914+
local transcript="${1:-}"
915+
if [ -n "${_CC_VERSION:-}" ]; then
916+
echo "$_CC_VERSION"
917+
return
918+
fi
919+
local v=""
920+
if [ -n "$transcript" ] && [ -f "$transcript" ]; then
921+
v=$(jq -rc 'select(.version) | .version' "$transcript" 2>/dev/null | head -1)
922+
fi
923+
if [ -z "$v" ]; then
924+
# e.g. "2.1.173 (Claude Code)" -> "2.1.173"
925+
v=$(claude --version 2>/dev/null | awk '{print $1}')
926+
fi
927+
_CC_VERSION="${v:-unknown}"
928+
echo "$_CC_VERSION"
929+
}
930+
893931
###
894932
# Emit spans for a Claude Code transcript file (typically a sub-agent's own
895933
# transcript), parented under a given span. This reproduces the same span

plugins/trace-claude-code/hooks/session_start.sh

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ HOSTNAME=$(get_hostname)
7676
USERNAME=$(get_username)
7777
OS=$(get_os)
7878

79+
# Version info for observability: this plugin's version and the Claude Code
80+
# CLI version that produced the session.
81+
TRANSCRIPT_PATH=$(echo "$INPUT" | jq -r '.transcript_path // empty' 2>/dev/null)
82+
PLUGIN_VERSION=$(get_plugin_version)
83+
CLAUDE_CODE_VERSION=$(get_claude_code_version "$TRANSCRIPT_PATH")
84+
7985
EVENT=$(jq -n \
8086
--arg id "$SPAN_ID" \
8187
--arg span_id "$SPAN_ID" \
@@ -87,6 +93,8 @@ EVENT=$(jq -n \
8793
--arg hostname "$HOSTNAME" \
8894
--arg username "$USERNAME" \
8995
--arg os "$OS" \
96+
--arg plugin_version "$PLUGIN_VERSION" \
97+
--arg claude_code_version "$CLAUDE_CODE_VERSION" \
9098
'{
9199
id: $id,
92100
span_id: $span_id,
@@ -99,7 +107,9 @@ EVENT=$(jq -n \
99107
hostname: $hostname,
100108
username: $username,
101109
os: $os,
102-
source: "claude-code"
110+
source: "claude-code",
111+
plugin_version: $plugin_version,
112+
claude_code_version: $claude_code_version
103113
},
104114
span_attributes: {
105115
name: ("Claude Code: " + $workspace),

plugins/trace-claude-code/hooks/user_prompt_submit.sh

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ if [ -z "$ROOT_SPAN_ID" ] || [ -z "$PROJECT_ID" ]; then
4949
USERNAME=$(get_username)
5050
OS=$(get_os)
5151

52+
# Version info for observability (mirrors session_start.sh).
53+
TRANSCRIPT_PATH=$(echo "$INPUT" | jq -r '.transcript_path // empty' 2>/dev/null)
54+
PLUGIN_VERSION=$(get_plugin_version)
55+
CLAUDE_CODE_VERSION=$(get_claude_code_version "$TRANSCRIPT_PATH")
56+
5257
EVENT=$(jq -n \
5358
--arg id "$ROOT_SPAN_ID" \
5459
--arg span_id "$ROOT_SPAN_ID" \
@@ -59,6 +64,8 @@ if [ -z "$ROOT_SPAN_ID" ] || [ -z "$PROJECT_ID" ]; then
5964
--arg hostname "$HOSTNAME" \
6065
--arg username "$USERNAME" \
6166
--arg os "$OS" \
67+
--arg plugin_version "$PLUGIN_VERSION" \
68+
--arg claude_code_version "$CLAUDE_CODE_VERSION" \
6269
'{
6370
id: $id,
6471
span_id: $span_id,
@@ -71,7 +78,9 @@ if [ -z "$ROOT_SPAN_ID" ] || [ -z "$PROJECT_ID" ]; then
7178
hostname: $hostname,
7279
username: $username,
7380
os: $os,
74-
source: "claude-code"
81+
source: "claude-code",
82+
plugin_version: $plugin_version,
83+
claude_code_version: $claude_code_version
7584
},
7685
span_attributes: {
7786
name: ("Claude Code: " + $workspace),

plugins/trace-claude-code/test/test_session_start.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,19 @@ t_session_start_metadata() {
8080
local session_id
8181
session_id=$(echo "$span" | jq -r '.metadata.session_id')
8282
assert_eq "$session_id" "sess-meta"
83+
84+
# Version attributes are present and non-empty. plugin_version comes from
85+
# plugin.json; claude_code_version from the transcript or `claude --version`
86+
# (falls back to "unknown" but must always be set).
87+
local plugin_version cc_version
88+
plugin_version=$(echo "$span" | jq -r '.metadata.plugin_version')
89+
cc_version=$(echo "$span" | jq -r '.metadata.claude_code_version')
90+
assert_ne "$plugin_version" "null" "plugin_version should be set"
91+
assert_ne "$plugin_version" "" "plugin_version should be non-empty"
92+
# plugin_version should match the manifest (e.g. a semver-ish string).
93+
assert_match "$plugin_version" "^[0-9]+\.[0-9]+\.[0-9]+" "plugin_version looks like a version"
94+
assert_ne "$cc_version" "null" "claude_code_version should be set"
95+
assert_ne "$cc_version" "" "claude_code_version should be non-empty"
8396
}
8497

8598
t_session_start_writes_state() {

0 commit comments

Comments
 (0)