Coverage for mcp_bridge/tools/project_context.py: 0%

69 statements  

« prev     ^ index     » next       coverage.py v7.10.1, created at 2026-01-10 00:20 -0500

1""" 

2Project Context and System Health Tools. 

3 

4Provides the agent with environmental awareness (Git, Rules, Todos) 

5and ensures all required dependencies are installed and authenticated. 

6""" 

7 

8import os 

9import shutil 

10import subprocess 

11import sys 

12from pathlib import Path 

13 

14from ..auth.token_store import TokenStore 

15 

16 

17async def get_project_context(project_path: str | None = None) -> str: 

18 """ 

19 Summarize project environment: Git status, local rules, and pending todos. 

20  

21 Args: 

22 project_path: Path to the project root 

23  

24 Returns: 

25 Formatted summary of the project context. 

26 """ 

27 root = Path(project_path) if project_path else Path.cwd() 

28 context = [] 

29 

30 # 1. Git Information 

31 context.append("### 🌿 Git Context") 

32 try: 

33 branch = subprocess.check_output( 

34 ["git", "rev-parse", "--abbrev-ref", "HEAD"], 

35 stderr=subprocess.DEVNULL, text=True 

36 ).strip() 

37 status = subprocess.check_output( 

38 ["git", "status", "--short"], 

39 stderr=subprocess.DEVNULL, text=True 

40 ).strip() 

41 

42 context.append(f"**Branch**: `{branch}`") 

43 if status: 

44 files_changed = len(status.split("\n")) 

45 context.append(f"**Status**: {files_changed} files modified (staged/unstaged)") 

46 else: 

47 context.append("**Status**: Clean") 

48 except Exception: 

49 context.append("**Status**: Not a git repository") 

50 

51 # 2. Local Rules (.claude/rules/) 

52 rules_dir = root / ".claude" / "rules" 

53 if rules_dir.exists(): 

54 context.append("\n### 📜 Local Project Rules") 

55 rule_files = list(rules_dir.glob("*.md")) 

56 if rule_files: 

57 for rf in rule_files: 

58 try: 

59 content = rf.read_text().strip() 

60 context.append(f"#### {rf.name}\n{content}") 

61 except Exception: 

62 continue 

63 else: 

64 context.append("_No specific rules found in .claude/rules/_") 

65 

66 # 3. Pending Todos 

67 context.append("\n### 📝 Pending Todos (Top 20)") 

68 try: 

69 # Search for [ ] in code files, excluding common noise directories 

70 todo_cmd = [ 

71 "rg", "--line-number", "--no-heading", "--column", 

72 "--glob", "!.git/*", "--glob", "!node_modules/*", 

73 "--glob", "!.venv/*", 

74 r"\[ \]", str(root) 

75 ] 

76 todo_output = subprocess.check_output( 

77 todo_cmd, stderr=subprocess.DEVNULL, text=True 

78 ).strip() 

79 

80 if todo_output: 

81 lines = todo_output.split("\n")[:20] 

82 for line in lines: 

83 context.append(f"- {line}") 

84 if len(todo_output.split("\n")) > 20: 

85 context.append("_(... and more)_") 

86 else: 

87 context.append("_No pending [ ] markers found._") 

88 except Exception: 

89 context.append("_Ripgrep not found or error searching for todos._") 

90 

91 return "\n".join(context) 

92 

93 

94async def get_system_health() -> str: 

95 """ 

96 Comprehensive check of system dependencies and authentication status. 

97  

98 Returns: 

99 Checklist of system health. 

100 """ 

101 health = ["## 🏥 Stravinsky System Health Report\n"] 

102 

103 # 1. CLI Dependencies 

104 health.append("### 🛠️ CLI Dependencies") 

105 dependencies = { 

106 "rg": "ripgrep", 

107 "fd": "fd-find", 

108 "sg": "ast-grep", 

109 "gh": "GitHub CLI", 

110 "ruff": "Python Linter", 

111 "tsc": "TypeScript Compiler", 

112 "git": "Git" 

113 } 

114 

115 for cmd, name in dependencies.items(): 

116 path = shutil.which(cmd) 

117 status = "✅" if path else "❌" 

118 health.append(f"- {status} **{name}** (`{cmd}`): {'Installed' if path else 'MISSING'}") 

119 

120 # 2. Authentication Status 

121 health.append("\n### 🔑 Provider Authentication") 

122 token_store = TokenStore() 

123 providers = ["gemini", "openai"] 

124 

125 for p in providers: 

126 has_token = token_store.has_valid_token(p) 

127 status = "✅" if has_token else "❌" 

128 health.append(f"- {status} **{p.capitalize()}**: {'Authenticated' if has_token else 'NOT LOGGED IN'}") 

129 

130 # 3. Environment 

131 health.append("\n### 🐍 Environment") 

132 health.append(f"- **Python**: `{sys.version.split()[0]}`") 

133 health.append(f"- **Virtualenv**: `{os.environ.get('VIRTUAL_ENV', 'None')}`") 

134 

135 health.append("\n---") 

136 health.append("**Resolution Guide**:") 

137 health.append("- For missing CLI tools: Use `brew install` or `npm install -g` as appropriate.") 

138 health.append("- For Auth: Run `python -m mcp_bridge.auth.cli login [provider]`.") 

139 

140 return "\n".join(health)