1"""Compaction analysis utilities for context optimization.

2

3 This module provides helper functions for analyzing when context compaction

4 would be beneficial based on project characteristics, git activity, and

5 development patterns.

6"""

7

8 from __future__ import annotations

9

10 import subprocess # nosec B404

11 from contextlib import suppress

12 from typing import TYPE_CHECKING

13

14 if TYPE_CHECKING:

15 from pathlib import Path

16

17

18 def get_default_compaction_reason() -> str:

19 """Get the default reason when no strong indicators are found."""

20 return "Context appears manageable - compaction not immediately needed"

21

22

23 def get_fallback_compaction_reason() -> str:

24 """Get fallback reason when evaluation fails."""

25 return "Unable to assess context complexity - compaction may be beneficial as a precaution"

26

27

28 def count_significant_files(current_dir: Path) -> int:

29 """Count significant files in project as a complexity indicator."""

30 file_count = 0

31 with suppress(OSError, PermissionError, FileNotFoundError, ValueError):

32 for file_path in current_dir.rglob("*"):

33 if (

34 file_path.is_file()

35 and not any(part.startswith(".") for part in file_path.parts)

36 and file_path.suffix

37 in {

38 ".py",

39 ".js",

40 ".ts",

41 ".jsx",

42 ".tsx",

43 ".go",

44 ".rs",

45 ".java",

46 ".cpp",

47 ".c",

48 ".h",

49 }

50 ):

51 file_count += 1

52 if file_count > 50: # Stop counting after threshold

53 break

54 return file_count

55

56

57 def check_git_activity(current_dir: Path) -> tuple[int, int] | None:

58 """Check for active development via git and return (recent_commits, modified_files)."""

59 git_dir = current_dir / ".git"

60 if not git_dir.exists():

61 return None

62

63 try:

64 # Check number of recent commits as activity indicator

65 result = subprocess.run(

66 ["git", "log", "--oneline", "-20", "--since='24 hours ago'"],

67 check=False,

68 capture_output=True,

69 text=True,

70 cwd=current_dir,

71 timeout=5,

72 )

73 if result.returncode == 0: 73 ↛ 78 line 73 didn't jump to line 78 because the condition on line 73 was always true

74 recent_commits = len(

75 [line for line in result.stdout.strip().split("\n") if line.strip()],

76 )

77 else:

78 recent_commits = 0

79

80 # Check for large number of modified files

81 status_result = subprocess.run(

82 ["git", "status", "--porcelain"],

83 check=False,

84 capture_output=True,

85 text=True,

86 cwd=current_dir,

87 timeout=5,

88 )

89 if status_result.returncode == 0: 89 ↛ 98 line 89 didn't jump to line 98 because the condition on line 89 was always true

90 modified_files = len(

91 [

92 line

93 for line in status_result.stdout.strip().split("\n")

94 if line.strip()

95 ],

96 )

97 else:

98 modified_files = 0

99

100 return recent_commits, modified_files

101

102 except (subprocess.TimeoutExpired, Exception):

103 return None

104

105

106 def evaluate_large_project_heuristic(file_count: int) -> tuple[bool, str]:

107 """Evaluate if the project is large enough to benefit from compaction."""

108 if file_count > 50:

109 return (

110 True,

111 "Large codebase with 50+ source files detected - context compaction recommended",

112 )

113 return False, ""

114

115

116 def evaluate_git_activity_heuristic(

117 git_activity: tuple[int, int] | None,

118) -> tuple[bool, str]:

119 """Evaluate if git activity suggests compaction would be beneficial."""

120 if git_activity: 120 ↛ 135 line 120 didn't jump to line 135 because the condition on line 120 was always true

121 recent_commits, modified_files = git_activity

122

123 if recent_commits >= 3: 123 ↛ 129 line 123 didn't jump to line 129 because the condition on line 123 was always true

124 return (

125 True,

126 f"High development activity ({recent_commits} commits in 24h) - compaction recommended",

127 )

128

129 if modified_files >= 10:

130 return (

131 True,

132 f"Many modified files ({modified_files}) detected - context optimization beneficial",

133 )

134

135 return False, ""

136

137

138 def evaluate_python_project_heuristic(current_dir: Path) -> tuple[bool, str]:

139 """Evaluate if this is a Python project that might benefit from compaction."""

140 if (current_dir / "tests").exists() and (current_dir / "pyproject.toml").exists():

141 return (

142 True,

143 "Python project with tests detected - compaction may improve focus",

144 )

145 return False, ""