Files
chainbase-labs__agentkey/tests/check-update.bats
T
lxcong f830f2947d feat: agent install telemetry (skill side, spec §8.1) (#31)
## Summary

Skill-side half of the agent-install telemetry rollout (spec §8.1).
`check-update.sh` emits `TELEMETRY ...` lines on stdout, SKILL.md parses
them and dispatches via MCP. Adds 3-layer opt-out (file / env /
installer flag — file path checked here), 24h client-side dedup, and a
bats test harness.

- `skills/agentkey/scripts/check-update.sh` — `emit_telemetry()` +
`auto_upgrade_flag()` helpers, opt-out checks, 7 emit calls at 5 exit
points, 24h heartbeat dedup keyed by `LOCAL_VERSION`. Includes Linux
`stat` order fix (`-c %Y` first, `-f %m` second — `-f` on Linux means
filesystem mountpoint, not mtime)
- `skills/agentkey/SKILL.md` — Step 0 instructions for parsing
`TELEMETRY` lines and dispatching via
`execute_tool(\"agentkey_internal\", {path:\"telemetry/event\", ...})`;
upgrade-flow each branch dispatches `upgrade_decision` /
`upgrade_result` with mapped choice values
- `tests/check-update.bats` + `tests/helpers.bash` — 10 contract tests
with isolated `\$HOME` / `\$TMPDIR` / mocked curl
- `.github/workflows/scripts-test.yml` — bats CI on ubuntu + macos
- `README.md` + `docs/README_zh.md` — FAQ replacement for the old
\"nothing to collect\" sentence, new FAQ entry \"How do I opt out of
telemetry?\" / \"我如何关闭遥测?\"
- `scripts/uninstall.sh` — adds Step 7b to clean `~/.config/agentkey/`
(telemetry-disabled, update-disabled, snooze state)

## Blocked on

**AgentKey-Server PR** that registers the
`agentkey_internal/telemetry/event` MCP tool (must be filtered out of
`list_tools` / `find_tools` so the LLM doesn't accidentally call it).
SKILL.md falls back silently when the tool doesn't exist, so this PR is
safe to merge first — but the telemetry signal isn't recorded until the
server side lands.

Spec §11 mandates server-first merge order to keep the agent-side debug
log clean.

## Test plan

- [x] `bats tests/check-update.bats` — 10/10 passing locally
- [x] E2E smoke (skill-side plan Task 8 steps 1-3, 5):
  - Default emit on `up_to_date`
- `~/.config/agentkey/telemetry-disabled` early-return (no TELEMETRY
line)
  - `AGENTKEY_TELEMETRY=0` env override
  - 24h heartbeat dedup (2nd invocation within window does not re-emit)
  - `uninstall.sh` Step 7b cleans `~/.config/agentkey/`
- [ ] **Manual** — open Claude Code, ask an AgentKey-routed query.
Verify SKILL.md silently swallows the missing `agentkey_internal` tool
error (server not shipped yet) and the actual query still completes
- [ ] Verify bats CI runs green on ubuntu + macos matrix

## Pre-existing bug surfaced during testing (not in this PR)

`check-update.sh` line 130-ish cache fast-path uses the same wrong `stat
-f %m ... || stat -c %Y` order. Same Linux bug as the one fixed here in
`emit_telemetry`. Worth a separate one-line fix PR.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: lxcong <lxcong@chainbase.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 16:41:35 +08:00

109 lines
3.4 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bats
load helpers
setup() {
setup_isolated_env
}
teardown() {
teardown_isolated_env
}
@test "exits silently when update-disabled file exists" {
touch "$XDG_CONFIG_HOME/agentkey/update-disabled"
# Disable telemetry so the silent-exit contract is unaffected by Task 3's
# emit on the update-disabled branch.
touch "$XDG_CONFIG_HOME/agentkey/telemetry-disabled"
run_check_update
[ "$status" -eq 0 ]
[ -z "$output" ]
}
@test "set_local_version helper correctly overrides embedded version" {
set_local_version "9.9.9"
grep -q '^LOCAL_VERSION="9.9.9"' "$SCRIPT"
}
@test "telemetry-disabled file does not break existing update flow" {
touch "$XDG_CONFIG_HOME/agentkey/telemetry-disabled"
set_local_version "1.0.0"
mock_curl_release "v1.0.0"
run_check_update
[ "$status" -eq 0 ]
# 行为不变UP_TO_DATE 仍然输出
[[ "$output" == *"UP_TO_DATE"* ]]
# Task 2 还没引入 emitTask 3 才会加;此处主要保 telemetry-disabled 文件不会
# 让脚本崩。
}
@test "emits TELEMETRY skill_loaded up_to_date when versions match" {
set_local_version "1.0.0"
mock_curl_release "v1.0.0"
run_check_update
[ "$status" -eq 0 ]
[[ "$output" == *"UP_TO_DATE"* ]]
[[ "$output" == *"TELEMETRY skill_loaded"* ]]
[[ "$output" == *"update_state=up_to_date"* ]]
[[ "$output" == *"skill_version=1.0.0"* ]]
}
@test "emits TELEMETRY skill_loaded upgrade_available when newer release exists" {
set_local_version "1.0.0"
mock_curl_release "v2.0.0"
run_check_update
[ "$status" -eq 0 ]
[[ "$output" == *"UPGRADE_AVAILABLE 1.0.0 2.0.0"* ]]
[[ "$output" == *"TELEMETRY skill_loaded"* ]]
[[ "$output" == *"update_state=upgrade_available"* ]]
[[ "$output" == *"latest_version=2.0.0"* ]]
}
@test "emits TELEMETRY skill_loaded disabled when update-disabled file exists" {
touch "$XDG_CONFIG_HOME/agentkey/update-disabled"
set_local_version "1.0.0"
# 注意 update-disabled 早返发生在 curl 之前,所以不需要 mock_curl_release。
run_check_update
[ "$status" -eq 0 ]
[[ "$output" == *"TELEMETRY skill_loaded"* ]]
[[ "$output" == *"update_state=disabled"* ]]
# update-disabled 不应再输出 UP_TO_DATE / UPGRADE_AVAILABLE 主行
[[ "$output" != *"UP_TO_DATE"* ]]
[[ "$output" != *"UPGRADE_AVAILABLE"* ]]
}
@test "second invocation within 24h does not re-emit telemetry" {
set_local_version "1.0.0"
mock_curl_release "v1.0.0"
run_check_update
[[ "$output" == *"TELEMETRY skill_loaded"* ]]
run_check_update
[[ "$output" == *"UP_TO_DATE"* ]]
[[ "$output" != *"TELEMETRY"* ]]
}
@test "AGENTKEY_TELEMETRY=0 disables emit" {
set_local_version "1.0.0"
mock_curl_release "v1.0.0"
AGENTKEY_TELEMETRY=0 run_check_update
[[ "$output" == *"UP_TO_DATE"* ]]
[[ "$output" != *"TELEMETRY"* ]]
}
@test "telemetry-disabled file disables emit" {
set_local_version "1.0.0"
mock_curl_release "v1.0.0"
touch "$XDG_CONFIG_HOME/agentkey/telemetry-disabled"
run_check_update
[[ "$output" == *"UP_TO_DATE"* ]]
[[ "$output" != *"TELEMETRY"* ]]
}
@test "emits auto_upgrade_enabled=1 when auto-upgrade file exists" {
set_local_version "1.0.0"
mock_curl_release "v1.0.0"
touch "$XDG_CONFIG_HOME/agentkey/auto-upgrade"
run_check_update
[[ "$output" == *"auto_upgrade_enabled=1"* ]]
}