@@ -473,6 +473,23 @@ def _scan_jscpd_report(project: Path) -> list[Suggestion]:
473473 ]
474474
475475
476+ _TOON_GOD_RE = re .compile (
477+ r"^\s*🔴\s+GOD\s+(?P<path>\S+)\s*=\s*(?P<loc>\d+)L,\s*(?P<classes>\d+)\s+classes?,\s*(?P<methods>\d+)m" ,
478+ re .MULTILINE ,
479+ )
480+ _TOON_CC_RE = re .compile (
481+ r"^\s*🟡\s+CC\s+(?P<func>\S+)\s+CC=(?P<cc>\d+)\s+\(limit:\s*(?P<limit>\d+)\)" ,
482+ re .MULTILINE ,
483+ )
484+ _TOON_DUP_RE = re .compile (
485+ r"^\s*🔴\s+DUP\s+(?P<count>\d+)\s+classes?\s+duplicated" ,
486+ re .MULTILINE ,
487+ )
488+ _TOON_REFACTOR_ITEM_RE = re .compile (
489+ r"^\s*(?P<num>\d+)\.\s+(?P<desc>.+?)\s*\((?P<note>[^)]+)\)\s*$"
490+ )
491+
492+
476493def _scan_code2llm_analysis (project : Path ) -> list [Suggestion ]:
477494 candidates = (
478495 project / "project" / "analysis.toon.yaml" ,
@@ -483,28 +500,105 @@ def _scan_code2llm_analysis(project: Path) -> list[Suggestion]:
483500 if path is None :
484501 return []
485502 try :
486- lines = path .read_text (encoding = "utf-8" , errors = "ignore" ). splitlines ( )
503+ text = path .read_text (encoding = "utf-8" , errors = "ignore" )
487504 except OSError :
488505 return []
489- god = sum (1 for ln in lines if "🔴 GOD" in ln )
490- critical = sum (1 for ln in lines if "🔴" in ln )
491- if god < 1 and critical < 8 :
492- return []
493506 rel = str (path .relative_to (project ))
494- pr = "high" if god >= 3 else "normal"
495- return [
496- Suggestion (
497- signal = "code2llm_analysis" ,
498- title = "Execute code2llm REFACTOR plan (god modules / critical)" ,
499- description = (
500- f"`{ rel } ` lists ~{ god } god-module rows and { critical } critical (🔴) markers. "
501- "Work through the REFACTOR section; re-run `code2llm ./ -f toon` to refresh."
502- ),
503- priority = pr ,
504- labels = ("code2llm" , "refactor" , "scan" ),
505- files = (rel ,),
507+
508+ suggestions : list [Suggestion ] = []
509+
510+ # --- HEALTH: DUP ---
511+ dup_match = _TOON_DUP_RE .search (text )
512+ if dup_match :
513+ count = int (dup_match .group ("count" ))
514+ suggestions .append (
515+ Suggestion (
516+ signal = "code2llm_dup" ,
517+ title = f"Remove { count } duplicated classes (code2llm analysis)" ,
518+ description = (
519+ f"`{ rel } ` reports **{ count } ** duplicated classes. "
520+ "Extract shared helpers/modules; re-run `code2llm ./ -f toon` to refresh."
521+ ),
522+ priority = "high" ,
523+ labels = ("code2llm" , "duplication" , "refactor" , "scan" ),
524+ files = (rel ,),
525+ )
506526 )
507- ]
527+
528+ # --- HEALTH: GOD modules ---
529+ for m in _TOON_GOD_RE .finditer (text ):
530+ file_path = m .group ("path" ).strip ()
531+ loc = m .group ("loc" )
532+ classes = m .group ("classes" )
533+ methods = m .group ("methods" )
534+ suggestions .append (
535+ Suggestion (
536+ signal = "code2llm_god" ,
537+ title = f"Split god module: { file_path } " ,
538+ description = (
539+ f"`{ rel } ` flags `{ file_path } ` as a god module "
540+ f"({ loc } lines, { classes } classes, { methods } methods). "
541+ "Split into focused submodules by responsibility."
542+ ),
543+ priority = "high" ,
544+ labels = ("code2llm" , "god-module" , "refactor" , "scan" ),
545+ files = (file_path , rel ),
546+ )
547+ )
548+
549+ # --- HEALTH: high-CC methods ---
550+ cc_seen : set [str ] = set ()
551+ for m in _TOON_CC_RE .finditer (text ):
552+ func = m .group ("func" ).strip ()
553+ cc = int (m .group ("cc" ))
554+ limit = int (m .group ("limit" ))
555+ if func in cc_seen :
556+ continue
557+ cc_seen .add (func )
558+ suggestions .append (
559+ Suggestion (
560+ signal = "code2llm_cc" ,
561+ title = f"Reduce cyclomatic complexity: { func } (CC={ cc } , limit={ limit } )" ,
562+ description = (
563+ f"`{ rel } ` reports `{ func } ` with CC={ cc } (limit={ limit } ). "
564+ "Extract sub-functions, simplify conditionals, or split into strategy pattern."
565+ ),
566+ priority = "normal" ,
567+ labels = ("code2llm" , "complexity" , "refactor" , "scan" ),
568+ files = (rel ,),
569+ )
570+ )
571+
572+ # --- REFACTOR plan items ---
573+ in_refactor = False
574+ for line in text .splitlines ():
575+ if line .startswith ("REFACTOR" ):
576+ in_refactor = True
577+ continue
578+ if in_refactor and line .startswith (("HEALTH" , "PIPELINES" , "LAYERS" )):
579+ break
580+ if not in_refactor :
581+ continue
582+ rm = _TOON_REFACTOR_ITEM_RE .match (line )
583+ if not rm :
584+ continue
585+ desc = rm .group ("desc" ).strip ()
586+ note = rm .group ("note" ).strip ()
587+ suggestions .append (
588+ Suggestion (
589+ signal = "code2llm_refactor" ,
590+ title = f"code2llm refactor: { desc } " ,
591+ description = (
592+ f"REFACTOR item from `{ rel } `: **{ desc } ** ({ note } ). "
593+ "Execute this refactor step; re-run `code2llm ./ -f toon` to verify."
594+ ),
595+ priority = "normal" ,
596+ labels = ("code2llm" , "refactor" , "scan" ),
597+ files = (rel ,),
598+ )
599+ )
600+
601+ return suggestions
508602
509603
510604def _scan_testql_export (project : Path ) -> list [Suggestion ]:
0 commit comments