feat: enhance profile path resolution and add example profiles for better project adaptability

This commit is contained in:
2026-05-21 10:21:52 -06:00
parent fb8a6ba2d9
commit f0d3cd4ce9
12 changed files with 234 additions and 34 deletions

View File

@@ -27,7 +27,9 @@ PROTOCOL_VERSION = "2025-06-18"
SERVER_NAME = "aiw-context-mcp"
SERVER_VERSION = "0.1.0"
LOCAL_ENV = ROOT / "scripts" / "mattermost-proxy" / ".env"
INDEX_ROOT = ROOT / ".aiw" / "indexes"
AIW_SCRIPT_DIR = ROOT / "scripts" / "aiw"
sys.path.insert(0, str(AIW_SCRIPT_DIR))
import profile as aiw_profile # noqa: E402
def load_local_env(path: Path = LOCAL_ENV) -> None:
@@ -47,22 +49,20 @@ def load_local_env(path: Path = LOCAL_ENV) -> None:
def profile_dir(profile: str) -> Path:
if profile == "fidelity":
return ROOT
candidate = ROOT / "profiles" / profile
return candidate if candidate.exists() else ROOT
def knowledge_dir(profile: str) -> Path:
base = profile_dir(profile)
candidate = base / "project-knowledge"
return candidate if candidate.exists() else ROOT / "project-knowledge"
return aiw_profile.knowledge_dir(profile, root=ROOT)
def inbox_dir(profile: str) -> Path:
base = profile_dir(profile)
candidate = base / "ai" / "inbox"
return candidate if candidate.exists() else ROOT / "ai" / "inbox"
return aiw_profile.inbox_dir(profile, root=ROOT)
def rel(path: Path) -> str:
return aiw_profile.relative_to_root(path, root=ROOT)
def mattermost_mirror_dir(profile: str) -> Path:
@@ -257,7 +257,7 @@ def project_current_context(args: dict[str, Any]) -> dict[str, Any]:
result = []
for path in files:
if path.is_file():
result.append({"path": str(path.relative_to(ROOT)), "text": path.read_text(encoding="utf-8", errors="replace")})
result.append({"path": rel(path), "text": path.read_text(encoding="utf-8", errors="replace")})
return tool_result({"profile": profile, "canonical": True, "files": result})
@@ -270,8 +270,8 @@ def project_search_memory(args: dict[str, Any]) -> dict[str, Any]:
base = knowledge_dir(profile)
matches: list[dict[str, Any]] = []
for path in sorted(base.rglob("*.md")):
rel = path.relative_to(base)
if str(rel).startswith("09-templates/"):
relative_to_base = path.relative_to(base)
if str(relative_to_base).startswith("09-templates/"):
continue
text = path.read_text(encoding="utf-8", errors="replace")
lowered = text.lower()
@@ -280,18 +280,18 @@ def project_search_memory(args: dict[str, Any]) -> dict[str, Any]:
continue
start = max(0, index - 220)
end = min(len(text), index + len(query) + 220)
matches.append({"path": str(path.relative_to(ROOT)), "snippet": text[start:end].strip()})
matches.append({"path": rel(path), "snippet": text[start:end].strip()})
if len(matches) >= limit:
break
return tool_result({"profile": profile, "canonical": True, "query": query, "matches": matches})
def index_path(profile: str) -> Path:
return INDEX_ROOT / profile / "project-knowledge.jsonl"
return aiw_profile.index_dir(profile, root=ROOT) / "project-knowledge.jsonl"
def index_manifest_path(profile: str) -> Path:
return INDEX_ROOT / profile / "manifest.json"
return aiw_profile.index_dir(profile, root=ROOT) / "manifest.json"
def search_tokens(text: str) -> set[str]:

View File

@@ -175,7 +175,7 @@ class ContextMCPTests(unittest.TestCase):
}) + "\n", encoding="utf-8")
manifest.write_text(json.dumps({"chunk_count": 1}), encoding="utf-8")
with patch.object(server, "ROOT", root), patch.object(server, "INDEX_ROOT", root / ".aiw" / "indexes"):
with patch.object(server, "ROOT", root):
result = server.memory_hybrid_search({"profile": "fidelity", "query": "dismissal lifecycle"})["structuredContent"]
self.assertTrue(result["index_available"])
@@ -189,13 +189,31 @@ class ContextMCPTests(unittest.TestCase):
real.parent.mkdir(parents=True)
real.write_text("Important XFlow context", encoding="utf-8")
with patch.object(server, "ROOT", root), patch.object(server, "INDEX_ROOT", root / ".aiw" / "indexes"):
with patch.object(server, "ROOT", root):
result = server.memory_hybrid_search({"profile": "fidelity", "query": "XFlow"})["structuredContent"]
self.assertFalse(result["index_available"])
self.assertEqual(result["source"], "live-project-knowledge-fallback")
self.assertEqual(len(result["matches"]), 1)
def test_project_context_uses_workspace_json_paths(self) -> None:
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
config = root / "profiles" / "demo" / "workspace.json"
current = root / "workspaces" / "demo" / "project-knowledge" / "01-current" / "current-work.md"
work_items = root / "workspaces" / "demo" / "project-knowledge" / "01-current" / "work-items.md"
config.parent.mkdir(parents=True)
current.parent.mkdir(parents=True)
config.write_text(json.dumps({"knowledge_dir": "workspaces/demo/project-knowledge"}), encoding="utf-8")
current.write_text("# Current\nDemo current work", encoding="utf-8")
work_items.write_text("# Work Items", encoding="utf-8")
with patch.object(server, "ROOT", root):
result = server.project_current_context({"profile": "demo"})["structuredContent"]
self.assertEqual(result["files"][0]["path"], "workspaces/demo/project-knowledge/01-current/current-work.md")
self.assertIn("Demo current work", result["files"][0]["text"])
def test_previous_workday_skips_weekend(self) -> None:
monday = date(2026, 5, 18)