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
« prev ^ index » next coverage.py v7.10.1, created at 2026-01-10 00:20 -0500
1"""
2Project Context and System Health Tools.
4Provides the agent with environmental awareness (Git, Rules, Todos)
5and ensures all required dependencies are installed and authenticated.
6"""
8import os
9import shutil
10import subprocess
11import sys
12from pathlib import Path
14from ..auth.token_store import TokenStore
17async def get_project_context(project_path: str | None = None) -> str:
18 """
19 Summarize project environment: Git status, local rules, and pending todos.
21 Args:
22 project_path: Path to the project root
24 Returns:
25 Formatted summary of the project context.
26 """
27 root = Path(project_path) if project_path else Path.cwd()
28 context = []
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()
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")
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/_")
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()
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._")
91 return "\n".join(context)
94async def get_system_health() -> str:
95 """
96 Comprehensive check of system dependencies and authentication status.
98 Returns:
99 Checklist of system health.
100 """
101 health = ["## 🏥 Stravinsky System Health Report\n"]
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 }
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'}")
120 # 2. Authentication Status
121 health.append("\n### 🔑 Provider Authentication")
122 token_store = TokenStore()
123 providers = ["gemini", "openai"]
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'}")
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')}`")
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]`.")
140 return "\n".join(health)