mirror of
https://github.com/chainbase-labs/Agentkey.git
synced 2026-09-20 14:20:23 +08:00
fix(update-check): ship version.txt inside skill so npx-skills-add installs find it (#26)
## Problem The skill assumed the whole repo is the plugin root (`PLUGIN_ROOT` = repo root, `version.txt` at repo root). That holds in Claude Code plugin mode, where Claude Code injects `CLAUDE_PLUGIN_ROOT`. But the README's recommended path — ``` npx skills add chainbase-labs/agentkey ``` — uses [vercel-labs/skills](https://github.com/vercel-labs/skills), which only copies the `skills/agentkey/` subdirectory to `~/.claude/skills/agentkey/`. The repo-root `version.txt` doesn't come along. In that layout, `check-update.sh`'s fallback ```bash PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." 2>/dev/null && pwd)}" ``` resolves `../../..` from `~/.claude/skills/agentkey/scripts/` to `~/.claude/`, so `VERSION_FILE` points at `~/.claude/version.txt` — which doesn't exist. `LOCAL_VERSION` ends up empty, the script silently `exit 0`s at line 35, and **skills-CLI users never see upgrade prompts at all**. (Worse case: if some other tool ever drops a `~/.claude/version.txt`, AgentKey would read it as its own version.) This is an interface contract mismatch between the two distribution models, not a one-sided bug — both are valid, but the skill needs to work under either. ## Fix 1. Move `version.txt` into the skill directory (`skills/agentkey/version.txt`) so it travels with whichever subset of the repo gets copied. 2. In `check-update.sh`, anchor on `SKILL_ROOT` (one level above `scripts/`) instead of an external `CLAUDE_PLUGIN_ROOT`. Both distribution paths now resolve identically: - Plugin: `<repo>/skills/agentkey/version.txt` - Skills CLI: `~/.claude/skills/agentkey/version.txt` 3. Point release-please at the new path via `version-file`. The `plugin.json` `extra-files` entry is unchanged. 4. Update docs (README, `docs/README_zh.md`, `.claude/CLAUDE.md`, `SECURITY.md`, `claude-pr-review.yml`) to reflect the new path. ## Test plan - [x] `bash skills/agentkey/scripts/check-update.sh` in repo: resolves `SKILL_ROOT` to `<repo>/skills/agentkey`, reads `LOCAL_VERSION=1.2.2` correctly. - [x] Simulated skills-CLI install: `cp -r skills/agentkey /tmp/sim/` then ran `bash /tmp/sim/agentkey/scripts/check-update.sh` with `CLAUDE_PLUGIN_ROOT` unset → resolves `SKILL_ROOT=/tmp/sim/agentkey`, reads `LOCAL_VERSION=1.2.2` correctly. - [ ] After merge, the next release-please Release PR should bump `skills/agentkey/version.txt` (along with `plugin.json` and `CHANGELOG.md`) — please verify the Release PR diff before merging it. - [ ] After release, on a fresh `npx skills add chainbase-labs/agentkey` install, an out-of-date version should now correctly produce `UPGRADE_AVAILABLE <old> <new>` and trigger the existing AskUserQuestion prompt flow. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+7
-6
@@ -23,10 +23,10 @@ agentkey/
|
||||
├── .mcp.json # Auto-registers AgentKey MCP when installed as a plugin
|
||||
├── skills/agentkey/
|
||||
│ ├── SKILL.md # Decision tree + routing rules (end-user facing)
|
||||
│ └── scripts/ # check-mcp / check-update helpers
|
||||
├── scripts/
|
||||
│ └── uninstall.sh # End-user cleanup helper
|
||||
└── version.txt # Managed by release-please only
|
||||
│ ├── scripts/ # check-mcp / check-update helpers
|
||||
│ └── version.txt # Managed by release-please only — must live inside the skill so it survives `npx skills add`
|
||||
└── scripts/
|
||||
└── uninstall.sh # End-user cleanup helper
|
||||
```
|
||||
|
||||
## Key Commands
|
||||
@@ -48,11 +48,12 @@ git tag -d vX.Y.Z && git push origin :refs/tags/vX.Y.Z
|
||||
gh release delete vX.Y.Z --repo chainbase-labs/agentkey --yes
|
||||
```
|
||||
|
||||
Releases are driven by [release-please](https://github.com/googleapis/release-please): merged PRs with Conventional Commit messages (`feat:`, `fix:`, `feat!:`, etc.) update an open Release PR that bumps `version`, `.claude-plugin/plugin.json` version, and `CHANGELOG.md`. Merging the Release PR tags the release and creates the GitHub Release, which in turn triggers plugin updates for users.
|
||||
Releases are driven by [release-please](https://github.com/googleapis/release-please): merged PRs with Conventional Commit messages (`feat:`, `fix:`, `feat!:`, etc.) update an open Release PR that bumps `skills/agentkey/version.txt`, `.claude-plugin/plugin.json` version, and `CHANGELOG.md`. Merging the Release PR tags the release and creates the GitHub Release, which in turn triggers plugin updates for users.
|
||||
|
||||
## Version & Release Rules
|
||||
|
||||
- `version`, `.claude-plugin/plugin.json` version, and `CHANGELOG.md` are managed by release-please based on Conventional Commits — never edit manually except via PR that intentionally amends them.
|
||||
- `skills/agentkey/version.txt`, `.claude-plugin/plugin.json` version, and `CHANGELOG.md` are managed by release-please based on Conventional Commits — never edit manually except via PR that intentionally amends them.
|
||||
- `version.txt` lives inside `skills/agentkey/` (not at repo root) so it travels with the skill when the Skills CLI copies the subdirectory. `release-please-config.json` points at this path via `version-file`.
|
||||
- Tag format: `v` prefix (e.g. `v0.4.5`)
|
||||
- Plugin updates trigger on **GitHub Release** publication, not on plain commits
|
||||
- `npx skills update` pulls from the default branch, so main must always be shippable
|
||||
|
||||
@@ -186,7 +186,7 @@ jobs:
|
||||
|
||||
### 4b. Files that shouldn't be touched directly
|
||||
- `archive/**` — retired code
|
||||
- `version.txt` — managed by release-please
|
||||
- `skills/agentkey/version.txt` — managed by release-please
|
||||
- `.release-please-manifest.json` — managed
|
||||
- `CHANGELOG.md` — managed (unless part of a release PR
|
||||
from release-please itself, which won't trigger this
|
||||
|
||||
@@ -342,16 +342,16 @@ agentkey/
|
||||
├── .mcp.json # Used when installed as a plugin
|
||||
├── skills/agentkey/
|
||||
│ ├── SKILL.md # Decision tree + routing rules
|
||||
│ └── scripts/ # check-mcp / check-update helpers
|
||||
├── scripts/
|
||||
│ ├── install.sh # One-command installer (mac/linux)
|
||||
│ ├── install.ps1 # Windows PowerShell installer
|
||||
│ ├── uninstall.sh # One-command uninstaller (mac/linux)
|
||||
│ └── uninstall.ps1 # Windows PowerShell uninstaller
|
||||
└── version.txt # Managed by release-please
|
||||
│ ├── scripts/ # check-mcp / check-update helpers
|
||||
│ └── version.txt # Managed by release-please
|
||||
└── scripts/
|
||||
├── install.sh # One-command installer (mac/linux)
|
||||
├── install.ps1 # Windows PowerShell installer
|
||||
├── uninstall.sh # One-command uninstaller (mac/linux)
|
||||
└── uninstall.ps1 # Windows PowerShell uninstaller
|
||||
```
|
||||
|
||||
**Release a new version (maintainers):** releases are cut automatically by [release-please](https://github.com/googleapis/release-please). Merging a PR with a `feat:` or `fix:` title opens a Release PR that bumps `version.txt`, `plugin.json`, and `CHANGELOG.md`. Merging the Release PR creates the tag + GitHub Release + uploads the `agentkey.skill` asset.
|
||||
**Release a new version (maintainers):** releases are cut automatically by [release-please](https://github.com/googleapis/release-please). Merging a PR with a `feat:` or `fix:` title opens a Release PR that bumps `skills/agentkey/version.txt`, `plugin.json`, and `CHANGELOG.md`. Merging the Release PR creates the tag + GitHub Release + uploads the `agentkey.skill` asset.
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
+2
-2
@@ -32,7 +32,7 @@ We follow coordinated disclosure. Once a fix is available, we publish a security
|
||||
|
||||
The skill ships two helper scripts that the agent invokes:
|
||||
|
||||
- **`skills/agentkey/scripts/check-update.sh`** — **notify-only**. At most every 60 minutes (12 hours once an upgrade is known), it calls `https://api.github.com/repos/chainbase-labs/agentkey/releases/latest`, compares the tag against the local `version.txt`, and prints `UPGRADE_AVAILABLE <old> <new>` if they differ. The script also honors a snooze file (`~/.config/agentkey/update-snoozed`, escalating 24h/48h/7d backoff) and a disable file (`~/.config/agentkey/update-disabled`); both are read-only from this script's perspective. The script never runs `git`, never writes to anything except its TMPDIR cache, and never executes downloaded code.
|
||||
- **`skills/agentkey/scripts/check-update.sh`** — **notify-only**. At most every 60 minutes (12 hours once an upgrade is known), it calls `https://api.github.com/repos/chainbase-labs/agentkey/releases/latest`, compares the tag against the local `skills/agentkey/version.txt`, and prints `UPGRADE_AVAILABLE <old> <new>` if they differ. The script also honors a snooze file (`~/.config/agentkey/update-snoozed`, escalating 24h/48h/7d backoff) and a disable file (`~/.config/agentkey/update-disabled`); both are read-only from this script's perspective. The script never runs `git`, never writes to anything except its TMPDIR cache, and never executes downloaded code.
|
||||
|
||||
When the agent sees `UPGRADE_AVAILABLE` it surfaces an `AskUserQuestion` prompt (Yes / Always / Not now / Never). The actual update — `npx skills update chainbase-labs/agentkey` — runs only after the user picks "Yes" or "Always", or if the user has previously opted into auto-upgrade via `AGENTKEY_AUTO_UPGRADE=1` or `~/.config/agentkey/auto-upgrade`. The agent invokes that command via its own Bash tool, not via this script.
|
||||
- **`skills/agentkey/scripts/check-mcp.sh`** — reads `~/.claude.json` and `~/.env.local` to verify the AgentKey MCP server is registered and the API key is present. **Read-only**; no network egress; output is a single status code.
|
||||
@@ -73,7 +73,7 @@ The skill ships two helper scripts that the agent invokes:
|
||||
|
||||
Automated scanners (VirusTotal, ClawScan) may flag this skill as `Suspicious` due to two intentional patterns. We document them here so reviewers can verify intent:
|
||||
|
||||
1. **`check-update.sh` contacts GitHub.** Pattern may match "remote-controlled binary update" heuristics. **Why this is intentional:** the script is notify-only — it issues a single `GET https://api.github.com/repos/chainbase-labs/agentkey/releases/latest`, compares the tag against `version.txt`, prints a one-line status, and exits. It never writes anywhere except the cache file at `${TMPDIR}/agentkey-update-check`, never invokes `git`, and never executes downloaded code. Update execution lives entirely in the agent's interactive layer (`AskUserQuestion` → `npx skills update`), gated by explicit user consent or a previously persisted opt-in flag.
|
||||
1. **`check-update.sh` contacts GitHub.** Pattern may match "remote-controlled binary update" heuristics. **Why this is intentional:** the script is notify-only — it issues a single `GET https://api.github.com/repos/chainbase-labs/agentkey/releases/latest`, compares the tag against `skills/agentkey/version.txt`, prints a one-line status, and exits. It never writes anywhere except the cache file at `${TMPDIR}/agentkey-update-check`, never invokes `git`, and never executes downloaded code. Update execution lives entirely in the agent's interactive layer (`AskUserQuestion` → `npx skills update`), gated by explicit user consent or a previously persisted opt-in flag.
|
||||
2. **`check-mcp.sh` reads `*API_KEY*` env values.** Pattern matches "credential harvesting" heuristics. **Why this is intentional:** the read is local-only, never transmitted, and exists purely to confirm `AGENTKEY_API_KEY` is configured before the agent attempts an MCP call. The script's only output is a one-word status code (`MCP_OK` / `MCP_NO_KEY` / `MCP_NOT_CONFIGURED`); the key value itself is discarded.
|
||||
|
||||
If you operate a scanner and need additional context to triage, please email `support@chainbase.com`.
|
||||
|
||||
+8
-8
@@ -342,16 +342,16 @@ agentkey/
|
||||
├── .mcp.json # 作为插件安装时使用
|
||||
├── skills/agentkey/
|
||||
│ ├── SKILL.md # 决策树 & 路由规则
|
||||
│ └── scripts/ # check-mcp / check-update 辅助脚本
|
||||
├── scripts/
|
||||
│ ├── install.sh # 一键安装脚本(mac/linux)
|
||||
│ ├── install.ps1 # Windows PowerShell 安装脚本
|
||||
│ ├── uninstall.sh # 一键卸载脚本(mac/linux)
|
||||
│ └── uninstall.ps1 # Windows PowerShell 卸载脚本
|
||||
└── version.txt # 由 release-please 自动维护
|
||||
│ ├── scripts/ # check-mcp / check-update 辅助脚本
|
||||
│ └── version.txt # 由 release-please 自动维护
|
||||
└── scripts/
|
||||
├── install.sh # 一键安装脚本(mac/linux)
|
||||
├── install.ps1 # Windows PowerShell 安装脚本
|
||||
├── uninstall.sh # 一键卸载脚本(mac/linux)
|
||||
└── uninstall.ps1 # Windows PowerShell 卸载脚本
|
||||
```
|
||||
|
||||
**发布新版本(Maintainer):** 发版由 [release-please](https://github.com/googleapis/release-please) 自动触发。合并一个 `feat:` 或 `fix:` 的 PR 后,release-please 会开一个 Release PR,自动 bump `version.txt`、`plugin.json`、`CHANGELOG.md`。合并这个 Release PR 即会创建 tag + GitHub Release + 上传 `agentkey.skill` 产物。
|
||||
**发布新版本(Maintainer):** 发版由 [release-please](https://github.com/googleapis/release-please) 自动触发。合并一个 `feat:` 或 `fix:` 的 PR 后,release-please 会开一个 Release PR,自动 bump `skills/agentkey/version.txt`、`plugin.json`、`CHANGELOG.md`。合并这个 Release PR 即会创建 tag + GitHub Release + 上传 `agentkey.skill` 产物。
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"package-name": "agentkey-skill",
|
||||
"release-type": "simple",
|
||||
"changelog-path": "CHANGELOG.md",
|
||||
"version-file": "skills/agentkey/version.txt",
|
||||
"bump-minor-pre-major": false,
|
||||
"bump-patch-for-minor-pre-major": false,
|
||||
"include-v-in-tag": true,
|
||||
|
||||
@@ -19,8 +19,13 @@ CACHE_TTL_UP_TO_DATE=3600 # 60 min — detect new releases quickly
|
||||
CACHE_TTL_UPGRADE=43200 # 12 h — keep nagging once an upgrade is known
|
||||
CURL_TIMEOUT=3
|
||||
|
||||
PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." 2>/dev/null && pwd)}"
|
||||
VERSION_FILE="$PLUGIN_ROOT/version.txt"
|
||||
# Anchor on the skill directory itself, not on a "plugin root" — the skill is
|
||||
# distributed two ways with different layouts: as a Claude Code plugin (whole
|
||||
# repo) or via the Skills CLI (only `skills/agentkey/` is copied to
|
||||
# ~/.claude/skills/agentkey/). Resolving relative to this script keeps both
|
||||
# paths working without depending on CLAUDE_PLUGIN_ROOT.
|
||||
SKILL_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." 2>/dev/null && pwd)"
|
||||
VERSION_FILE="$SKILL_ROOT/version.txt"
|
||||
CACHE_FILE="${TMPDIR:-/tmp}/agentkey-update-check"
|
||||
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/agentkey"
|
||||
DISABLED_FILE="$CONFIG_DIR/update-disabled"
|
||||
|
||||
Reference in New Issue
Block a user