codegraph-nav 0.1.0__py3-none-any.whl

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 (41) hide show
  1. codegraph_nav/__init__.py +194 -0
  2. codegraph_nav/ast_grep_analyzer.py +448 -0
  3. codegraph_nav/cli.py +223 -0
  4. codegraph_nav/code_navigator.py +1328 -0
  5. codegraph_nav/code_search.py +1009 -0
  6. codegraph_nav/colors.py +209 -0
  7. codegraph_nav/completions.py +354 -0
  8. codegraph_nav/dart_analyzer.py +301 -0
  9. codegraph_nav/dependency_graph.py +814 -0
  10. codegraph_nav/domain/__init__.py +20 -0
  11. codegraph_nav/domain/routes.py +337 -0
  12. codegraph_nav/domain/schemas.py +229 -0
  13. codegraph_nav/domain/tags.py +87 -0
  14. codegraph_nav/exporters.py +563 -0
  15. codegraph_nav/go_analyzer.py +273 -0
  16. codegraph_nav/graph/__init__.py +72 -0
  17. codegraph_nav/graph/builder.py +409 -0
  18. codegraph_nav/graph/communities.py +402 -0
  19. codegraph_nav/graph/flows.py +311 -0
  20. codegraph_nav/graph/query.py +380 -0
  21. codegraph_nav/graph/schema.py +266 -0
  22. codegraph_nav/graph/search.py +257 -0
  23. codegraph_nav/graph/store.py +517 -0
  24. codegraph_nav/hints.py +195 -0
  25. codegraph_nav/import_resolver.py +891 -0
  26. codegraph_nav/js_ts_analyzer.py +564 -0
  27. codegraph_nav/line_reader.py +664 -0
  28. codegraph_nav/mcp/__init__.py +39 -0
  29. codegraph_nav/mcp/__main__.py +5 -0
  30. codegraph_nav/mcp/server.py +2228 -0
  31. codegraph_nav/py.typed +2 -0
  32. codegraph_nav/ruby_analyzer.py +259 -0
  33. codegraph_nav/rust_analyzer.py +379 -0
  34. codegraph_nav/token_efficient_renderer.py +743 -0
  35. codegraph_nav/watcher.py +382 -0
  36. codegraph_nav-0.1.0.dist-info/METADATA +487 -0
  37. codegraph_nav-0.1.0.dist-info/RECORD +41 -0
  38. codegraph_nav-0.1.0.dist-info/WHEEL +5 -0
  39. codegraph_nav-0.1.0.dist-info/entry_points.txt +4 -0
  40. codegraph_nav-0.1.0.dist-info/licenses/LICENSE +21 -0
  41. codegraph_nav-0.1.0.dist-info/top_level.txt +1 -0
codegraph_nav/hints.py ADDED
@@ -0,0 +1,195 @@
1
+ """Session hints — workflow adjacency suggestions and intent detection.
2
+
3
+ Tracks tool usage within a session and suggests the next most useful tool
4
+ based on a workflow adjacency graph. Appends a compact hint line to tool
5
+ responses.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from collections import deque
11
+
12
+ # ==============================================================================
13
+ # Workflow Adjacency Graph
14
+ # ==============================================================================
15
+
16
+ WORKFLOW_GRAPH: dict[str, list[str]] = {
17
+ "codegraph_scan": [
18
+ "codegraph_get_minimal_context",
19
+ "codegraph_search",
20
+ "codegraph_graph_build",
21
+ ],
22
+ "codegraph_get_minimal_context": [
23
+ "codegraph_search",
24
+ "codegraph_get_hubs",
25
+ "codegraph_graph_build",
26
+ ],
27
+ "codegraph_search": [
28
+ "codegraph_read",
29
+ "codegraph_get_structure",
30
+ "codegraph_search_graph",
31
+ ],
32
+ "codegraph_search_graph": [
33
+ "codegraph_read",
34
+ "codegraph_get_structure",
35
+ "codegraph_blast_radius",
36
+ ],
37
+ "codegraph_read": [
38
+ "codegraph_get_dependencies",
39
+ "codegraph_blast_radius",
40
+ "codegraph_search",
41
+ ],
42
+ "codegraph_stats": [
43
+ "codegraph_get_hubs",
44
+ "codegraph_search",
45
+ "codegraph_graph_build",
46
+ ],
47
+ "codegraph_get_hubs": [
48
+ "codegraph_get_dependencies",
49
+ "codegraph_get_structure",
50
+ "codegraph_list_communities",
51
+ ],
52
+ "codegraph_get_structure": [
53
+ "codegraph_read",
54
+ "codegraph_search",
55
+ "codegraph_get_dependencies",
56
+ ],
57
+ "codegraph_get_dependencies": [
58
+ "codegraph_blast_radius",
59
+ "codegraph_read",
60
+ "codegraph_get_structure",
61
+ ],
62
+ "codegraph_test_gaps": [
63
+ "codegraph_read",
64
+ "codegraph_detect_changes",
65
+ "codegraph_search",
66
+ ],
67
+ "codegraph_graph_build": [
68
+ "codegraph_list_flows",
69
+ "codegraph_list_communities",
70
+ "codegraph_detect_changes",
71
+ ],
72
+ "codegraph_blast_radius": [
73
+ "codegraph_read",
74
+ "codegraph_detect_changes",
75
+ "codegraph_list_flows",
76
+ ],
77
+ "codegraph_list_flows": [
78
+ "codegraph_read",
79
+ "codegraph_blast_radius",
80
+ "codegraph_detect_changes",
81
+ ],
82
+ "codegraph_detect_changes": [
83
+ "codegraph_blast_radius",
84
+ "codegraph_test_gaps",
85
+ "codegraph_read",
86
+ ],
87
+ "codegraph_list_communities": [
88
+ "codegraph_get_architecture_overview",
89
+ "codegraph_get_community",
90
+ "codegraph_list_flows",
91
+ ],
92
+ "codegraph_get_community": [
93
+ "codegraph_read",
94
+ "codegraph_list_communities",
95
+ "codegraph_get_dependencies",
96
+ ],
97
+ "codegraph_get_architecture_overview": [
98
+ "codegraph_list_communities",
99
+ "codegraph_list_flows",
100
+ "codegraph_get_hubs",
101
+ ],
102
+ "codegraph_list_routes": [
103
+ "codegraph_read",
104
+ "codegraph_list_schemas",
105
+ "codegraph_get_structure",
106
+ ],
107
+ "codegraph_list_schemas": [
108
+ "codegraph_read",
109
+ "codegraph_list_routes",
110
+ "codegraph_get_structure",
111
+ ],
112
+ }
113
+
114
+ # Intent keywords → intent label
115
+ INTENT_SIGNALS: dict[str, list[str]] = {
116
+ "reviewing": [
117
+ "codegraph_detect_changes",
118
+ "codegraph_blast_radius",
119
+ "codegraph_test_gaps",
120
+ ],
121
+ "debugging": [
122
+ "codegraph_search",
123
+ "codegraph_read",
124
+ "codegraph_search_graph",
125
+ ],
126
+ "implementing": [
127
+ "codegraph_get_structure",
128
+ "codegraph_list_routes",
129
+ "codegraph_list_schemas",
130
+ ],
131
+ "exploring": [
132
+ "codegraph_get_hubs",
133
+ "codegraph_list_communities",
134
+ "codegraph_get_architecture_overview",
135
+ "codegraph_list_flows",
136
+ ],
137
+ }
138
+
139
+
140
+ # ==============================================================================
141
+ # Session State
142
+ # ==============================================================================
143
+
144
+
145
+ class SessionState:
146
+ """Tracks tool usage within a session for next-tool suggestions."""
147
+
148
+ def __init__(self):
149
+ self.tools_called: deque[str] = deque(maxlen=20)
150
+ self.files_touched: set[str] = set()
151
+ self.inferred_intent: str = "exploring"
152
+
153
+ def record(self, tool_name: str, files: list[str] | None = None):
154
+ """Record a tool call and update intent."""
155
+ self.tools_called.append(tool_name)
156
+ if files:
157
+ self.files_touched.update(files)
158
+ self._update_intent()
159
+
160
+ def get_suggestions(self, tool_name: str) -> list[str]:
161
+ """Get top 3 next-tool suggestions based on workflow adjacency."""
162
+ candidates = WORKFLOW_GRAPH.get(tool_name, [])
163
+ if not candidates:
164
+ return ["codegraph_search", "codegraph_read", "codegraph_get_minimal_context"]
165
+
166
+ # Filter out recently called tools
167
+ recent = set(list(self.tools_called)[-3:])
168
+ filtered = [c for c in candidates if c not in recent]
169
+ if not filtered:
170
+ filtered = candidates
171
+
172
+ return filtered[:3]
173
+
174
+ def format_hint(self, tool_name: str) -> str:
175
+ """Format a compact hint line for appending to tool output."""
176
+ suggestions = self.get_suggestions(tool_name)
177
+ if not suggestions:
178
+ return ""
179
+ short_names = [s.replace("codegraph_", "") for s in suggestions]
180
+ return f"_hint: try {' | '.join(short_names)}"
181
+
182
+ def _update_intent(self):
183
+ """Infer session intent from recent tool usage."""
184
+ recent = list(self.tools_called)[-5:]
185
+ if not recent:
186
+ return
187
+
188
+ scores: dict[str, int] = {}
189
+ for intent, signals in INTENT_SIGNALS.items():
190
+ scores[intent] = sum(1 for t in recent if t in signals)
191
+
192
+ if scores:
193
+ best = max(scores, key=scores.get)
194
+ if scores[best] > 0:
195
+ self.inferred_intent = best