feat(v2): enhanced config display with separate counters

- Split config counting: CLAUDE.md, rules, MCPs, hooks
- Display distinct icons for each config type (📄 📜 🔌 🪝)
- Read hooks count from settings.json
- Remove ralph-loop local config file

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Jarrod Watts
2026-01-03 17:38:26 +11:00
parent 9672eea781
commit c8f46cfa3f
5 changed files with 69 additions and 99 deletions

View File

@@ -2,20 +2,48 @@ import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';
export async function countRules(cwd?: string): Promise<number> {
let count = 0;
export interface ConfigCounts {
claudeMdCount: number;
rulesCount: number;
mcpCount: number;
hooksCount: number;
}
export async function countConfigs(cwd?: string): Promise<ConfigCounts> {
let claudeMdCount = 0;
let rulesCount = 0;
let mcpCount = 0;
let hooksCount = 0;
const claudeDir = path.join(os.homedir(), '.claude');
const globalRulesDir = path.join(claudeDir, 'rules');
const settingsPath = path.join(claudeDir, 'settings.json');
if (fs.existsSync(path.join(claudeDir, 'CLAUDE.md'))) {
count++;
claudeMdCount++;
}
if (fs.existsSync(globalRulesDir)) {
try {
const files = fs.readdirSync(globalRulesDir);
count += files.filter((f) => f.endsWith('.md')).length;
rulesCount += files.filter((f) => f.endsWith('.md')).length;
} catch {
// Ignore errors
}
}
if (fs.existsSync(settingsPath)) {
try {
const content = fs.readFileSync(settingsPath, 'utf8');
const settings = JSON.parse(content);
if (settings.mcpServers && typeof settings.mcpServers === 'object') {
mcpCount += Object.keys(settings.mcpServers).length;
}
if (settings.hooks && typeof settings.hooks === 'object') {
hooksCount += Object.keys(settings.hooks).length;
}
} catch {
// Ignore errors
}
@@ -23,38 +51,38 @@ export async function countRules(cwd?: string): Promise<number> {
if (cwd) {
if (fs.existsSync(path.join(cwd, 'CLAUDE.md'))) {
count++;
claudeMdCount++;
}
const projectRulesDir = path.join(cwd, '.claude', 'rules');
if (fs.existsSync(projectRulesDir)) {
try {
const files = fs.readdirSync(projectRulesDir);
count += files.filter((f) => f.endsWith('.md')).length;
rulesCount += files.filter((f) => f.endsWith('.md')).length;
} catch {
// Ignore errors
}
}
const projectSettingsPath = path.join(cwd, '.claude', 'settings.json');
if (fs.existsSync(projectSettingsPath)) {
try {
const content = fs.readFileSync(projectSettingsPath, 'utf8');
const settings = JSON.parse(content);
if (settings.mcpServers && typeof settings.mcpServers === 'object') {
mcpCount += Object.keys(settings.mcpServers).length;
}
if (settings.hooks && typeof settings.hooks === 'object') {
hooksCount += Object.keys(settings.hooks).length;
}
} catch {
// Ignore errors
}
}
}
return count;
return { claudeMdCount, rulesCount, mcpCount, hooksCount };
}
export async function countMcpServers(): Promise<number> {
let count = 0;
const globalMcpPath = path.join(os.homedir(), '.claude', '.mcp.json');
if (fs.existsSync(globalMcpPath)) {
try {
const content = fs.readFileSync(globalMcpPath, 'utf8');
const config = JSON.parse(content);
if (config.mcpServers && typeof config.mcpServers === 'object') {
count += Object.keys(config.mcpServers).length;
}
} catch {
// Ignore errors
}
}
return count;
}