diff --git a/.agent/rules/documents.md b/.agent/rules/documents.md index 62571f4..36b75d7 100644 --- a/.agent/rules/documents.md +++ b/.agent/rules/documents.md @@ -5,3 +5,5 @@ --- 1. 詳細な設計がdocumentsにあるので、改造を計画する際に参照すること。 +2. ソースコードの編集が完了したら、`tools/count_loc.cjs` と `tools/nesting_depth.cjs` を使用して計測を行うこと。 +3. 計測の結果、ソースコードが600行以上、またはネストが7階層以上のコードについては、リファクタリングを検討すること。 diff --git a/tools/count_loc.cjs b/tools/count_loc.cjs new file mode 100644 index 0000000..987c09e --- /dev/null +++ b/tools/count_loc.cjs @@ -0,0 +1,44 @@ +const fs = require('fs'); +const path = require('path'); + +function countLines(filePath) { + try { + const content = fs.readFileSync(filePath, 'utf8'); + return content.split('\n').length; + } catch (e) { + return 0; + } +} + +function walk(dir, results = []) { + const list = fs.readdirSync(dir); + list.forEach(file => { + const fullPath = path.join(dir, file); + const stat = fs.statSync(fullPath); + if (stat.isDirectory()) { + if (!['node_modules', 'target', 'dist', '.git', '.gemini', '.brain'].includes(file) && !file.startsWith('.')) { + walk(fullPath, results); + } + } else { + const ext = path.extname(fullPath); + if (['.rs', '.js', '.ts', '.html', '.css'].includes(ext)) { + results.push({ + path: path.relative(process.cwd(), fullPath), + loc: countLines(fullPath) + }); + } + } + }); + return results; +} + +const srcDir = process.cwd(); +const files = walk(srcDir); +files.sort((a, b) => b.loc - a.loc); + +console.log('--- Source Code Line Counts ---'); +files.forEach(f => { + if (f.loc === 0) return; + const status = f.loc >= 600 ? '[REFACTOR REQUIRED]' : ' '; + console.log(`${f.path.padEnd(60)} : ${f.loc.toString().padStart(5)} lines ${status}`); +}); diff --git a/tools/nesting_depth.cjs b/tools/nesting_depth.cjs new file mode 100644 index 0000000..3122026 --- /dev/null +++ b/tools/nesting_depth.cjs @@ -0,0 +1,55 @@ +const fs = require('fs'); +const path = require('path'); + +function getMaxNesting(filePath) { + try { + const content = fs.readFileSync(filePath, 'utf8'); + let maxDepth = 0; + let currentDepth = 0; + + for (let i = 0; i < content.length; i++) { + const char = content[i]; + if (char === '{') { + currentDepth++; + if (currentDepth > maxDepth) maxDepth = currentDepth; + } else if (char === '}') { + currentDepth--; + } + } + return maxDepth; + } catch (e) { + return 0; + } +} + +function walk(dir, results = []) { + const list = fs.readdirSync(dir); + list.forEach(file => { + const fullPath = path.join(dir, file); + const stat = fs.statSync(fullPath); + if (stat.isDirectory()) { + if (!['node_modules', 'target', 'dist', '.git', '.gemini', '.brain'].includes(file) && !file.startsWith('.')) { + walk(fullPath, results); + } + } else { + const ext = path.extname(fullPath); + if (['.rs', '.js', '.ts', '.html', '.css'].includes(ext)) { + results.push({ + path: path.relative(process.cwd(), fullPath), + depth: getMaxNesting(fullPath) + }); + } + } + }); + return results; +} + +const srcDir = process.cwd(); +const files = walk(srcDir); +files.sort((a, b) => b.depth - a.depth); + +console.log('--- Source Code Nesting Depth ---'); +files.forEach(f => { + const status = f.depth >= 7 ? '[REFACTOR REQUIRED]' : ' '; + console.log(`${f.path.padEnd(60)} : ${f.depth.toString().padStart(5)} levels ${status}`); +});