Skip to content

Commit 02e9db9

Browse files
committed
feat: capture Rust→server HTTP edges + fix obsidian regen and grammar guard
- enrich.py: add Rust `format!("{}/api/...")` regex so reqwest calls in Tauri commands resolve to backend routes; widen the API-scan node-type filter to include `route`/`service` so cross-language IPC→HTTP chains appear in the graph (e.g. `src-tauri → server` calls_api edges). - obsidian.py: clear stale per-service `*.md` notes at the start of vault generation so step 5's collision branch no longer drops freshly built notes, which had been silently preserving outdated `## Connections`. - base.py: `is_grammar_allowed` fallback flips from allow→deny when the grammar can't be identified, preventing unrelated query files (e.g. Python parsed against `svelte.scm`) from triggering the `Invalid node type: export_statement` warning.
1 parent 8b4382f commit 02e9db9

5 files changed

Lines changed: 13 additions & 5 deletions

File tree

codebeacon/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.1.8"
1+
__version__ = "0.2.0"

codebeacon/export/obsidian.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ def generate_obsidian_vault(
7474
vault = Path(obsidian_dir) if obsidian_dir else Path(output_dir) / "obsidian"
7575
vault.mkdir(parents=True, exist_ok=True)
7676

77+
# Clear stale notes from previous runs so step 5 can overwrite them
78+
for svc_dir in vault.iterdir():
79+
if svc_dir.is_dir() and not svc_dir.name.startswith("."):
80+
for md in svc_dir.glob("*.md"):
81+
md.unlink()
82+
7783
# Step 1 — basic note generation
7884
_step1_generate_notes(G, communities, vault)
7985

codebeacon/extract/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def is_grammar_allowed(query_name: str, lang: Language) -> bool:
104104
# Reverse-lookup the grammar name from the cached Language object
105105
gram_name = next((k for k, v in _LANG_CACHE.items() if v is lang), None)
106106
if gram_name is None:
107-
return True # can't determine — let it run
107+
return False # can't determine — deny when allowlist exists
108108
return gram_name in allowed
109109

110110

codebeacon/graph/enrich.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
re.compile(r'''(?:api|http|client|instance|request)\.\w+\b[^`"']*[`"']([^`"'$]+)[`"']'''),
2424
re.compile(r'''url\s*[:=]\s*[`"']([^`"'$]+)[`"']'''),
2525
re.compile(r'''["'](/api/[^"'`\s]+)["'`]'''),
26+
# Rust reqwest: format!("{}/api/...", base_url)
27+
re.compile(r'''"\{\}(/api/[^"'\s]+)'''),
2628
]
2729
_URL_LIKE = re.compile(r'^/[a-zA-Z]')
2830

@@ -68,9 +70,9 @@ def enrich_http_api(G: nx.DiGraph) -> int:
6870
if not route_map:
6971
return 0
7072

71-
# Find component/class nodes and scan their source for API calls
73+
# Find nodes that may call external APIs and scan their source files
7274
for node_id, data in G.nodes(data=True):
73-
if data.get("type") not in ("component", "class"):
75+
if data.get("type") not in ("component", "class", "route", "service"):
7476
continue
7577
src_proj = data.get("project", "")
7678

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "codebeacon"
7-
version = "0.1.8"
7+
version = "0.2.0"
88
description = "Source code AST analysis tool for AI context generation — unified multi-framework knowledge graph"
99
readme = "README.md"
1010
license = { text = "MIT" }

0 commit comments

Comments
 (0)