codebase-brain 0.3.2__tar.gz → 0.3.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/PKG-INFO +1 -1
  2. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/brain_parser/root_cause.py +34 -8
  3. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/codebase_brain.egg-info/PKG-INFO +1 -1
  4. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/setup.py +1 -1
  5. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/README.md +0 -0
  6. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/brain_cli.py +0 -0
  7. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/brain_parser/__init__.py +0 -0
  8. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/brain_parser/ast_parser.py +0 -0
  9. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/brain_parser/bug_detector.py +0 -0
  10. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/brain_parser/codebase_walker.py +0 -0
  11. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/brain_parser/file_watcher.py +0 -0
  12. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/brain_parser/graph_builder.py +0 -0
  13. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/brain_parser/llm_router.py +0 -0
  14. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/brain_parser/query_engine.py +0 -0
  15. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/brain_parser/universal_parser.py +0 -0
  16. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/codebase_brain.egg-info/SOURCES.txt +0 -0
  17. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/codebase_brain.egg-info/dependency_links.txt +0 -0
  18. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/codebase_brain.egg-info/entry_points.txt +0 -0
  19. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/codebase_brain.egg-info/requires.txt +0 -0
  20. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/codebase_brain.egg-info/top_level.txt +0 -0
  21. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/setup.cfg +0 -0
  22. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/tests/test_bugs.py +0 -0
  23. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/tests/test_classes.py +0 -0
  24. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/tests/test_parser.py +0 -0
  25. {codebase_brain-0.3.2 → codebase_brain-0.3.3}/tests/test_treesitter.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codebase-brain
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: An AI brain that lives inside your codebase
5
5
  Requires-Python: >=3.8
6
6
  Requires-Dist: watchdog
@@ -37,21 +37,47 @@ def extract_frames(stacktrace):
37
37
 
38
38
 
39
39
  def match_frame_to_graph(frame_file, G):
40
- """Match a short filename from stacktrace to full path in graph."""
41
- frame_norm = frame_file.replace('\\', '/')
42
- candidates = []
40
+ """Match any path format from stacktrace to full path in graph — universal matching."""
41
+
42
+ def normalize(path):
43
+ p = path.replace('\\', '/').lower()
44
+ if len(p) > 1 and p[1] == ':':
45
+ p = p[2:]
46
+ return p.lstrip('/')
47
+
48
+ frame_norm = normalize(frame_file)
49
+ frame_parts = frame_norm.split('/')
43
50
 
51
+ candidates = []
44
52
  for node in G.nodes():
45
- node_norm = node.replace('\\', '/')
46
- # exact suffix match — auth/middleware.js matches ./src/auth/middleware.js
47
- if node_norm.endswith(frame_norm):
53
+ node_norm = normalize(node)
54
+ node_parts = node_norm.split('/')
55
+
56
+ min_len = min(len(frame_parts), len(node_parts))
57
+ if min_len == 0:
58
+ continue
59
+
60
+ if frame_parts[-min_len:] == node_parts[-min_len:]:
61
+ candidates.append(node)
62
+ continue
63
+
64
+ if frame_parts[-1] == node_parts[-1]:
48
65
  candidates.append(node)
49
66
 
50
67
  if not candidates:
51
68
  return None
52
- # prefer shortest path — most specific match
53
- return min(candidates, key=len)
54
69
 
70
+ def match_score(node):
71
+ node_parts = normalize(node).split('/')
72
+ score = 0
73
+ for a, b in zip(reversed(frame_parts), reversed(node_parts)):
74
+ if a == b:
75
+ score += 1
76
+ else:
77
+ break
78
+ return score
79
+
80
+ return max(candidates, key=match_score)
55
81
 
56
82
  def find_root_cause(stacktrace):
57
83
  """Main function — paste stacktrace, get root cause analysis."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codebase-brain
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: An AI brain that lives inside your codebase
5
5
  Requires-Python: >=3.8
6
6
  Requires-Dist: watchdog
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="codebase-brain",
5
- version="0.3.2",
5
+ version="0.3.3",
6
6
  description="An AI brain that lives inside your codebase",
7
7
  package_dir={"": "."},
8
8
  packages=find_packages(where="."),
File without changes
File without changes