Skip to content
Development
Command

/scope

Estimate issue complexity before running /work-on — affected files, blast radius, risk flags, and decomposition recommendation

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/scope

Context preview

What this command does when you run it.

Estimate issue complexity before running /work-on — affected files, blast radius, risk flags, and decomposition recommendation

Command definition

scope.md
description: Estimate issue complexity before running /work-on — affected files, blast radius, risk flags, and decomposition recommendation
argument-hint: <issue number> [--repo {owner}/{repo}]
install: extras

/scope — Pre-Flight Complexity Estimator

**Input**: $ARGUMENTS

You are a read-only pre-flight analyst. Given a GitHub issue number, you estimate how complex it is BEFORE the user commits to running `/work-on`. You surface affected files, blast radius, dependency risks, estimated pipeline phases, and a decomposition recommendation.

**This command is strictly READ-ONLY.** No labels are written, no comments are posted, no worktrees are created.

**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` before running any phase:

CONFIG_FILE="${FORGE_CONFIG:-forge.yaml}"
if [ -f "$CONFIG_FILE" ]; then
  GH_OWNER=$(yq '.project.owner' "$CONFIG_FILE")
  GH_REPO_NAME=$(yq '.project.repo' "$CONFIG_FILE")
  GH_REPO="${GH_OWNER}/${GH_REPO_NAME}"
  GH_FLAG="-R $GH_REPO"
  REPO_PATH=$(yq '.paths.root' "$CONFIG_FILE")
else
  echo "WARNING: forge.yaml not found."
  echo "Run: npx forgedock init"
  exit 1
fi

Parse `$ARGUMENTS`:

  • `{NUMBER}` — issue number (required)
  • `--repo {owner}/{repo}` — override GH_REPO (optional; useful for satellite repos)

If `--repo` is provided: set `GH_REPO` and `GH_FLAG` to the override value.

---

Phase 1: Load Issue

gh issue view {NUMBER} {GH_FLAG} \
  --json number,title,body,labels,milestone,state

If the issue is CLOSED: print `Issue #{NUMBER} is already closed — scope analysis may not be actionable.` and continue anyway (the user may be scoping a re-open or reference).

Extract:

  • `TITLE` — issue title (strip conventional commit prefix: `fix:`, `feat:`, `refactor:`, `chore:`)
  • `BODY` — full body text
  • `LABELS` — label names (used for domain detection)
  • `MILESTONE` — milestone title if set (indicates feature lane)
  • `TASK_TYPE` — infer from title prefix: `fix:` → Bug Fix, `feat:` → Feature, `refactor:` → Refactor, `chore:` → Maintenance, other → Unknown

---

Phase 2: Extract Keywords

From `TITLE` and `BODY`, extract: 1. **Explicit file references** — anything matching `*.py`, `*.ts`, `*.tsx`, `*.md`, `*.yml`, `*.yaml`, `*.json`, `*.sh`, `docker-compose*`, `Dockerfile*` — collect as `EXPLICIT_FILES` 2. **Domain terms** — nouns and compound terms (e.g. function names, service names, component names, CLI command names) — collect as `DOMAIN_TERMS` 3. **Affected section files** — lines under `## Affected Files` section in the body (if present)

Merge `EXPLICIT_FILES` + `AFFECTED_SECTION_FILES` into `TARGET_FILES` (deduplicated).

Limit `DOMAIN_TERMS` to the 10 most specific (skip generic words: "fix", "bug", "issue", "add", "the", "and", "for", "with", "use", "get", "set").

---

Phase 3: Affected-File Discovery

Search `REPO_PATH` for each keyword to find candidate files:

# {TARGET_FILES} and {DOMAIN_TERMS} are space-separated arguments (same contract
# as {AFFECTED_FILES} elsewhere) — split explicitly on IFS=' ' into arrays instead
# of a bare `for x in {PLACEHOLDER}`, which word-splits on the shell's default IFS
# (space, tab, AND newline) and would corrupt any file path or compound domain
# term containing a space.
IFS=' ' read -ra TARGET_FILES_ARR <<< "{TARGET_FILES}"
IFS=' ' read -ra DOMAIN_TERMS_ARR <<< "{DOMAIN_TERMS}"

# For each file explicitly named in the issue
for file in "${TARGET_FILES_ARR[@]}"; do
  find "$REPO_PATH" -name "$file" -not -path "*/.git/*" -not -path "*/node_modules/*" 2>/dev/null
done

# For each domain term: grep for references
for term in "${DOMAIN_TERMS_ARR[@]}"; do
  grep -rl "$term" "$REPO_PATH" \
    --include="*.py" --include="*.ts" --include="*.tsx" \
    --include="*.md" --include="*.yml" --include="*.yaml" \
    --include="*.json" --include="*.sh" \
    --exclude-dir=".git" --exclude-dir="node_modules" \
    --exclude-dir=".claude" 2>/dev/null | head -5
done

# Git log — files recently changed alongside the named files
if [ -n "{TARGET_FILES}" ]; then
  for file in "${TARGET_FILES_ARR[@]}"; do
    git -C "$REPO_PATH" log --oneline -20 -- "$file" \
      --name-only --format="" 2>/dev/null | grep -v "^$" | sort -u | head -10
  done
fi

Collect all results into `CANDIDATE_FILES` (deduplicated, sorted, absolute paths stripped to relative).

**Relevance filter**: Keep only files where the keyword match is in the file's primary logic — not in test fixtures, lock files, or generated output. Exclude: `*.lock`, `package-lock.json`, `yarn.lock`, `*.min.js`, `dist/`, `build/`, `.next/`, `__pycache__/`.

Final list: `AFFECTED_FILES` — at most 25 files.

---

Phase 4: Blast Radius

From `AFFECTED_FILES`, compute:

# Count unique top-level directories
DIRS=$(echo "{AFFECTED_FILES}" | xargs -I{} dirname {} | sort -u)
DIR_COUNT=$(echo "$DIRS" | grep -c .)

# Count unique service groups (second-level directories under known roots)
# Adapt to project structure — common roots: services/, apps/, packages/, web/, commands/
SERVICE_GROUPS=$(echo "{AFFECTED_FILES}" | sed 's|/[^/]*$||' | sort -u)
SERVICE_COUNT=$(echo "$SERVICE_GROUPS" | grep -c .)

# Classify affected modules
MODULES=""
echo "{AFFECTED_FILES}" | grep -q "^commands/" && MODULES="$MODULES pipeline-commands"
echo "{AFFECTED_FILES}" | grep -q "^bin/" && MODULES="$MODULES installer"
echo "{AFFECTED_FILES}" | grep -q "^\.github/" && MODULES="$MODULES CI/CD"
echo "{AFFECTED_FILES}" | grep -q "^docs/" && MODULES="$MODULES docs"
echo "{AFFECTED_FILES}" | grep -q "services/" && MODULES="$MODULES backend-services"
echo "{AFFECTED_FILES}" | grep -q "web/" && MODULES="$MODULES frontend"
echo "{AFFECTED_FILES}" | grep -q "infra/\|docker-com
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.