Skip to content
Development
Command

/compat-audit

On-demand Claude Code compatibility and feature parity report — compares installed version against the breakpoints registry and lists affected ForgeDock features

BOOST
From plugin
forgedock
11980 skills80 commands
Install
> /plugin marketplace add RapierCraftStudios/ForgeDock
> /plugin install forgedock@forgedock

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/compat-audit

Context preview

What this command does when you run it.

On-demand Claude Code compatibility and feature parity report — compares installed version against the breakpoints registry and lists affected ForgeDock features

Command definition

compat-audit.md
description: On-demand Claude Code compatibility and feature parity report — compares installed version against the breakpoints registry and lists affected ForgeDock features
argument-hint: "[--refresh]"
install: extras

/compat-audit — Claude Code Compatibility Report

**Input**: $ARGUMENTS

You are the ForgeDock compatibility auditor. Produce a point-in-time advisory report that shows whether the user's installed Claude Code version is current and which ForgeDock features may behave differently on their runtime. This command is **non-blocking** — it never aborts the session. All output is advisory.

**Agent model policy**: `model: "{DEFAULT_MODEL}"` — resolved from forge.yaml `agents.default_model`, else "sonnet" (standard tier). Fallback: `model: "opus"` if rate-limited. Feature gate: pass `effort` in Task/Skill spawns only on Claude Code >= 2.1.154. **NEVER use plan mode (EnterPlanMode).**

---

Config Preamble

Read `forge.yaml` to resolve the ForgeDock installation path:

CONFIG_FILE="${FORGE_CONFIG:-forge.yaml}"
if [ -f "$CONFIG_FILE" ]; then
  FORGE_HOME_PATH=$(yq '.paths.root // ""' "$CONFIG_FILE" 2>/dev/null || echo "")
fi

# Fallback: resolve from this command file's own location if yq is unavailable
# or forge.yaml is absent. The commands/ directory is always inside FORGE_HOME.
if [ -z "$FORGE_HOME_PATH" ] || [ ! -d "$FORGE_HOME_PATH" ]; then
  FORGE_HOME_PATH="$(cd "$(dirname "${BASH_SOURCE[0]:-${0}}")/.." 2>/dev/null && pwd)"
fi
export FORGE_HOME_PATH

---

Phase 1: Parse Arguments

Parse `$ARGUMENTS` for the `--refresh` flag:

REFRESH=false
for arg in $ARGUMENTS; do
  [ "$arg" = "--refresh" ] && REFRESH=true
done

**If `--refresh` is set**: delete the version cache before detection so the npm registry is queried for the latest version regardless of TTL:

VERSION_CACHE="$HOME/.claude/forgedock/version-cache.json"
if [ "$REFRESH" = "true" ] && [ -f "$VERSION_CACHE" ]; then
  rm -f "$VERSION_CACHE"
  echo "Version cache cleared — will query npm registry for fresh data."
fi

---

Phase 2: Detect Installed Claude Code Version

Run `detectClaudeVersion()` from `bin/forge-utils.mjs`. This function reads from the cache at `~/.claude/forgedock/version-cache.json` (24h TTL) on a cache hit, or queries `npm info @anthropic-ai/claude-code version` and `claude --version` on a miss. It is fail-open — it never throws.

VERSION_CACHE="$HOME/.claude/forgedock/version-cache.json"
INSTALLED="unknown"
LATEST="unknown"
STALE=false
DELTA=""
CACHED_AT=""
DAYS_SINCE_REFRESH="unknown"

if [ -f "$VERSION_CACHE" ]; then
  INSTALLED=$(CACHE_PATH="$VERSION_CACHE" node -e "
    try {
      const c = JSON.parse(require('fs').readFileSync(process.env.CACHE_PATH, 'utf8'));
      process.stdout.write(c.installed || 'unknown');
    } catch { process.stdout.write('unknown'); }
  " 2>/dev/null || echo "unknown")

  LATEST=$(CACHE_PATH="$VERSION_CACHE" node -e "
    try {
      const c = JSON.parse(require('fs').readFileSync(process.env.CACHE_PATH, 'utf8'));
      process.stdout.write(c.latest || 'unknown');
    } catch { process.stdout.write('unknown'); }
  " 2>/dev/null || echo "unknown")

  STALE=$(CACHE_PATH="$VERSION_CACHE" node -e "
    try {
      const c = JSON.parse(require('fs').readFileSync(process.env.CACHE_PATH, 'utf8'));
      process.stdout.write(c.stale === true ? 'true' : 'false');
    } catch { process.stdout.write('false'); }
  " 2>/dev/null || echo "false")

  DELTA=$(CACHE_PATH="$VERSION_CACHE" node -e "
    try {
      const c = JSON.parse(require('fs').readFileSync(process.env.CACHE_PATH, 'utf8'));
      process.stdout.write(c.delta || '');
    } catch { process.stdout.write(''); }
  " 2>/dev/null || echo "")

  DAYS_SINCE_REFRESH=$(CACHE_PATH="$VERSION_CACHE" node -e "
    try {
      const c = JSON.parse(require('fs').readFileSync(process.env.CACHE_PATH, 'utf8'));
      if (typeof c.cachedAt === 'number') {
        const days = Math.floor((Date.now() - c.cachedAt) / 86400000);
        process.stdout.write(days.toString());
      } else {
        process.stdout.write('unknown');
      }
    } catch { process.stdout.write('unknown'); }
  " 2>/dev/null || echo "unknown")
else
  # Cache absent — attempt a fresh detection by running detectClaudeVersion()
  DETECT_RESULT=$(node --input-type=module <<'NODE_EOF' 2>/dev/null
import { pathToFileURL } from 'url';
import { join, resolve, dirname } from 'path';
import { fileURLToPath } from 'url';
const forgeHome = process.env.FORGE_HOME_PATH || '.';
const utilsPath = join(forgeHome, 'bin', 'forge-utils.mjs');
try {
  const { detectClaudeVersion } = await import(pathToFileURL(utilsPath).href);
  const r = await detectClaudeVersion();
  process.stdout.write(JSON.stringify(r));
} catch {
  process.stdout.write(JSON.stringify({ version: 'unknown' }));
}
NODE_EOF
)
  INSTALLED=$(echo "$DETECT_RESULT" | node -e "
    try {
      const r = JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));
      process.stdout.write(r.installed || r.version || 'unknown');
    } catch { process.stdout.write('unknown'); }
  " 2>/dev/null || echo "unknown")
  LATEST=$(echo "$DETECT_RESULT" | node -e "
    try {
      const r = JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));
      process.stdout.write(r.latest || 'unknown');
    } catch { process.stdout.write('unknown'); }
  " 2>/dev/null || echo "unknown")
fi

**Fail-open**: if all detection attempts return `unknown`, proceed to Phase 3 and report degraded output.

---

Phase 3: Load Breakpoints Registry

Read `docs/claude-breakpoints.json` from the ForgeDock installation root:

BREAKPOINTS_FILE="${FORGE_HOME_PATH}/docs/claude-breakpoints.json"
BREAKPOINTS_JSON=""

if [ -f "$BREAKPOINTS_FILE" ]; then
  BREAKPOINTS_JSON=$(cat "$BREAKPOINTS_FILE" 2>/dev/null || echo "")
else
  echo "NOTE: docs/claude-breakpoints.json not found at ${FORGE_HOME_PATH}/docs/."
  echo "This file is included in ForgeDock v1.x+. Run: npx forgedock upd
Read more
Ships withforgedock

ForgeDock — autonomous AI dev pipeline for Claude Code. GitHub as agent memory: issue in, PR out.

Get the whole plugin

Other commands on forgedock.