const fs = require('fs'); function parseFrontmatter(content) { if (!content.startsWith('---')) return null; const end = content.indexOf('---', 3); if (end === -1) return null; const fm = content.slice(3, end).trim(); const data = {}; for (const line of fm.split('\n')) { const m = line.match(/^(\w+):\s*(.+)$/); if (m) data[m[1]] = m[2].trim(); } return data; } function stripComments(str) { // Remove single-line comments, but not inside strings return str.replace(/\/\/.*$/gm, ''); } const agents = []; const commands = []; const issues = []; // 1. Parse agent .md files for (const f of fs.readdirSync('.kilo/agents').filter(f => f.endsWith('.md'))) { const content = fs.readFileSync('.kilo/agents/' + f, 'utf8'); const fm = parseFrontmatter(content); if (fm && fm.model) { agents.push({ name: f.replace('.md', ''), model: fm.model, mode: fm.mode || 'subagent', source: '.kilo/agents/' + f, description: fm.description || '' }); } } // 2. Parse command .md files for (const f of fs.readdirSync('.kilo/commands').filter(f => f.endsWith('.md'))) { const content = fs.readFileSync('.kilo/commands/' + f, 'utf8'); const fm = parseFrontmatter(content); if (fm && fm.model) { commands.push({ name: f.replace('.md', ''), model: fm.model, mode: fm.mode || 'command', source: '.kilo/commands/' + f, description: fm.description || '' }); } } // 3. Parse kilo-meta.json const meta = JSON.parse(fs.readFileSync('kilo-meta.json', 'utf8')); for (const a of agents) { const m = meta.agents?.[a.name]; if (m) { a.metaModel = m.model; if (a.model !== m.model) issues.push(`AGENT ${a.name}: .md=${a.model} vs meta=${m.model}`); } } for (const c of commands) { const m = meta.commands?.[c.name]; if (m) { c.metaModel = m.model; if (c.model !== m.model) issues.push(`CMD ${c.name}: .md=${c.model} vs meta=${m.model}`); } } // 4. Parse .kilo/kilo.jsonc const dotKiloRaw = stripComments(fs.readFileSync('.kilo/kilo.jsonc', 'utf8')); const dotKilo = JSON.parse(dotKiloRaw); for (const [name, cfg] of Object.entries(dotKilo.agent || {})) { if (!cfg.model) continue; const agent = agents.find(a => a.name === name); if (agent) { agent.kiloModel = cfg.model; if (agent.model !== cfg.model) issues.push(`AGENT ${name}: .md=${agent.model} vs .kilo/kilo.jsonc=${cfg.model}`); } } // 5. Parse root kilo.jsonc const rootKiloRaw = stripComments(fs.readFileSync('kilo.jsonc', 'utf8')); const rootKilo = JSON.parse(rootKiloRaw); for (const [name, cfg] of Object.entries(rootKilo.agent || {})) { if (!cfg.model) continue; const cmd = commands.find(c => c.name === name); if (cmd) { cmd.rootModel = cfg.model; if (cmd.model !== cfg.model) issues.push(`CMD ${name}: .md=${cmd.model} vs kilo.jsonc=${cfg.model}`); } } // 6. Check non-ollama const nonOllama = []; for (const a of agents) if (!a.model.startsWith('ollama-cloud/')) nonOllama.push({type:'agent', name:a.name, model:a.model}); for (const c of commands) if (!c.model.startsWith('ollama-cloud/')) nonOllama.push({type:'command', name:c.name, model:c.model}); // 7. Summary by model const modelStats = {}; for (const a of agents) modelStats[a.model] = (modelStats[a.model] || 0) + 1; for (const c of commands) modelStats[c.model] = (modelStats[c.model] || 0) + 1; const state = { generated: new Date().toISOString(), totalAgents: agents.length, totalCommands: commands.length, allOllama: nonOllama.length === 0, modelDistribution: modelStats, agents: agents.sort((a,b) => a.name.localeCompare(b.name)), commands: commands.sort((a,b) => a.name.localeCompare(b.name)), issues: issues, nonOllama: nonOllama }; fs.writeFileSync('agent-evolution/data/real-state.json', JSON.stringify(state, null, 2) + '\n'); // Console report console.log('=== REAL SYSTEM STATE ==='); console.log('Generated:', state.generated); console.log('Agents:', state.totalAgents); console.log('Commands:', state.totalCommands); console.log('All ollama-cloud/:', state.allOllama ? 'YES' : 'NO (' + nonOllama.length + ' exceptions)'); console.log('\n=== MODEL DISTRIBUTION ==='); for (const [m, c] of Object.entries(modelStats).sort((a,b) => b[1]-a[1])) { console.log(` ${m}: ${c}`); } if (issues.length > 0) { console.log('\n=== ISSUES ==='); issues.forEach(i => console.log(' ⚠️', i)); } if (nonOllama.length > 0) { console.log('\n=== NON-OLLOMA ==='); nonOllama.forEach(n => console.log(' ❌', n.type, n.name, n.model)); } console.log('\n✅ State written to agent-evolution/data/real-state.json');