Help us improve
Share bugs, ideas, or general feedback.
From agent-flow
Compares installed plugin version with the latest available by reading the plugin registry and checking remote sources.
npx claudepluginhub asysta-act/agent-flow --plugin agent-flowHow this skill is triggered — by the user, by Claude, or both
Slash command
/agent-flow:version-checkThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Check whether the installed plugin version is up to date. Works from any directory.
Checks if the bopen-tools plugin is up to date by comparing local and GitHub versions. Returns status (current, outdated, etc.) and suggests update commands. Fast (~70ms).
Checks and updates CWF plugin across scopes to align with latest marketplace versions and fixes. Triggers: 'cwf:update', 'update cwf', 'check for updates'.
Updates the WOZCODE plugin to the latest version from its marketplace, with fallback steps for authentication and installation issues.
Share bugs, ideas, or general feedback.
Check whether the installed plugin version is up to date. Works from any directory.
| Key | Value |
|---|---|
| Plugin | agent-flow |
| Marketplace | agent-flow |
| Legacy names | CLAUDE-agents |
All steps below use {plugin} and {marketplace} from this table.
Read ~/.claude/plugins/installed_plugins.json.
~/.claude/plugins/installed_plugins.json. No plugins installed — run /plugin install first." and STOP.~/.claude/plugins/installed_plugins.json is empty or corrupt — cannot parse." and STOP.plugins that starts with {plugin}@. If no match, also search for keys starting with any name in Legacy names (e.g. CLAUDE-agents@). Prefer {plugin}@{marketplace} if it exists; otherwise use the first match./plugin install {plugin}@{marketplace}" and STOP.version and installPath from the matched entry. Store as installed_version, install_path, and note the actual registry key as registry_key.registry_key does not equal {plugin}@{marketplace} → warn: "Plugin is registered under {registry_key} instead of {plugin}@{marketplace}. Consider reinstalling: /plugin uninstall {plugin} then /plugin install {plugin}@{marketplace}"Verify install_path exists on disk.
{install_path} does not exist — plugin may need reinstalling. Run: /plugin uninstall {plugin} then /plugin install {plugin}@{marketplace}". Continue to step 3.Determine the latest available version from remote.
.claude-plugin/plugin.json exists with matching name) → use git remote get-url origin from CWD. This is the most reliable source (uses the developer's configured SSH/HTTPS auth).{install_path}/.claude-plugin/plugin.json and extract the repository field.repository); source-1 (user git remote) is trusted by definition.
# RFC 2606 reserved TLD fast-fail:
# source-2 only; HTTPS-only scope; SSH SCP-style deferred (no source-1 check)
# Extract hostname from URL, then match (test|example|invalid|localhost) as last DNS label
# or as the bare host. Path-anchored matching avoids false positives where a reserved
# label appears in a path component (e.g. github.com/foo.invalid/bar).
# Match alternation kept inline for harness compatibility: (test|example|invalid|localhost)
host=$(echo "$remote_url" | sed -E 's|^[a-z]+://([^/]+).*|\1|' | sed -E 's|^[^@]+@||' | sed -E 's|:[0-9]+$||')
host="${host%.}" # strip RFC 1034 trailing dot
last_label=$(echo "$host" | awk -F. '{print $NF}')
if [ "$last_label" = "test" ] || [ "$last_label" = "example" ] || [ "$last_label" = "invalid" ] || [ "$last_label" = "localhost" ] \
|| [ "$host" = "test" ] || [ "$host" = "example" ] || [ "$host" = "invalid" ] || [ "$host" = "localhost" ]; then
echo "Remote version check skipped — plugin.json \`repository\` field is a placeholder. Set it to a real URL."
exit 0
fi
The boundary anchor (/|:|$) is implicit in the hostname-extract step — the host is delimited by / or end-of-string after the scheme, so the URL parser handles boundary detection.timeout 10 git ls-remote --tags {remote_url} 'refs/tags/v*' 2>/dev/null | grep -v '\^{}' | sort -t/ -k3 -V | tail -1
If timeout is not available, omit it and run git ls-remote directly.v*) → report: "No version tags found on remote repository. Showing installed version only." Skip to step 4.refs/tags/v5.5.1 → 5.5.1). Store as remote_version.Compare and display.
remote_version is not available (skipped in step 3) → display: "{plugin} {installed_version} (installed) — remote version unknown" and proceed to Part B.installed_version and remote_version as semantic versions: split each on . and compare each component (major, minor, patch) as integers — NOT as strings. To determine which version is smaller, use:
printf '%s\n' "$installed_version" "$remote_version" | sort -V | head -1
If the result equals $installed_version and $installed_version != $remote_version, then remote_version is newer.installed_version == remote_version → "{plugin} {installed_version} — up to date"installed_version < remote_version → "{plugin} {installed_version} → {remote_version} — update available. Run: /plugin uninstall {plugin} then /plugin install {plugin}@{marketplace}"installed_version > remote_version → "{plugin} {installed_version} > {remote_version} — installed version is newer than remote"Check if .claude-plugin/plugin.json exists in the current working directory.
name field from it.name does not equal {plugin} → skip Part B silently (CWD is a different plugin's repo).name equals {plugin} → read version from the same file. Store as repo_version.If remote_version is available and repo_version < remote_version: auto-pull.
git pull to update the repo to the latest remote version.git pull fails (merge conflict, dirty working tree, etc.) → warn: "git pull failed — repo stays at {repo_version}." and continue with the current repo_version.git pull succeeds → re-read version from .claude-plugin/plugin.json and update repo_version.Compare repo_version with installed_version.
{registry_key} — it is the part after the @ (e.g. agent-flow@CLAUDE-agents → marketplace is CLAUDE-agents). Store as {actual_marketplace}.claude plugin marketplace update {actual_marketplace}
claude plugin update "{registry_key}" --scope user
/reload-plugins to apply, or changes take effect on the next Claude Code session."/plugin uninstall {plugin} then /plugin install {plugin}@{marketplace}".claude-plugin/plugin.json whose name field matches the Plugin Identity. Step 6 auto-pulls if repo is behind remote.~/.claude/plugins/installed_plugins.json, NOT the cache directory structurerepository field in {install_path}/.claude-plugin/plugin.json — never use a hardcoded URL