Loading...
Loading...
Compare original and translation side by side
CLAUDE.md → rules → skills → hooks → subagents → verifiers## CommunicationStep 1/3: Collecting configuration data [1/10]
· CLAUDE.md (global + local) · rules/ · settings.local.json · hooks
· MCP servers · skills inventory + security scan
· conversation history (up to 2 recent sessions)CLAUDE.md → rules → skills → hooks → subagents → verifiers## CommunicationStep 1/3: Collecting configuration data [1/10]
· CLAUDE.md (global + local) · rules/ · settings.local.json · hooks
· MCP servers · skills inventory + security scan
· conversation history (up to 2 recent sessions)| Tier | Signal | What's expected |
|---|---|---|
| Simple | <500 project files, 1 contributor, no CI | CLAUDE.md only; 0–1 skills; no rules/; hooks optional |
| Standard | 500–5K project files, small team or CI present | CLAUDE.md + 1–2 rules files; 2–4 skills; basic hooks |
| Complex | >5K project files, multi-contributor, multi-language, active CI | Full six-layer setup required |
| 层级 | 判断信号 | 预期配置 |
|---|---|---|
| 简单 | 项目文件<500个、1名贡献者、无CI | 仅需CLAUDE.md;0-1个skill;无rules/目录;hooks可选 |
| 标准 | 项目文件500-5000个、小型团队或已接入CI | CLAUDE.md + 1-2个规则文件;2-4个skill;基础hooks |
| 复杂 | 项目文件>5000个、多贡献者、多语言、活跃CI | 需要完整的六层配置 |
P=$(pwd)
SETTINGS="$P/.claude/settings.local.json"
echo "[1/10] Tier metrics..."
echo "=== TIER METRICS ==="
echo "project_files: $(git -C "$P" ls-files 2>/dev/null | wc -l || find "$P" -type f -not -path "*/.git/*" -not -path "*/node_modules/*" -not -path "*/dist/*" -not -path "*/build/*" | wc -l)"
echo "contributors: $(git -C "$P" log -n 500 --format='%ae' 2>/dev/null | sort -u | wc -l)"
echo "ci_workflows: $(ls "$P/.github/workflows/"*.yml "$P/.github/workflows/"*.yaml 2>/dev/null | wc -l)"
echo "skills: $(find "$P/.claude/skills" -name "SKILL.md" 2>/dev/null | grep -v '/health/SKILL.md' | wc -l)"
echo "claude_md_lines: $(wc -l < "$P/CLAUDE.md" 2>/dev/null)"
echo "[2/10] CLAUDE.md (global + local)..."
echo "=== CLAUDE.md (global) ===" ; cat ~/.claude/CLAUDE.md 2>/dev/null || echo "(none)"
echo "=== CLAUDE.md (local) ===" ; cat "$P/CLAUDE.md" 2>/dev/null || echo "(none)"
echo "[3/10] Settings, hooks, MCP..."
echo "=== settings.local.json ===" ; cat "$SETTINGS" 2>/dev/null || echo "(none)"
echo "[4/10] Rules + skill descriptions..."
echo "=== rules/ ===" ; find "$P/.claude/rules" -name "*.md" 2>/dev/null | while IFS= read -r f; do echo "--- $f ---"; cat "$f"; done
echo "=== skill descriptions ===" ; { [ -d "$P/.claude/skills" ] && grep -r "^description:" "$P/.claude/skills" 2>/dev/null; grep -r "^description:" ~/.claude/skills 2>/dev/null; } | sort -u
echo "[5/10] Context budget estimate..."
echo "=== STARTUP CONTEXT ESTIMATE ==="
echo "global_claude_words: $(wc -w < ~/.claude/CLAUDE.md 2>/dev/null | tr -d ' ' || echo 0)"
echo "local_claude_words: $(wc -w < "$P/CLAUDE.md" 2>/dev/null | tr -d ' ' || echo 0)"
echo "rules_words: $(find "$P/.claude/rules" -name "*.md" 2>/dev/null | while IFS= read -r f; do cat "$f"; done | wc -w | tr -d ' ')"
echo "skill_desc_words: $({ [ -d "$P/.claude/skills" ] && grep -r "^description:" "$P/.claude/skills" 2>/dev/null; grep -r "^description:" ~/.claude/skills 2>/dev/null; } | wc -w | tr -d ' ')"
python3 -c "
import json, sys
try:
d = json.load(open('$SETTINGS'))
except Exception as e:
msg = '(unavailable: settings.local.json missing or malformed)'
print('=== hooks ==='); print(msg)
print('=== MCP ==='); print(msg)
print('=== MCP FILESYSTEM ==='); print(msg)
print('=== allowedTools count ==='); print(msg)
sys.exit(0)
print('=== hooks ===')
print(json.dumps(d.get('hooks', {}), indent=2))
print('=== MCP ===')
s = d.get('mcpServers', d.get('enabledMcpjsonServers', {}))
names = list(s.keys()) if isinstance(s, dict) else list(s)
n = len(names)
print(f'servers({n}):', ', '.join(names))
est = n * 25 * 200
print(f'est_tokens: ~{est} ({round(est/2000)}% of 200K)')
print('=== MCP FILESYSTEM ===')
if isinstance(s, list):
print('filesystem_present: (array format -- check .mcp.json)')
print('allowedDirectories: (not detectable)')
else:
fs = s.get('filesystem') if isinstance(s, dict) else None; a = []
if isinstance(fs, dict):
a = fs.get('allowedDirectories') or (fs.get('config', {}).get('allowedDirectories') if isinstance(fs.get('config'), dict) else [])
if not a and isinstance(fs.get('args'), list):
args = fs['args']
for i, v in enumerate(args):
if v in ('--allowed-directories', '--allowedDirectories') and i+1 < len(args): a = [args[i+1]]; break
if not a: a = [v for v in args if v.startswith('/') or (v.startswith('~') and len(v) > 1)]
print('filesystem_present:', 'yes' if fs else 'no')
print('allowedDirectories:', a or '(missing or not detected)')
print('=== allowedTools count ===')
print(len(d.get('permissions', {}).get('allow', [])))
" 2>/dev/null || echo "(unavailable)"
echo "[6/10] Nested CLAUDE.md + gitignore..."
echo "=== NESTED CLAUDE.md ===" ; find "$P" -maxdepth 4 -name "CLAUDE.md" -not -path "$P/CLAUDE.md" -not -path "*/.git/*" -not -path "*/node_modules/*" 2>/dev/null || echo "(none)"
echo "=== GITIGNORE ==="
_GITIGNORE_HIT=$(git -C "$P" check-ignore -v .claude/settings.local.json 2>/dev/null || true)
if [ -n "$_GITIGNORE_HIT" ]; then
_GITIGNORE_SOURCE=${_GITIGNORE_HIT%%:*}
case "$_GITIGNORE_SOURCE" in
.gitignore|.claude/.gitignore)
echo "settings.local.json: gitignored"
;;
*)
echo "settings.local.json: ignored only by non-project rule ($_GITIGNORE_SOURCE) -- add a repo-local ignore rule"
;;
esac
else
echo "settings.local.json: NOT gitignored -- risk of committing tokens/credentials"
fi
echo "[7/10] HANDOFF.md + MEMORY.md..."
echo "=== HANDOFF.md ===" ; cat "$P/HANDOFF.md" 2>/dev/null || echo "(none)"
echo "=== MEMORY.md ===" ; cat "$HOME/.claude/projects/-$(pwd | sed 's|[/_]|-|g; s|^-||')/memory/MEMORY.md" 2>/dev/null | head -50 || echo "(none)"
echo "[8/10] Conversation extract (up to 2 recent sessions)..."
echo "=== CONVERSATION FILES ==="
PROJECT_PATH=$(pwd | sed 's|[/_]|-|g; s|^-||')
CONVO_DIR=~/.claude/projects/-${PROJECT_PATH}
ls -lhS "$CONVO_DIR"/*.jsonl 2>/dev/null | head -10
echo "=== CONVERSATION EXTRACT (up to 2 most recent, confidence improves with more files) ==="P=$(pwd)
SETTINGS="$P/.claude/settings.local.json"
echo "[1/10] Tier metrics..."
echo "=== TIER METRICS ==="
echo "project_files: $(git -C "$P" ls-files 2>/dev/null | wc -l || find "$P" -type f -not -path "*/.git/*" -not -path "*/node_modules/*" -not -path "*/dist/*" -not -path "*/build/*" | wc -l)"
echo "contributors: $(git -C "$P" log -n 500 --format='%ae' 2>/dev/null | sort -u | wc -l)"
echo "ci_workflows: $(ls "$P/.github/workflows/"*.yml "$P/.github/workflows/"*.yaml 2>/dev/null | wc -l)"
echo "skills: $(find "$P/.claude/skills" -name "SKILL.md" 2>/dev/null | grep -v '/health/SKILL.md' | wc -l)"
echo "claude_md_lines: $(wc -l < "$P/CLAUDE.md" 2>/dev/null)"
echo "[2/10] CLAUDE.md (global + local)..."
echo "=== CLAUDE.md (global) ===" ; cat ~/.claude/CLAUDE.md 2>/dev/null || echo "(none)"
echo "=== CLAUDE.md (local) ===" ; cat "$P/CLAUDE.md" 2>/dev/null || echo "(none)"
echo "[3/10] Settings, hooks, MCP..."
echo "=== settings.local.json ===" ; cat "$SETTINGS" 2>/dev/null || echo "(none)"
echo "[4/10] Rules + skill descriptions..."
echo "=== rules/ ===" ; find "$P/.claude/rules" -name "*.md" 2>/dev/null | while IFS= read -r f; do echo "--- $f ---"; cat "$f"; done
echo "=== skill descriptions ===" ; { [ -d "$P/.claude/skills" ] && grep -r "^description:" "$P/.claude/skills" 2>/dev/null; grep -r "^description:" ~/.claude/skills 2>/dev/null; } | sort -u
echo "[5/10] Context budget estimate..."
echo "=== STARTUP CONTEXT ESTIMATE ==="
echo "global_claude_words: $(wc -w < ~/.claude/CLAUDE.md 2>/dev/null | tr -d ' ' || echo 0)"
echo "local_claude_words: $(wc -w < "$P/CLAUDE.md" 2>/dev/null | tr -d ' ' || echo 0)"
echo "rules_words: $(find "$P/.claude/rules" -name "*.md" 2>/dev/null | while IFS= read -r f; do cat "$f"; done | wc -w | tr -d ' ')"
echo "skill_desc_words: $({ [ -d "$P/.claude/skills" ] && grep -r "^description:" "$P/.claude/skills" 2>/dev/null; grep -r "^description:" ~/.claude/skills 2>/dev/null; } | wc -w | tr -d ' ')"
python3 -c "
import json, sys
try:
d = json.load(open('$SETTINGS'))
except Exception as e:
msg = '(unavailable: settings.local.json missing or malformed)'
print('=== hooks ==='); print(msg)
print('=== MCP ==='); print(msg)
print('=== MCP FILESYSTEM ==='); print(msg)
print('=== allowedTools count ==='); print(msg)
sys.exit(0)
print('=== hooks ===')
print(json.dumps(d.get('hooks', {}), indent=2))
print('=== MCP ===')
s = d.get('mcpServers', d.get('enabledMcpjsonServers', {}))
names = list(s.keys()) if isinstance(s, dict) else list(s)
n = len(names)
print(f'servers({n}):', ', '.join(names))
est = n * 25 * 200
print(f'est_tokens: ~{est} ({round(est/2000)}% of 200K)')
print('=== MCP FILESYSTEM ===')
if isinstance(s, list):
print('filesystem_present: (array format -- check .mcp.json)')
print('allowedDirectories: (not detectable)')
else:
fs = s.get('filesystem') if isinstance(s, dict) else None; a = []
if isinstance(fs, dict):
a = fs.get('allowedDirectories') or (fs.get('config', {}).get('allowedDirectories') if isinstance(fs.get('config'), dict) else [])
if not a and isinstance(fs.get('args'), list):
args = fs['args']
for i, v in enumerate(args):
if v in ('--allowed-directories', '--allowedDirectories') and i+1 < len(args): a = [args[i+1]]; break
if not a: a = [v for v in args if v.startswith('/') or (v.startswith('~') and len(v) > 1)]
print('filesystem_present:', 'yes' if fs else 'no')
print('allowedDirectories:', a or '(missing or not detected)')
print('=== allowedTools count ===')
print(len(d.get('permissions', {}).get('allow', [])))
" 2>/dev/null || echo "(unavailable)"
echo "[6/10] Nested CLAUDE.md + gitignore..."
echo "=== NESTED CLAUDE.md ===" ; find "$P" -maxdepth 4 -name "CLAUDE.md" -not -path "$P/CLAUDE.md" -not -path "*/.git/*" -not -path "*/node_modules/*" 2>/dev/null || echo "(none)"
echo "=== GITIGNORE ==="
_GITIGNORE_HIT=$(git -C "$P" check-ignore -v .claude/settings.local.json 2>/dev/null || true)
if [ -n "$_GITIGNORE_HIT" ]; then
_GITIGNORE_SOURCE=${_GITIGNORE_HIT%%:*}
case "$_GITIGNORE_SOURCE" in
.gitignore|.claude/.gitignore)
echo "settings.local.json: gitignored"
;;
*)
echo "settings.local.json: ignored only by non-project rule ($_GITIGNORE_SOURCE) -- add a repo-local ignore rule"
;;
esac
else
echo "settings.local.json: NOT gitignored -- risk of committing tokens/credentials"
fi
echo "[7/10] HANDOFF.md + MEMORY.md..."
echo "=== HANDOFF.md ===" ; cat "$P/HANDOFF.md" 2>/dev/null || echo "(none)"
echo "=== MEMORY.md ===" ; cat "$HOME/.claude/projects/-$(pwd | sed 's|[/_]|-|g; s|^-||')/memory/MEMORY.md" 2>/dev/null | head -50 || echo "(none)"
echo "[8/10] Conversation extract (up to 2 recent sessions)..."
echo "=== CONVERSATION FILES ==="
PROJECT_PATH=$(pwd | sed 's|[/_]|-|g; s|^-||')
CONVO_DIR=~/.claude/projects/-${PROJECT_PATH}
ls -lhS "$CONVO_DIR"/*.jsonl 2>/dev/null | head -10
echo "=== CONVERSATION EXTRACT (up to 2 most recent, confidence improves with more files) ==="undefinedundefinedjq(unavailable: jq not installed or parse error)python3(unavailable)settings.local.json(unavailable)sed 's|[/_]|-|g'pwd(none).jsonlnode_modules/dist/build/.next/__pycache__/.turbo/jq(unavailable: jq not installed or parse error)python3(unavailable)settings.local.json(unavailable)pwdsed 's|[/_]|-|g'(none).jsonlnode_modules/dist/build/.next/__pycache__/.turbo/Data collected: {X} CLAUDE.md words · {Y} rules words · {Z} skills found · {N} conversation files sampled
Tier: {SIMPLE/STANDARD/COMPLEX} -- {file_count} files · {contributor_count} contributors · CI: {present/absent}
Step 2/3: {SIMPLE: "Analyzing locally" | STANDARD/COMPLEX: "Launching parallel analysis agents"} · Agent 1: CLAUDE.md (6 checks) · rules (2) · skills (5) · MCP (3) · security (6)
· Agent 2: hooks (5 checks) · allowedTools (2) · behavior (6) · three-layer defense (3)[REDACTED]Data collected: {X} CLAUDE.md words · {Y} rules words · {Z} skills found · {N} conversation files sampled
Tier: {SIMPLE/STANDARD/COMPLEX} -- {file_count} files · {contributor_count} contributors · CI: {present/absent}
Step 2/3: {SIMPLE: "Analyzing locally" | STANDARD/COMPLEX: "Launching parallel analysis agents"} · Agent 1: CLAUDE.md (6 checks) · rules (2) · skills (5) · MCP (3) · security (6)
· Agent 2: hooks (5 checks) · allowedTools (2) · behavior (6) · three-layer defense (3)[REDACTED]agents/agent1-context.mdagents/agent1-context.mdagents/agent2-control.mdagents/agent2-control.mdStep 3/3: Synthesizing reportStep 3/3: Synthesizing report| Check | Detail |
|---|---|
| settings.local.json gitignored | ok |
| No nested CLAUDE.md | ok |
| Skill security scan | no flags |
| 检查项 | 详情 |
|---|---|
| settings.local.json已加入gitignore | 正常 |
| 无嵌套CLAUDE.md | 正常 |
| Skill安全扫描 | 无风险标记 |
Access denied访问被拒绝All relevant checks passed. Nothing to fix.所有相关检查已通过,无需修复。"Should I draft the changes? I can handle each layer separately: global CLAUDE.md / local CLAUDE.md / hooks / skills."
"需要我起草修改方案吗?我可以分别处理每个层级:全局CLAUDE.md / 本地CLAUDE.md / hooks / skills。"