11// CATEGORY 5: token_audit — Token Efficiency
22import { z } from "zod" ;
33import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js" ;
4- import { run } from "../lib/git.js" ;
4+ import { run , shell } from "../lib/git.js" ;
55import { readIfExists , findWorkspaceDocs , PROJECT_DIR } from "../lib/files.js" ;
66import { loadState , saveState , now , STATE_DIR } from "../lib/state.js" ;
77import { readFileSync , existsSync , statSync } from "fs" ;
@@ -39,8 +39,8 @@ export function registerTokenAudit(server: McpServer): void {
3939 let wasteScore = 0 ;
4040
4141 // 1. Git diff size & dirty file count
42- const diffStat = run ( "git diff --stat --no-color 2>/dev/null" ) ;
43- const dirtyFiles = run ( "git diff --name-only 2>/dev/null" ) ;
42+ const diffStat = run ( [ " diff" , " --stat" , " --no-color" ] ) ;
43+ const dirtyFiles = run ( [ " diff" , " --name-only" ] ) ;
4444 const dirtyList = dirtyFiles . split ( "\n" ) . filter ( Boolean ) ;
4545 const dirtyCount = dirtyList . length ;
4646
@@ -63,7 +63,7 @@ export function registerTokenAudit(server: McpServer): void {
6363
6464 for ( const f of dirtyList . slice ( 0 , 30 ) ) {
6565 // Use shell-safe quoting instead of interpolation
66- const wc = run ( `wc -l < '${ shellEscape ( f ) } ' 2>/dev/null` ) ;
66+ const wc = shell ( `wc -l < '${ shellEscape ( f ) } ' 2>/dev/null` ) ;
6767 const lines = parseInt ( wc ) || 0 ;
6868 estimatedContextTokens += lines * AVG_LINE_BYTES * AVG_TOKENS_PER_BYTE ;
6969 if ( lines > 500 ) {
@@ -80,7 +80,7 @@ export function registerTokenAudit(server: McpServer): void {
8080 // 3. CLAUDE.md bloat check
8181 const claudeMd = readIfExists ( "CLAUDE.md" , 1 ) ;
8282 if ( claudeMd !== null ) {
83- const stat = run ( `wc -c < '${ shellEscape ( "CLAUDE.md" ) } ' 2>/dev/null` ) ;
83+ const stat = shell ( `wc -c < '${ shellEscape ( "CLAUDE.md" ) } ' 2>/dev/null` ) ;
8484 const bytes = parseInt ( stat ) || 0 ;
8585 if ( bytes > 5120 ) {
8686 patterns . push ( `CLAUDE.md is ${ ( bytes / 1024 ) . toFixed ( 1 ) } KB — injected every session, burns tokens on paste` ) ;
@@ -139,7 +139,7 @@ export function registerTokenAudit(server: McpServer): void {
139139 // Read with size cap: take the tail if too large
140140 const raw = stat . size <= MAX_TOOL_LOG_BYTES
141141 ? readFileSync ( toolLogPath , "utf-8" )
142- : run ( `tail -c ${ MAX_TOOL_LOG_BYTES } '${ shellEscape ( toolLogPath ) } '` ) ;
142+ : shell ( `tail -c ${ MAX_TOOL_LOG_BYTES } '${ shellEscape ( toolLogPath ) } '` ) ;
143143
144144 const lines = raw . trim ( ) . split ( "\n" ) . filter ( Boolean ) ;
145145 totalToolCalls = lines . length ;
0 commit comments