compass-code 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.
- compass_cli/__init__.py +0 -0
- compass_cli/commands/__init__.py +0 -0
- compass_cli/commands/ingest.py +310 -0
- compass_cli/commands/mcp.py +25 -0
- compass_cli/commands/query.py +181 -0
- compass_cli/commands/serve.py +123 -0
- compass_cli/commands/setup.py +171 -0
- compass_cli/display.py +231 -0
- compass_cli/errors.py +30 -0
- compass_cli/main.py +54 -0
- compass_cli/progress.py +191 -0
- compass_cli/result_views.py +389 -0
- compass_cli/types.py +41 -0
- compass_code-0.1.0.dist-info/METADATA +72 -0
- compass_code-0.1.0.dist-info/RECORD +137 -0
- compass_code-0.1.0.dist-info/WHEEL +4 -0
- compass_code-0.1.0.dist-info/entry_points.txt +2 -0
- compass_core/__init__.py +1 -0
- compass_core/contract/__init__.py +6 -0
- compass_core/contract/errors.py +116 -0
- compass_core/contract/models.py +204 -0
- compass_core/contract/params.py +99 -0
- compass_core/contract/results.py +370 -0
- compass_core/contract/serialize.py +59 -0
- compass_core/contract/types.py +76 -0
- compass_core/errors.py +148 -0
- compass_core/graph/__init__.py +0 -0
- compass_core/graph/db.py +205 -0
- compass_core/graph/schema.py +165 -0
- compass_core/graph/stored_ids.py +133 -0
- compass_core/graph/writer.py +482 -0
- compass_core/index/__init__.py +1 -0
- compass_core/index/freshness.py +55 -0
- compass_core/index/locate.py +155 -0
- compass_core/index/metadata.py +107 -0
- compass_core/ir/__init__.py +0 -0
- compass_core/ir/graph.py +65 -0
- compass_core/ir/models.py +75 -0
- compass_core/languages/__init__.py +1 -0
- compass_core/languages/base.py +26 -0
- compass_core/languages/python/__init__.py +6 -0
- compass_core/languages/python/extractor.py +670 -0
- compass_core/languages/python/import_resolver.py +107 -0
- compass_core/languages/registry.py +89 -0
- compass_core/logger.py +42 -0
- compass_core/phases/__init__.py +0 -0
- compass_core/phases/base.py +58 -0
- compass_core/phases/discovery.py +167 -0
- compass_core/phases/parse.py +80 -0
- compass_core/phases/persistence.py +33 -0
- compass_core/phases/pipeline.py +152 -0
- compass_core/phases/resolution.py +572 -0
- compass_core/phases/symbol_table.py +36 -0
- compass_core/phases/validation.py +76 -0
- compass_core/progress.py +45 -0
- compass_core/py.typed +0 -0
- compass_core/query/__init__.py +1 -0
- compass_core/query/cypher.py +92 -0
- compass_core/query/detail.py +241 -0
- compass_core/query/graph_map.py +127 -0
- compass_core/query/impact.py +273 -0
- compass_core/query/impact_walk.py +352 -0
- compass_core/query/overview.py +221 -0
- compass_core/query/references.py +235 -0
- compass_core/query/rows.py +378 -0
- compass_core/query/search.py +183 -0
- compass_core/query/status.py +49 -0
- compass_core/query/walk_queries.py +202 -0
- compass_core/render.py +408 -0
- compass_core/settings.py +61 -0
- compass_core/shared_types.py +78 -0
- compass_mcp/__init__.py +0 -0
- compass_mcp/guide.py +45 -0
- compass_mcp/py.typed +0 -0
- compass_mcp/server.py +261 -0
- compass_server/__init__.py +5 -0
- compass_server/errors.py +84 -0
- compass_server/main.py +42 -0
- compass_server/py.typed +0 -0
- compass_server/routers/__init__.py +0 -0
- compass_server/routers/query.py +182 -0
- compass_server/settings.py +37 -0
- compass_server/static/404.html +1 -0
- compass_server/static/_next/static/chunks/1629039a.eed2a06658ec4f9c.js +1 -0
- compass_server/static/_next/static/chunks/1ff282bf-bb7c483245264fc9.js +1 -0
- compass_server/static/_next/static/chunks/223.f881a22f446259bf.js +508 -0
- compass_server/static/_next/static/chunks/51fa5c19.6396973222c9d6fd.js +485 -0
- compass_server/static/_next/static/chunks/556.443c1682b6b20128.js +1 -0
- compass_server/static/_next/static/chunks/684-1aa0170f59baf77e.js +1 -0
- compass_server/static/_next/static/chunks/92e71660.3a42d4f70d017951.js +342 -0
- compass_server/static/_next/static/chunks/937-8692224bb6d1b605.js +1 -0
- compass_server/static/_next/static/chunks/app/_not-found/page-2c96ddf295eb6a86.js +1 -0
- compass_server/static/_next/static/chunks/app/layout-4bd0ba4a7d18aff9.js +1 -0
- compass_server/static/_next/static/chunks/app/page-5376a0a98bbd1faa.js +1 -0
- compass_server/static/_next/static/chunks/framework-96dcd958cfe08bd4.js +1 -0
- compass_server/static/_next/static/chunks/main-6dee8e626b16731a.js +1 -0
- compass_server/static/_next/static/chunks/main-app-460e8bc670818718.js +1 -0
- compass_server/static/_next/static/chunks/pages/_app-638a3e7363f92b80.js +1 -0
- compass_server/static/_next/static/chunks/pages/_error-6a72dbbb45cae743.js +1 -0
- compass_server/static/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- compass_server/static/_next/static/chunks/webpack-597057bf48ce4111.js +1 -0
- compass_server/static/_next/static/css/1b0fbfd8dd653f37.css +3 -0
- compass_server/static/_next/static/ctUZeD9K7jQUgLqmBas2L/_buildManifest.js +1 -0
- compass_server/static/_next/static/ctUZeD9K7jQUgLqmBas2L/_ssgManifest.js +1 -0
- compass_server/static/_next/static/media/0086f8992871c45b-s.woff2 +0 -0
- compass_server/static/_next/static/media/034d78ad42e9620c-s.woff2 +0 -0
- compass_server/static/_next/static/media/03b436aa846269de-s.woff2 +0 -0
- compass_server/static/_next/static/media/0484562807a97172-s.p.woff2 +0 -0
- compass_server/static/_next/static/media/08aedeceaf1dcd57-s.woff2 +0 -0
- compass_server/static/_next/static/media/0aa834ed78bf6d07-s.woff2 +0 -0
- compass_server/static/_next/static/media/29a4aea02fdee119-s.woff2 +0 -0
- compass_server/static/_next/static/media/29e7bbdce9332268-s.woff2 +0 -0
- compass_server/static/_next/static/media/36008747766f78c6-s.woff2 +0 -0
- compass_server/static/_next/static/media/39969fcf98a3026e-s.woff2 +0 -0
- compass_server/static/_next/static/media/4de1fea1a954a5b6-s.p.woff2 +0 -0
- compass_server/static/_next/static/media/5c0c2bcbaa4149ca-s.p.woff2 +0 -0
- compass_server/static/_next/static/media/67957d42bae0796d-s.woff2 +0 -0
- compass_server/static/_next/static/media/6d38f9d4e0f4772b-s.woff2 +0 -0
- compass_server/static/_next/static/media/6d664cce900333ee-s.p.woff2 +0 -0
- compass_server/static/_next/static/media/886030b0b59bc5a7-s.woff2 +0 -0
- compass_server/static/_next/static/media/8888a3826f4a3af4-s.p.woff2 +0 -0
- compass_server/static/_next/static/media/939c4f875ee75fbb-s.woff2 +0 -0
- compass_server/static/_next/static/media/a1386beebedccca4-s.woff2 +0 -0
- compass_server/static/_next/static/media/ab00a911ac2adf48-s.woff2 +0 -0
- compass_server/static/_next/static/media/b957ea75a84b6ea7-s.p.woff2 +0 -0
- compass_server/static/_next/static/media/bb3ef058b751a6ad-s.p.woff2 +0 -0
- compass_server/static/_next/static/media/c3bc380753a8436c-s.woff2 +0 -0
- compass_server/static/_next/static/media/cce080f35d014443-s.woff2 +0 -0
- compass_server/static/_next/static/media/db911767852bc875-s.woff2 +0 -0
- compass_server/static/_next/static/media/eafabf029ad39a43-s.p.woff2 +0 -0
- compass_server/static/_next/static/media/f10b8e9d91f3edcb-s.woff2 +0 -0
- compass_server/static/_next/static/media/f911b923c6adde36-s.woff2 +0 -0
- compass_server/static/_next/static/media/fe0777f1195381cb-s.woff2 +0 -0
- compass_server/static/index.html +1 -0
- compass_server/static/index.txt +25 -0
- compass_server/web_bundle.py +27 -0
- compass_server/web_limits.py +48 -0
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
"""Rich views of query results, for a person reading them in a terminal.
|
|
2
|
+
|
|
3
|
+
The query commands print these only when stdout is a terminal. Piped output (scripts,
|
|
4
|
+
coding agents running ``compass`` in a shell) keeps the compact one-line-per-item text
|
|
5
|
+
from ``compass_core.render``, which is cheaper to read and easy to grep. Both show the same
|
|
6
|
+
facts; only the layout differs.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from collections.abc import Iterable, Sequence
|
|
12
|
+
|
|
13
|
+
from rich import box
|
|
14
|
+
from rich.console import Group, RenderableType
|
|
15
|
+
from rich.panel import Panel
|
|
16
|
+
from rich.table import Table
|
|
17
|
+
from rich.text import Text
|
|
18
|
+
|
|
19
|
+
from compass_cli.display import GOLD
|
|
20
|
+
from compass_core.contract.models import Caveat, IndexStatus, ResultItem, SymbolRef
|
|
21
|
+
from compass_core.contract.results import (
|
|
22
|
+
ImpactResult,
|
|
23
|
+
NodeDetail,
|
|
24
|
+
OverviewResult,
|
|
25
|
+
RankedSymbol,
|
|
26
|
+
SearchResult,
|
|
27
|
+
)
|
|
28
|
+
from compass_core.contract.types import CaveatCode
|
|
29
|
+
from compass_core.render import local_name, location, match_reason, plural, via_text
|
|
30
|
+
from compass_core.shared_types import EdgeType, SymbolKind
|
|
31
|
+
|
|
32
|
+
EDGE_LABELS: dict[EdgeType, str] = {
|
|
33
|
+
EdgeType.CONTAINS: "Contains",
|
|
34
|
+
EdgeType.IMPORTS: "Imports",
|
|
35
|
+
EdgeType.INHERITS: "Inherits",
|
|
36
|
+
EdgeType.CALLS: "Calls",
|
|
37
|
+
EdgeType.CALLS_EXTERN: "External calls",
|
|
38
|
+
}
|
|
39
|
+
"""Row label for each edge type in the overview totals."""
|
|
40
|
+
|
|
41
|
+
_NO_WRAP = frozenset({"Location", "File", "Kind", "Hops"})
|
|
42
|
+
"""Columns kept on one line; narrow terminals wrap the others first."""
|
|
43
|
+
|
|
44
|
+
_LABEL_WIDTH = 13
|
|
45
|
+
"""Width of the dim label column in key/value grids, matching the ingest summary."""
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _title(text: str) -> Text:
|
|
49
|
+
return Text(text, style=f"bold {GOLD}")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _location(symbol: SymbolRef) -> Text:
|
|
53
|
+
"""``path:line`` with the directory dimmed, so the file name stands out."""
|
|
54
|
+
where = location(symbol)
|
|
55
|
+
directory, slash, rest = where.rpartition("/")
|
|
56
|
+
text = Text(overflow="fold")
|
|
57
|
+
if slash:
|
|
58
|
+
text.append(directory + slash, style="dim")
|
|
59
|
+
text.append(rest)
|
|
60
|
+
return text
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _name(symbol: SymbolRef) -> Text:
|
|
64
|
+
"""The name within its file, last part bold (``User.`` **save**); a file's base name."""
|
|
65
|
+
prefix, dot, last = local_name(symbol).rpartition(".")
|
|
66
|
+
text = Text(overflow="fold")
|
|
67
|
+
if dot and symbol.kind is not SymbolKind.FILE:
|
|
68
|
+
text.append(prefix + dot, style="dim")
|
|
69
|
+
text.append(last, style="bold")
|
|
70
|
+
else:
|
|
71
|
+
text.append(local_name(symbol).rpartition("/")[2], style="bold")
|
|
72
|
+
return text
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _table(*headers: str, numeric: Sequence[str] = ()) -> Table:
|
|
76
|
+
table = Table(box=box.SIMPLE_HEAD, header_style="dim", show_edge=False, pad_edge=False)
|
|
77
|
+
for header in headers:
|
|
78
|
+
table.add_column(
|
|
79
|
+
header,
|
|
80
|
+
justify="right" if header in numeric else "left",
|
|
81
|
+
no_wrap=header in _NO_WRAP,
|
|
82
|
+
)
|
|
83
|
+
return table
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _section(title: str, body: RenderableType) -> Group:
|
|
87
|
+
return Group(Text(""), _title(title), body)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _caveats(caveats: Iterable[Caveat]) -> list[Text]:
|
|
91
|
+
"""Caveats in yellow; a stale index is already flagged by ``index_line``."""
|
|
92
|
+
return [
|
|
93
|
+
Text(f"! {caveat.message}", style="yellow")
|
|
94
|
+
for caveat in caveats
|
|
95
|
+
if caveat.code is not CaveatCode.STALE_INDEX
|
|
96
|
+
]
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _more(shown: int, total: int) -> list[Text]:
|
|
100
|
+
hidden = total - shown
|
|
101
|
+
if hidden <= 0:
|
|
102
|
+
return []
|
|
103
|
+
return [Text(f"… {hidden:,} more; raise --limit to see them", style="dim")]
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _freshness(status: IndexStatus) -> Text:
|
|
107
|
+
if status.stale_file_count:
|
|
108
|
+
changed = plural(status.stale_file_count, "file")
|
|
109
|
+
return Text(f"⚠ {changed} changed since; run compass ingest", style="yellow")
|
|
110
|
+
return Text("✓ up to date", style="green")
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def index_line(status: IndexStatus) -> Text:
|
|
114
|
+
"""One dim line saying which index answered and whether it is fresh.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
status: The index status every result carries.
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
The line, e.g. ``index 5610406 · built 2026-11-10 09:30 UTC · ✓ up to date``.
|
|
121
|
+
"""
|
|
122
|
+
commit = status.indexed_commit[:7] if status.indexed_commit else "no git commit"
|
|
123
|
+
built = status.indexed_at.strftime("%Y-%m-%d %H:%M UTC")
|
|
124
|
+
line = Text(f"index {commit} · built {built} · ", style="dim")
|
|
125
|
+
line.append_text(_freshness(status))
|
|
126
|
+
return line
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def status_view(status: IndexStatus) -> Panel:
|
|
130
|
+
"""The index: which repository, which commit, when it was built and if it is fresh.
|
|
131
|
+
|
|
132
|
+
Args:
|
|
133
|
+
status: The index status.
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
A gold panel with one labelled row per fact.
|
|
137
|
+
|
|
138
|
+
Example:
|
|
139
|
+
``Repository /home/me/app``, ``Commit 5610406``, ``Built 2026-11-10 09:30 UTC``
|
|
140
|
+
and ``Status ✓ up to date``.
|
|
141
|
+
"""
|
|
142
|
+
grid = Table.grid(padding=(0, 3))
|
|
143
|
+
grid.add_column(style="dim", min_width=_LABEL_WIDTH)
|
|
144
|
+
grid.add_column()
|
|
145
|
+
grid.add_row("Repository", Text(str(status.repo_root), style="bold"))
|
|
146
|
+
grid.add_row("Commit", status.indexed_commit[:7] if status.indexed_commit else "no git commit")
|
|
147
|
+
grid.add_row("Built", status.indexed_at.strftime("%Y-%m-%d %H:%M UTC"))
|
|
148
|
+
grid.add_row("Status", _freshness(status))
|
|
149
|
+
return Panel(grid, title=_title("compass index"), border_style=GOLD, padding=(1, 2))
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def _totals(result: OverviewResult) -> Table:
|
|
153
|
+
counts, calls = result.counts, result.call_resolution
|
|
154
|
+
percent = round(100 * calls.resolved / calls.total) if calls.total else 0
|
|
155
|
+
|
|
156
|
+
left = Table.grid(padding=(0, 3))
|
|
157
|
+
left.add_column(style="dim", min_width=_LABEL_WIDTH)
|
|
158
|
+
left.add_column(style="bold")
|
|
159
|
+
left.add_row("Files", f"{counts.files:,}")
|
|
160
|
+
left.add_row("Classes", f"{counts.classes:,}")
|
|
161
|
+
left.add_row("Functions", f"{counts.functions:,}")
|
|
162
|
+
resolved = Text(f"{percent}%", style="bold")
|
|
163
|
+
resolved.append(f" ({calls.resolved:,} of {calls.total:,})", style="dim")
|
|
164
|
+
left.add_row("Calls resolved", resolved)
|
|
165
|
+
|
|
166
|
+
right = Table.grid(padding=(0, 3))
|
|
167
|
+
right.add_column(style="dim", min_width=_LABEL_WIDTH)
|
|
168
|
+
right.add_column(style="bold")
|
|
169
|
+
for edge, count in counts.edges_by_type.items():
|
|
170
|
+
right.add_row(EDGE_LABELS[edge], f"{count:,}")
|
|
171
|
+
|
|
172
|
+
columns = Table.grid(padding=(0, 8))
|
|
173
|
+
columns.add_column()
|
|
174
|
+
columns.add_column()
|
|
175
|
+
columns.add_row(left, right)
|
|
176
|
+
return columns
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def _ranked(ranked: tuple[RankedSymbol, ...], count_header: str) -> Table:
|
|
180
|
+
"""One row per symbol with its count; files show only their path."""
|
|
181
|
+
if all(item.symbol.kind is SymbolKind.FILE for item in ranked):
|
|
182
|
+
files = _table("File", count_header, numeric=(count_header,))
|
|
183
|
+
for item in ranked:
|
|
184
|
+
files.add_row(_location(item.symbol), f"{item.count:,}")
|
|
185
|
+
return files
|
|
186
|
+
table = _table("Name", "Location", count_header, numeric=(count_header,))
|
|
187
|
+
for item in ranked:
|
|
188
|
+
table.add_row(_name(item.symbol), _location(item.symbol), f"{item.count:,}")
|
|
189
|
+
return table
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def overview_view(result: OverviewResult) -> Group:
|
|
193
|
+
"""The shape of the repository: totals, then one table per hot-spot list.
|
|
194
|
+
|
|
195
|
+
Args:
|
|
196
|
+
result: An overview result.
|
|
197
|
+
|
|
198
|
+
Returns:
|
|
199
|
+
The index line, a gold panel of totals, the entry points and the ranked tables,
|
|
200
|
+
then any caveats.
|
|
201
|
+
|
|
202
|
+
Example:
|
|
203
|
+
A panel with ``Files 147`` and ``Calls 225``, then ``Most called functions`` as a
|
|
204
|
+
table of ``Name``, ``Location`` and ``Callers``.
|
|
205
|
+
"""
|
|
206
|
+
parts: list[RenderableType] = [
|
|
207
|
+
index_line(result.index),
|
|
208
|
+
Panel(_totals(result), title=_title("compass overview"), border_style=GOLD, padding=(1, 2)),
|
|
209
|
+
]
|
|
210
|
+
if result.entry_points:
|
|
211
|
+
entries = _table("File", "Module")
|
|
212
|
+
for symbol in result.entry_points:
|
|
213
|
+
entries.add_row(_location(symbol), Text(symbol.qualified_name, style="dim"))
|
|
214
|
+
parts.append(_section("Entry points (files nothing imports)", entries))
|
|
215
|
+
sections = (
|
|
216
|
+
("Most imported files", result.most_imported_files, "Importers"),
|
|
217
|
+
("Most called functions", result.most_called_functions, "Callers"),
|
|
218
|
+
("Riskiest to change", result.riskiest_to_change, "Affected"),
|
|
219
|
+
)
|
|
220
|
+
for title, ranked, header in sections:
|
|
221
|
+
if ranked:
|
|
222
|
+
parts.append(_section(title, _ranked(ranked, header)))
|
|
223
|
+
if result.top_external_libraries:
|
|
224
|
+
libraries = _table("Library", "Calls", numeric=("Calls",))
|
|
225
|
+
for lib in result.top_external_libraries:
|
|
226
|
+
libraries.add_row(Text(lib.library, style="bold"), f"{lib.call_count:,}")
|
|
227
|
+
parts.append(_section("Top external libraries", libraries))
|
|
228
|
+
parts += _caveats(result.caveats)
|
|
229
|
+
return Group(*parts)
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def search_view(result: SearchResult) -> Group:
|
|
233
|
+
"""Search hits as a table, best first, with why each matched.
|
|
234
|
+
|
|
235
|
+
Args:
|
|
236
|
+
result: A search result.
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
The index line, a title with the hit count, the table and any caveats.
|
|
240
|
+
|
|
241
|
+
Example:
|
|
242
|
+
``search "save" · 2 hits`` then rows like ``save method app/models.py:2 exact
|
|
243
|
+
name · 1 caller``.
|
|
244
|
+
"""
|
|
245
|
+
table = _table("Name", "Kind", "Location", "Match")
|
|
246
|
+
for hit in result.hits:
|
|
247
|
+
table.add_row(
|
|
248
|
+
_name(hit.symbol),
|
|
249
|
+
Text(hit.symbol.kind.value, style="dim"),
|
|
250
|
+
_location(hit.symbol),
|
|
251
|
+
Text(match_reason(hit), style="dim"),
|
|
252
|
+
)
|
|
253
|
+
title = Text(f'search "{result.query}"', style=f"bold {GOLD}")
|
|
254
|
+
title.append(f" · {plural(result.total, 'hit')}", style="dim")
|
|
255
|
+
return Group(
|
|
256
|
+
index_line(result.index),
|
|
257
|
+
Text(""),
|
|
258
|
+
title,
|
|
259
|
+
table,
|
|
260
|
+
*_more(len(result.hits), result.total),
|
|
261
|
+
*_caveats(result.caveats),
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def _neighbours(title: str, symbols: tuple[SymbolRef, ...]) -> list[RenderableType]:
|
|
266
|
+
if not symbols:
|
|
267
|
+
return []
|
|
268
|
+
table = _table("Name", "Kind", "Location")
|
|
269
|
+
for symbol in symbols:
|
|
270
|
+
table.add_row(_name(symbol), Text(symbol.kind.value, style="dim"), _location(symbol))
|
|
271
|
+
return [_section(f"{title} ({len(symbols)})", table)]
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
def describe_view(detail: NodeDetail, *, include_source: bool = False) -> Group:
|
|
275
|
+
"""One symbol: a panel with where and what it is, then a table per neighbour list.
|
|
276
|
+
|
|
277
|
+
Args:
|
|
278
|
+
detail: A describe result.
|
|
279
|
+
include_source: Also show the symbol's source text.
|
|
280
|
+
|
|
281
|
+
Returns:
|
|
282
|
+
The index line, the symbol panel, the neighbour tables and any caveats.
|
|
283
|
+
|
|
284
|
+
Example:
|
|
285
|
+
A panel titled ``method User.save`` with ``Location app/models.py:6-7`` and
|
|
286
|
+
``Id app/models.py::User.save``, then ``Callees (1)``.
|
|
287
|
+
"""
|
|
288
|
+
symbol = detail.symbol
|
|
289
|
+
grid = Table.grid(padding=(0, 3))
|
|
290
|
+
grid.add_column(style="dim", min_width=_LABEL_WIDTH)
|
|
291
|
+
grid.add_column()
|
|
292
|
+
grid.add_row("Name", _name(symbol))
|
|
293
|
+
span = location(symbol)
|
|
294
|
+
if symbol.file_path and symbol.line_start and symbol.line_end != symbol.line_start:
|
|
295
|
+
span = f"{span}-{symbol.line_end}"
|
|
296
|
+
grid.add_row("Location", span)
|
|
297
|
+
grid.add_row("Id", Text(symbol.id, style="dim"))
|
|
298
|
+
if symbol.signature:
|
|
299
|
+
grid.add_row("Signature", Text(symbol.signature, style="bold"))
|
|
300
|
+
body: list[RenderableType] = [grid]
|
|
301
|
+
if detail.docstring:
|
|
302
|
+
body += [Text(""), Text(detail.docstring.strip(), style="italic")]
|
|
303
|
+
parts: list[RenderableType] = [
|
|
304
|
+
index_line(detail.index),
|
|
305
|
+
Panel(
|
|
306
|
+
Group(*body),
|
|
307
|
+
title=_title(f"{symbol.kind.value} {symbol.name}"),
|
|
308
|
+
border_style=GOLD,
|
|
309
|
+
padding=(1, 2),
|
|
310
|
+
),
|
|
311
|
+
]
|
|
312
|
+
parts += _neighbours("Bases", detail.bases)
|
|
313
|
+
parts += _neighbours("Subclasses", detail.subclasses)
|
|
314
|
+
parts += _neighbours("Members", detail.members)
|
|
315
|
+
parts += _neighbours("Callers", detail.callers)
|
|
316
|
+
parts += _neighbours("Callees", detail.callees)
|
|
317
|
+
parts += _neighbours("Imports", detail.imports)
|
|
318
|
+
parts += _neighbours("Imported by", detail.imported_by)
|
|
319
|
+
if detail.truncated:
|
|
320
|
+
parts.append(
|
|
321
|
+
Text("! some lists were cut short; describe the related symbols directly", "yellow")
|
|
322
|
+
)
|
|
323
|
+
if include_source and symbol.source:
|
|
324
|
+
parts.append(_section("Source", Text(symbol.source.rstrip())))
|
|
325
|
+
parts += _caveats(detail.caveats)
|
|
326
|
+
return Group(*parts)
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
def _impact_row(table: Table, item: ResultItem) -> None:
|
|
330
|
+
via = via_text(item.via) if item.via else ""
|
|
331
|
+
confidence = "" if item.min_confidence is None else f"{item.min_confidence:.2f}"
|
|
332
|
+
table.add_row(
|
|
333
|
+
str(item.distance),
|
|
334
|
+
_name(item.symbol),
|
|
335
|
+
_location(item.symbol),
|
|
336
|
+
Text(via, style="dim"),
|
|
337
|
+
confidence,
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
def impact_view(result: ImpactResult) -> Group:
|
|
342
|
+
"""What may break if the target changes: a summary panel, then one row per symbol.
|
|
343
|
+
|
|
344
|
+
Args:
|
|
345
|
+
result: An impact result.
|
|
346
|
+
|
|
347
|
+
Returns:
|
|
348
|
+
The index line, the summary panel, the affected symbols nearest first and the
|
|
349
|
+
caveats (an empty answer is never shown as certain).
|
|
350
|
+
|
|
351
|
+
Example:
|
|
352
|
+
A panel ``impact of function decode_token`` with ``Affected 3 symbols in 2
|
|
353
|
+
files``, then rows like ``1 app.api.handle app/api.py:4 calls decode_token
|
|
354
|
+
1.00``.
|
|
355
|
+
"""
|
|
356
|
+
target = result.target
|
|
357
|
+
grid = Table.grid(padding=(0, 3))
|
|
358
|
+
grid.add_column(style="dim", min_width=_LABEL_WIDTH)
|
|
359
|
+
grid.add_column()
|
|
360
|
+
grid.add_row("Target", _name(target))
|
|
361
|
+
grid.add_row("Location", location(target))
|
|
362
|
+
grid.add_row("Depth", str(result.depth))
|
|
363
|
+
grid.add_row(
|
|
364
|
+
"Affected",
|
|
365
|
+
Text(
|
|
366
|
+
f"{plural(result.total, 'symbol')} in {plural(result.affected_file_count, 'file')}",
|
|
367
|
+
style="bold",
|
|
368
|
+
),
|
|
369
|
+
)
|
|
370
|
+
table = _table("Hops", "Name", "Location", "Via", "Confidence", numeric=("Hops", "Confidence"))
|
|
371
|
+
shown = 0
|
|
372
|
+
for group in result.groups:
|
|
373
|
+
for item in group.items:
|
|
374
|
+
_impact_row(table, item)
|
|
375
|
+
shown += 1
|
|
376
|
+
parts: list[RenderableType] = [
|
|
377
|
+
index_line(result.index),
|
|
378
|
+
Panel(
|
|
379
|
+
grid,
|
|
380
|
+
title=_title(f"impact of {target.kind.value} {target.name}"),
|
|
381
|
+
border_style=GOLD,
|
|
382
|
+
padding=(1, 2),
|
|
383
|
+
),
|
|
384
|
+
]
|
|
385
|
+
if shown:
|
|
386
|
+
parts.append(table)
|
|
387
|
+
parts += _more(shown, result.total)
|
|
388
|
+
parts += _caveats(result.caveats)
|
|
389
|
+
return Group(*parts)
|
compass_cli/types.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Typed data objects shared across compass_cli commands."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from enum import StrEnum
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
from compass_core.shared_types import Language
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(frozen=True)
|
|
13
|
+
class IngestSummary:
|
|
14
|
+
"""Aggregate results of a single `compass ingest` run."""
|
|
15
|
+
|
|
16
|
+
file_count: int
|
|
17
|
+
class_count: int
|
|
18
|
+
function_count: int
|
|
19
|
+
elapsed: float
|
|
20
|
+
node_count: int
|
|
21
|
+
edge_count: int
|
|
22
|
+
db_path: Path
|
|
23
|
+
db_size: int
|
|
24
|
+
skipped: int
|
|
25
|
+
resolved_pct: float
|
|
26
|
+
orphan_count: int
|
|
27
|
+
language_counts: dict[Language, int]
|
|
28
|
+
dropped_edges: int = 0
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class OutputFormat(StrEnum):
|
|
32
|
+
"""How a query command prints its answer.
|
|
33
|
+
|
|
34
|
+
Attributes:
|
|
35
|
+
TEXT: Compact text, one line per item with ``file:line`` first; for people and
|
|
36
|
+
coding agents.
|
|
37
|
+
JSON: The typed contract result as JSON; for scripts and tools.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
TEXT = "text"
|
|
41
|
+
JSON = "json"
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: compass-code
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Local-first code knowledge graph for AI coding agents: the compass command and its MCP server.
|
|
5
|
+
Project-URL: Homepage, https://github.com/NIKU-SINGH/code-compass
|
|
6
|
+
Project-URL: Repository, https://github.com/NIKU-SINGH/code-compass
|
|
7
|
+
Project-URL: Issues, https://github.com/NIKU-SINGH/code-compass/issues
|
|
8
|
+
License-Expression: Apache-2.0
|
|
9
|
+
Keywords: code-graph,coding-agents,knowledge-graph,mcp,tree-sitter
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Topic :: Software Development
|
|
17
|
+
Requires-Python: >=3.11
|
|
18
|
+
Requires-Dist: fastapi>=0.115.0
|
|
19
|
+
Requires-Dist: mcp<2,>=1.26.0
|
|
20
|
+
Requires-Dist: pathspec>=1.0.4
|
|
21
|
+
Requires-Dist: pydantic-settings>=2.0.0
|
|
22
|
+
Requires-Dist: pydantic>=2.0.0
|
|
23
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
24
|
+
Requires-Dist: real-ladybug<0.16,>=0.15.3
|
|
25
|
+
Requires-Dist: rich>=13.0.0
|
|
26
|
+
Requires-Dist: tree-sitter-python<0.26,>=0.25.0
|
|
27
|
+
Requires-Dist: tree-sitter<0.26,>=0.25.0
|
|
28
|
+
Requires-Dist: typer>=0.9.0
|
|
29
|
+
Requires-Dist: uvicorn>=0.32.0
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
# Code Compass
|
|
33
|
+
|
|
34
|
+
**A local-first code knowledge graph for AI coding agents.** Code Compass parses your
|
|
35
|
+
repository with Tree-sitter into a graph of files, classes, functions and the calls,
|
|
36
|
+
imports and inheritance between them, and answers structural questions from it: where
|
|
37
|
+
something is defined, who calls it, and what may break if it changes. Coding agents
|
|
38
|
+
(Claude Code, Codex, Cursor) ask over MCP; you ask with the `compass` command or in a 3D
|
|
39
|
+
web view. Parsing is deterministic and nothing leaves your machine: no API keys, no
|
|
40
|
+
embeddings, no network calls.
|
|
41
|
+
|
|
42
|
+
> **Alpha.** Python repositories only; call resolution is partial, and every answer says
|
|
43
|
+
> where it may be incomplete.
|
|
44
|
+
|
|
45
|
+
## Install
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
uv tool install compass-code # or: pipx install compass-code
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Use
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
cd your-repo
|
|
55
|
+
compass ingest . # build the graph in .compass/
|
|
56
|
+
compass overview # entry points and hot spots
|
|
57
|
+
compass search save # where is it defined?
|
|
58
|
+
compass describe app/models.py::User
|
|
59
|
+
compass impact decode_token # what may break if it changes?
|
|
60
|
+
compass serve # explore the graph in the browser
|
|
61
|
+
compass setup --mcp # let coding agents in this repo use it
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
For Codex, add to `~/.codex/config.toml`:
|
|
65
|
+
|
|
66
|
+
```toml
|
|
67
|
+
[mcp_servers.code-compass]
|
|
68
|
+
command = "compass"
|
|
69
|
+
args = ["mcp"]
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Documentation, source and issues: https://github.com/NIKU-SINGH/code-compass
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
compass_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
compass_cli/display.py,sha256=krgkeDQuT8iIAIW_QLpufCPo6H-aI2P8wE79ey3aEPY,8043
|
|
3
|
+
compass_cli/errors.py,sha256=PYXZuU2uoYTTO1kje_Iip3h6cOU9Bzd8iCo165vO-yY,809
|
|
4
|
+
compass_cli/main.py,sha256=e_PefCx8nl9y09ri0gmfUKVixQq05M2VZtroODiBjfo,1497
|
|
5
|
+
compass_cli/progress.py,sha256=ZK9DaK7iD-dgindMKK15kmPySSE-HuNAF0uDtokE8sI,6487
|
|
6
|
+
compass_cli/result_views.py,sha256=NiCB7hhUkzZsus7ey2hua9RkX1psRWd6cZg36NfhCcs,14013
|
|
7
|
+
compass_cli/types.py,sha256=mWVTx5R-yx1LMn8VOgWrYmxsOPOrasWTMbdEunlOEcQ,955
|
|
8
|
+
compass_cli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
+
compass_cli/commands/ingest.py,sha256=I7ejSqfBb_bRqK9Gd5u-e-wo5ZRdt8L6d51llYQKFaE,12237
|
|
10
|
+
compass_cli/commands/mcp.py,sha256=CBH8t-rx3l7-XR9oYi_5n0jVAmUOnOVqEC3_Zbu4pmM,693
|
|
11
|
+
compass_cli/commands/query.py,sha256=zNkD-nEsv5mQGyjm_2rGu41vr5zljograpmR7JtFCOU,7255
|
|
12
|
+
compass_cli/commands/serve.py,sha256=5lQKA-yG7XoQlCPS7yEj5Z8bFXfZIOVaC_PjCEvdGUs,4199
|
|
13
|
+
compass_cli/commands/setup.py,sha256=xtcmauTOE716zPA3OARLzvnkRMTrR77GDa5IjwHfSro,5836
|
|
14
|
+
compass_core/__init__.py,sha256=bLZ28IvgwA7oBuxlzvElrUyjSnFyRiiAViXnU0mAnR4,36
|
|
15
|
+
compass_core/errors.py,sha256=inwih-HI_0lHP61sW4QS6QzL6YUO40iV6xjTeC3-658,4640
|
|
16
|
+
compass_core/logger.py,sha256=KErtsdB0Ns8Jng8sGw5SrwB751ynY0OmYn34uw61yZM,1209
|
|
17
|
+
compass_core/progress.py,sha256=Xt74PchS_Ryq8TM2UZlzktHrTAO1LkXlqXiiCpnIpZI,1274
|
|
18
|
+
compass_core/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
|
+
compass_core/render.py,sha256=z_qzdxdCLMYLZaU5tAidZKJmRFtseQiaG90_Z1BtctI,13213
|
|
20
|
+
compass_core/settings.py,sha256=cWrkcniccwCKPgaLA9-f7-QPPFsGUItPSHSwrH2LMPA,2121
|
|
21
|
+
compass_core/shared_types.py,sha256=svqlJnMxXZy14woxHCSB7zDq27oTcujWV87tdM_11Xo,2340
|
|
22
|
+
compass_core/contract/__init__.py,sha256=OGDPIc8G_WnNzBWaWcVYvXWBlziYPfK3iE670SjiFZo,322
|
|
23
|
+
compass_core/contract/errors.py,sha256=ypaw7Y_EYM48PdsNTQA97RWkdk91a0CEY2Ang7LaSLY,3864
|
|
24
|
+
compass_core/contract/models.py,sha256=AjOreXm8OlBVEw2OnOBXjdAOs95grcW0PoGHnD27wGk,7478
|
|
25
|
+
compass_core/contract/params.py,sha256=8US4THZ46ukORVI3IjeFsGZCU0VE7BRWTS4gzN4MQ-E,3018
|
|
26
|
+
compass_core/contract/results.py,sha256=_2yIxn68Eyppoxcq3kJWNHJEeMbTddcFA7uwgv7QgfE,11245
|
|
27
|
+
compass_core/contract/serialize.py,sha256=mrPoYUUpYT7_gyETdmRwzIh_H4FdXGJh9QXVChKfcLE,1507
|
|
28
|
+
compass_core/contract/types.py,sha256=d8TqDwb4jDjJNhrjECXUoLabKdEpkLgLY--5EcAxm6I,2100
|
|
29
|
+
compass_core/graph/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
30
|
+
compass_core/graph/db.py,sha256=Wx1znvYeKC87qFzRCqFVaznZ_DyiSbTbfllhmAjyLS4,7469
|
|
31
|
+
compass_core/graph/schema.py,sha256=5sCkUFpQpSWyLzGrg0TuBYqlq8I2RawUyVM9zfh4uPY,6152
|
|
32
|
+
compass_core/graph/stored_ids.py,sha256=p1MPMXcFjDW8vsvO4G4ojKx5MstvWk9ICvRmJHV6rGI,4567
|
|
33
|
+
compass_core/graph/writer.py,sha256=1CynWY_EJE27ioDM-BsrAJ-sNjl6Pz6ujR3NMr9gx-w,17721
|
|
34
|
+
compass_core/index/__init__.py,sha256=pznUFyoF9HfB5GurNvgW6MBNzS1zfvyS-Wpln54g__Q,57
|
|
35
|
+
compass_core/index/freshness.py,sha256=FiMgyNJRa1Hyw_1OSznsB-d-E59qlaysaU7u8mDutvo,1868
|
|
36
|
+
compass_core/index/locate.py,sha256=YSJPFVKA-OwlccaWy98jmt0ZVXIdxAV6wmIeZuNDA5M,4957
|
|
37
|
+
compass_core/index/metadata.py,sha256=3kfBx1UTmmEusnZFMvER91bZmRiLhaqr4rVh10o3m4Q,4162
|
|
38
|
+
compass_core/ir/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
|
+
compass_core/ir/graph.py,sha256=ItJHo16U24EQnbHGJrTB41RN0BuGJv4fJisMqKOgt30,1753
|
|
40
|
+
compass_core/ir/models.py,sha256=36Lf4OlGbROWbRpoCAcmKvphhF5g8KWIUwDkYtPJKsM,2075
|
|
41
|
+
compass_core/languages/__init__.py,sha256=U5_wQ2gIBTys9lGpzlNNCvIjgLsnvzBpZ2DYx_30NnY,67
|
|
42
|
+
compass_core/languages/base.py,sha256=BtR8X4LCXW177kPPInokBip06DEXjN72EUR3LMjFz20,721
|
|
43
|
+
compass_core/languages/registry.py,sha256=rGk0fsBsS-LWoUHEbN1T_kOJajhMN7AhbahvmkvkjsY,3114
|
|
44
|
+
compass_core/languages/python/__init__.py,sha256=_zIlp3tJ-ivgZr6lCt9MJ5YVBwvq40a0OsThL0zRjJQ,297
|
|
45
|
+
compass_core/languages/python/extractor.py,sha256=wsqlP9r3zNysviqs3ls523VHRzjjCTIumh_hJzOnJuE,24802
|
|
46
|
+
compass_core/languages/python/import_resolver.py,sha256=s0SHp-dcnHmNYl1qo2TdPuqtD3htbiBWXjFNALZ2T4U,4485
|
|
47
|
+
compass_core/phases/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
48
|
+
compass_core/phases/base.py,sha256=OEC5TQHKZBu6v8huJPky8H7QdP7e90W64GtM914z-sQ,1593
|
|
49
|
+
compass_core/phases/discovery.py,sha256=UcgZnYt5ttlLkHwOlD2vF_Uq62Wh6ibl4abuHYxkmQQ,5454
|
|
50
|
+
compass_core/phases/parse.py,sha256=PAJiEoUB48hJrsZRNFnYU6UUcDkoEwvzKK-kMGUyB7Y,3052
|
|
51
|
+
compass_core/phases/persistence.py,sha256=Bw5mNh6YaOh0qgMJUFvg8CeJ8d0XCH5YqLebXa458-4,1327
|
|
52
|
+
compass_core/phases/pipeline.py,sha256=iSpinvT_QUOe2XhJIgbUC1QLHhblh06NI8aFlSwcc1s,5508
|
|
53
|
+
compass_core/phases/resolution.py,sha256=ifE-PPTted4HvKcUt9EY7vXz0db281DKUzZn2-HWaVQ,23199
|
|
54
|
+
compass_core/phases/symbol_table.py,sha256=sHRuNFY70mgwIMSe6FgIDG_CSzqbE21AWyAxrh_Kjy0,1389
|
|
55
|
+
compass_core/phases/validation.py,sha256=VPSrzXLdCry0hO5Z_VGrjDCN5dPmPPJb_uElXVfHIQc,2869
|
|
56
|
+
compass_core/query/__init__.py,sha256=Ht8JXVvajtbujwCJMsPCbTh5yP6GEficDsFsuCCkMpI,66
|
|
57
|
+
compass_core/query/cypher.py,sha256=B0i6xB5e18PIy5ewbseCN7vqtmQqkWgYV_0gwcin4BU,3602
|
|
58
|
+
compass_core/query/detail.py,sha256=sUyX_jVpiWFmJs5UsykgNQJjZjRz8Dj4yKShOzLeESA,8804
|
|
59
|
+
compass_core/query/graph_map.py,sha256=RIX_I9JhL55v2QNUrWCNuSYmTx04xRs9_iz4CB3_JM8,4116
|
|
60
|
+
compass_core/query/impact.py,sha256=piSg_4h_GkquUgAnA65X2sGfWpMonzR2GuhlL6FVP4E,11472
|
|
61
|
+
compass_core/query/impact_walk.py,sha256=5wXP80ocsbYCYFND7nWnzerELHokEJdhWzHBxU9Kk6k,14703
|
|
62
|
+
compass_core/query/overview.py,sha256=IZNxaOLXfmT2--WYrryixLzKjvRbtOxaU-EPm34kh6c,8474
|
|
63
|
+
compass_core/query/references.py,sha256=lcHFl2nx71PKwWJUQ5zVTtVNqzvbMqjjOyOpXbGnwEQ,8941
|
|
64
|
+
compass_core/query/rows.py,sha256=Ar-PJdpVBiBrYoYA1RSCK3ZXKZRSPsq_quJqsT9X0t4,11752
|
|
65
|
+
compass_core/query/search.py,sha256=QAaUIKneWu51ZNyxGyuKvRDixPkR8UBEjoTmpYPpbJA,6950
|
|
66
|
+
compass_core/query/status.py,sha256=c7eb204_nB3zjkBs5SeIfRSiCkC6Wi1k86vS1hGW5ws,1757
|
|
67
|
+
compass_core/query/walk_queries.py,sha256=Rvkla5pb1Nm5gyva745fwqauIMcM21Cg-uO7CX-XyJc,5911
|
|
68
|
+
compass_mcp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
69
|
+
compass_mcp/guide.py,sha256=rAYwnxn0TZypSyDPxRdYorQ2OMPbtc_lNNIFt7CuqmM,2450
|
|
70
|
+
compass_mcp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
71
|
+
compass_mcp/server.py,sha256=-owv7sHphYh8_VW3yUa_HZRz2JxpGC77PTo3UakR_jc,10015
|
|
72
|
+
compass_server/__init__.py,sha256=uVqAZBP4QElVBIzkwhNYC4qJYp6NKm4p3wtOss66zdM,209
|
|
73
|
+
compass_server/errors.py,sha256=rz8nCLlSo8miCsQeTRREZ7s_oPBiC3Ag4xm8aur5b0s,2959
|
|
74
|
+
compass_server/main.py,sha256=O9K6bznDv2QvBgWTSrnjqLwRoVRyBG9-AR8KjuJWE1M,1437
|
|
75
|
+
compass_server/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
76
|
+
compass_server/settings.py,sha256=GFgJTRK7Y0icLKgg53FyUlbILki101yuHC4ISZZbYhc,1543
|
|
77
|
+
compass_server/web_bundle.py,sha256=_miKsqgubeU_Swcx8Vg5GPLivVj_H-ZGaY_fkVtQ8tk,840
|
|
78
|
+
compass_server/web_limits.py,sha256=gmGP8CnpOouCNFSf2yfNJWsIKIZpRUaxG_JWK4j1LOY,1640
|
|
79
|
+
compass_server/routers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
80
|
+
compass_server/routers/query.py,sha256=mnhBBHYFjR-Lu-72Xi3lDcpVQjFar4MWWkz9ei_nRr4,6498
|
|
81
|
+
compass_server/static/404.html,sha256=xx5ek8k-8rmKLQY2mWnjQoOTTrO6cF6CY6Z__OFTMcU,8944
|
|
82
|
+
compass_server/static/index.html,sha256=0pNeobPgYfp1_7NoA8fipDvsgj5cUinRw9hrE-2EaTw,8837
|
|
83
|
+
compass_server/static/index.txt,sha256=TSPr0oaUdavPv7hF4tR0-AE7OJp_oP7TCuk4vNcjlN8,4917
|
|
84
|
+
compass_server/static/_next/static/chunks/1629039a.eed2a06658ec4f9c.js,sha256=CzwYPfFrw8P8JQYIqRjPOoUI9bjjsMGeJkhTQ72wYP8,325287
|
|
85
|
+
compass_server/static/_next/static/chunks/1ff282bf-bb7c483245264fc9.js,sha256=v36UjjYs-FTFbnbFaCOG9X8vjZIcmnDYxcFgd131cVw,173024
|
|
86
|
+
compass_server/static/_next/static/chunks/223.f881a22f446259bf.js,sha256=0B72j0iI_J2ksjZAXKJzQ0frU3TU3I6RIBPwRxfEOPQ,242122
|
|
87
|
+
compass_server/static/_next/static/chunks/51fa5c19.6396973222c9d6fd.js,sha256=LlR323CG2bbBFD7DKcoYEn-naLLHnZtlT8sQGPTouHU,615887
|
|
88
|
+
compass_server/static/_next/static/chunks/556.443c1682b6b20128.js,sha256=E01B1nCUGSXk6R5ufcxHON27xsaii-UP-Tej2btlN4Y,12512
|
|
89
|
+
compass_server/static/_next/static/chunks/684-1aa0170f59baf77e.js,sha256=fGIZoOayzSCMeA1LZ2yebfA1oSREDXNXVk885_GbxLY,643162
|
|
90
|
+
compass_server/static/_next/static/chunks/92e71660.3a42d4f70d017951.js,sha256=pApYdSv8vU-m31VwFmj-8jJAZDwh3n2tQw2wH0igQ90,356819
|
|
91
|
+
compass_server/static/_next/static/chunks/937-8692224bb6d1b605.js,sha256=fdiJJPvd7INYsAJKoJ7o04txhGNdAEOM2zhxUOgLUWQ,173207
|
|
92
|
+
compass_server/static/_next/static/chunks/framework-96dcd958cfe08bd4.js,sha256=aVpaPpZV0_FPiahM-SI4Mgj8toXHGxlCOP-ThrWHAxA,189785
|
|
93
|
+
compass_server/static/_next/static/chunks/main-6dee8e626b16731a.js,sha256=--C4B4IYTh1m6Ju77MDPdyvxeIVSmny7lfMPGKmRfu8,127924
|
|
94
|
+
compass_server/static/_next/static/chunks/main-app-460e8bc670818718.js,sha256=-zXnZGz9DsQnVjxS51Xp4SQ9J0QWNf_sc41Gm1fuyTY,569
|
|
95
|
+
compass_server/static/_next/static/chunks/polyfills-42372ed130431b0a.js,sha256=CXPB1kyIrcjjyVBBDLWLKI9yEY1ZZbeASUON648vloM,112594
|
|
96
|
+
compass_server/static/_next/static/chunks/webpack-597057bf48ce4111.js,sha256=8fUZdRdxkSDbh4vowE-E9L3fyJ-tC1IaX_snJzLOevk,3713
|
|
97
|
+
compass_server/static/_next/static/chunks/app/layout-4bd0ba4a7d18aff9.js,sha256=xIYQqZKBs1Se2ByHaVevd4895_8Ki2QiZ4LGpZb2i20,991
|
|
98
|
+
compass_server/static/_next/static/chunks/app/page-5376a0a98bbd1faa.js,sha256=4iwaIvueAxRBjxc96iLPeyS8PPB4Uxg-yp0Pw0ryBxo,91866
|
|
99
|
+
compass_server/static/_next/static/chunks/app/_not-found/page-2c96ddf295eb6a86.js,sha256=53bragw1qG3uwojbLK45JWTExwp3pgofBhuZpgHWNJY,2680
|
|
100
|
+
compass_server/static/_next/static/chunks/pages/_app-638a3e7363f92b80.js,sha256=J0xoqYN9AaBB2ZCzKOERq1xoejbtN95S046ubjJNCuQ,239
|
|
101
|
+
compass_server/static/_next/static/chunks/pages/_error-6a72dbbb45cae743.js,sha256=oVBW5enTs3OVGsSJZ5_Sh7ItTkD2qaKyn60urQFjDxc,221
|
|
102
|
+
compass_server/static/_next/static/css/1b0fbfd8dd653f37.css,sha256=6VPo2Lz-UXQ8iAAiUxTF2-gXWOxB0R1DKUKnjkj4joM,77188
|
|
103
|
+
compass_server/static/_next/static/ctUZeD9K7jQUgLqmBas2L/_buildManifest.js,sha256=JL8CFWQG0GDopX39z0HQhfbSBn_QYSeaxQAoXOEcBLk,506
|
|
104
|
+
compass_server/static/_next/static/ctUZeD9K7jQUgLqmBas2L/_ssgManifest.js,sha256=Z49s4suAsf5y_GfnQSvm4qtq2ggxEbZPfEDTXjy6XgA,80
|
|
105
|
+
compass_server/static/_next/static/media/0086f8992871c45b-s.woff2,sha256=ZuG4x8ScKDWJ7JAWdL_zaIujYyDK1MKe6cz00Do6KCA,21252
|
|
106
|
+
compass_server/static/_next/static/media/034d78ad42e9620c-s.woff2,sha256=I2F6G_Zn3Wop4nJKxlledZJFSdHCXoZy4jRu84vJmEo,39504
|
|
107
|
+
compass_server/static/_next/static/media/03b436aa846269de-s.woff2,sha256=0NNYz8z88OMGB9ig3HrOCAkIfzONfx80okR94Nqqw3U,23588
|
|
108
|
+
compass_server/static/_next/static/media/0484562807a97172-s.p.woff2,sha256=hy6GKRhZGp6CTcA-2S8FcpQ1_7uOu7EO_37aJlkrF5g,7992
|
|
109
|
+
compass_server/static/_next/static/media/08aedeceaf1dcd57-s.woff2,sha256=VWBvvHbcIyxb6471hNe09_duManyeHcRLnVIQ1ZGJ4E,20176
|
|
110
|
+
compass_server/static/_next/static/media/0aa834ed78bf6d07-s.woff2,sha256=r3SGlViAvhwrly6cdmrP-3dnaNZptldu2aCRnOcufKY,12064
|
|
111
|
+
compass_server/static/_next/static/media/29a4aea02fdee119-s.woff2,sha256=briALXMZ_NSIUOs45B7W6hLZF_qv36x9rlYUpRfcK1Q,39204
|
|
112
|
+
compass_server/static/_next/static/media/29e7bbdce9332268-s.woff2,sha256=bY70Ir5NgnA39vLVdmoICAGIdvpemqmpJ4f62dHxeTg,39384
|
|
113
|
+
compass_server/static/_next/static/media/36008747766f78c6-s.woff2,sha256=Nn317QKwguP62WFcVPVqorU4gzElessivmDHwKYI5kc,17280
|
|
114
|
+
compass_server/static/_next/static/media/39969fcf98a3026e-s.woff2,sha256=eOhQ1WmDSJLT9L39IITHp8DcZK5CJvMjGvMNrnBkAOI,3028
|
|
115
|
+
compass_server/static/_next/static/media/4de1fea1a954a5b6-s.p.woff2,sha256=1K5RiKZTcOz-KPQik7vugpfP1XEsaq39snDUjyvNiLA,13980
|
|
116
|
+
compass_server/static/_next/static/media/5c0c2bcbaa4149ca-s.p.woff2,sha256=axAqs1qh8rMVeIu0hTQ07R5SE3YDv3o9pxpoInZ0jUU,37792
|
|
117
|
+
compass_server/static/_next/static/media/67957d42bae0796d-s.woff2,sha256=Pt82Pb-dX6DNx4SuK0MaikFS9AVaiohYAowL1miAgnM,9084
|
|
118
|
+
compass_server/static/_next/static/media/6d38f9d4e0f4772b-s.woff2,sha256=qRSdr4LKX-8cEr3uSSdJ9JPC4uQxN2py-58DXmcGRXM,8908
|
|
119
|
+
compass_server/static/_next/static/media/6d664cce900333ee-s.p.woff2,sha256=enzho08-mUT-iPxhq7yTtts4OvorkIFf18zqRW-85OU,14168
|
|
120
|
+
compass_server/static/_next/static/media/886030b0b59bc5a7-s.woff2,sha256=mS7qL3AhBFfd0Rlt5N8yQJGf_gaK0YjHnZhfukVl078,2020
|
|
121
|
+
compass_server/static/_next/static/media/8888a3826f4a3af4-s.p.woff2,sha256=KJ4K_IvnMahoIjSeVFVylvFFkmSWvSE42xusDbd_d6I,7740
|
|
122
|
+
compass_server/static/_next/static/media/939c4f875ee75fbb-s.woff2,sha256=fbev-84f3uacH_wmQbvKKJsEmGf1JMnYYf41q2Zwvyk,15204
|
|
123
|
+
compass_server/static/_next/static/media/a1386beebedccca4-s.woff2,sha256=JHdoOksSAGgHgKdZzBuTuBZBA2LcX0x06_6vohK8t00,5448
|
|
124
|
+
compass_server/static/_next/static/media/ab00a911ac2adf48-s.woff2,sha256=j9lctmxT1fJjcHurU2RDdFb_wtW7eA56zobNVtWBgj4,29236
|
|
125
|
+
compass_server/static/_next/static/media/b957ea75a84b6ea7-s.p.woff2,sha256=GXo8vXKQwkLFx2UmjN1pqaOYZ_3IDNEwcfJDqBxW-3Y,7848
|
|
126
|
+
compass_server/static/_next/static/media/bb3ef058b751a6ad-s.p.woff2,sha256=HgZ0CgKkQ_t_Pu2o_KpoWg9sYg4_AeZmboRylUac460,40480
|
|
127
|
+
compass_server/static/_next/static/media/c3bc380753a8436c-s.woff2,sha256=cu_Goyz9N8VXEIYoz_oBFTxIDD1M3lVnREBuULnY6fc,5552
|
|
128
|
+
compass_server/static/_next/static/media/cce080f35d014443-s.woff2,sha256=uFyExlW8u6O9YossH-oPvbWxWKkCIoGi-RDoL9baUJg,2988
|
|
129
|
+
compass_server/static/_next/static/media/db911767852bc875-s.woff2,sha256=nIxH7grqotN49OXVcZ7L8FpgGjXChdDUi4iBBrsVz0k,39160
|
|
130
|
+
compass_server/static/_next/static/media/eafabf029ad39a43-s.p.woff2,sha256=PcXQxSQo_haWJkkHoQVOu6rAf4y-RYMsEF-BnCrjl8A,7900
|
|
131
|
+
compass_server/static/_next/static/media/f10b8e9d91f3edcb-s.woff2,sha256=-PDChmHIjtvO4CKkqAZXYZ6JMa-MKkfCjiMDB-KvMOU,5496
|
|
132
|
+
compass_server/static/_next/static/media/f911b923c6adde36-s.woff2,sha256=E5DobMKCPnWTWJGMAcT8wbbk8BvKkVvb621o61wkRAU,7468
|
|
133
|
+
compass_server/static/_next/static/media/fe0777f1195381cb-s.woff2,sha256=H65ec9J4juHeodduyjqfFXoDht5r6MKA0HalOmTDWKE,5640
|
|
134
|
+
compass_code-0.1.0.dist-info/METADATA,sha256=2ZzAwOOZfZkM2LEhqJAme5blg3cu_v8pzcHGk3tKKCw,2694
|
|
135
|
+
compass_code-0.1.0.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
|
|
136
|
+
compass_code-0.1.0.dist-info/entry_points.txt,sha256=tY_5a4mMnxtpCok7wP4zOHzpuKTJoaKsNL9LGOot9fs,49
|
|
137
|
+
compass_code-0.1.0.dist-info/RECORD,,
|
compass_core/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Code Compass – core engine."""
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"""Public contract of the query engine: the types every adapter sends and receives.
|
|
2
|
+
|
|
3
|
+
Plain frozen dataclasses and enums with no database, I/O or adapter imports. The
|
|
4
|
+
query layer builds these values; the CLI, the MCP server and the HTTP server consume
|
|
5
|
+
them. Only ``serialize.py`` uses Pydantic, to turn them into JSON.
|
|
6
|
+
"""
|