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,152 @@
|
|
|
1
|
+
"""Orchestrates the 6 phases through IngestContext. Enables
|
|
2
|
+
`compass ingest --stop-after <phase>` for debugging."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import logging
|
|
7
|
+
import os
|
|
8
|
+
import shutil
|
|
9
|
+
import subprocess
|
|
10
|
+
from collections.abc import Callable
|
|
11
|
+
from datetime import UTC, datetime
|
|
12
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
from compass_core.graph.db import GraphDB
|
|
16
|
+
from compass_core.graph.schema import create_schema
|
|
17
|
+
from compass_core.index.locate import metadata_path_for
|
|
18
|
+
from compass_core.index.metadata import SCHEMA_VERSION, IndexMetadata, save_metadata
|
|
19
|
+
from compass_core.phases.base import IngestContext, Phase
|
|
20
|
+
from compass_core.phases.discovery import DiscoveryPhase
|
|
21
|
+
from compass_core.phases.parse import ParsePhase
|
|
22
|
+
from compass_core.phases.persistence import PersistencePhase
|
|
23
|
+
from compass_core.phases.resolution import ResolutionPhase
|
|
24
|
+
from compass_core.phases.symbol_table import SymbolTablePhase
|
|
25
|
+
from compass_core.phases.validation import ValidationPhase
|
|
26
|
+
from compass_core.progress import ProgressReporter
|
|
27
|
+
from compass_core.shared_types import Language
|
|
28
|
+
|
|
29
|
+
logger = logging.getLogger(__name__)
|
|
30
|
+
|
|
31
|
+
_PHASE_ORDER = ["discovery", "parse", "symbol_table", "resolution", "validation", "persistence"]
|
|
32
|
+
|
|
33
|
+
_GRAMMAR_PACKAGES: dict[Language, str] = {
|
|
34
|
+
Language.PYTHON: "tree-sitter-python",
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class Pipeline:
|
|
39
|
+
def __init__(self, *, max_workers: int | None = None) -> None:
|
|
40
|
+
self._max_workers = max_workers
|
|
41
|
+
|
|
42
|
+
def run(
|
|
43
|
+
self,
|
|
44
|
+
repo_root: Path,
|
|
45
|
+
db_path: Path,
|
|
46
|
+
*,
|
|
47
|
+
reporter: ProgressReporter | None = None,
|
|
48
|
+
stop_after: str | None = None,
|
|
49
|
+
on_phase_complete: Callable[[str, IngestContext], None] | None = None,
|
|
50
|
+
) -> IngestContext:
|
|
51
|
+
# Stamp the index with the time the ingest STARTS: a file edited while a long
|
|
52
|
+
# ingest runs has a later mtime and is reported stale, not silently trusted.
|
|
53
|
+
started_at = datetime.now(UTC)
|
|
54
|
+
ctx = IngestContext(repo_root=repo_root, reporter=reporter)
|
|
55
|
+
|
|
56
|
+
phases: dict[str, Phase] = {
|
|
57
|
+
"discovery": DiscoveryPhase(),
|
|
58
|
+
"parse": ParsePhase(max_workers=self._max_workers),
|
|
59
|
+
"symbol_table": SymbolTablePhase(),
|
|
60
|
+
"resolution": ResolutionPhase(),
|
|
61
|
+
"validation": ValidationPhase(),
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
for phase_name in _PHASE_ORDER:
|
|
65
|
+
if phase_name == "persistence":
|
|
66
|
+
break
|
|
67
|
+
ctx = phases[phase_name].run(ctx)
|
|
68
|
+
if on_phase_complete is not None:
|
|
69
|
+
on_phase_complete(phase_name, ctx)
|
|
70
|
+
if stop_after == phase_name:
|
|
71
|
+
return ctx
|
|
72
|
+
|
|
73
|
+
db_path.parent.mkdir(parents=True, exist_ok=True)
|
|
74
|
+
building = db_path.with_name(db_path.name + ".building")
|
|
75
|
+
_remove_db(building)
|
|
76
|
+
try:
|
|
77
|
+
with GraphDB(building) as db:
|
|
78
|
+
create_schema(db)
|
|
79
|
+
ctx = PersistencePhase().run(ctx, db)
|
|
80
|
+
os.replace(building, db_path)
|
|
81
|
+
except BaseException:
|
|
82
|
+
_remove_db(building)
|
|
83
|
+
raise
|
|
84
|
+
if on_phase_complete is not None:
|
|
85
|
+
on_phase_complete("persistence", ctx)
|
|
86
|
+
|
|
87
|
+
_save_metadata(repo_root, metadata_path_for(db_path), started_at)
|
|
88
|
+
return ctx
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _remove_db(path: Path) -> None:
|
|
92
|
+
"""Delete a LadybugDB file or directory plus its write-ahead log, if present.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
path: The database path; sibling files named ``<path>.wal`` are removed too.
|
|
96
|
+
"""
|
|
97
|
+
for candidate in (path, path.with_name(path.name + ".wal")):
|
|
98
|
+
if candidate.is_dir():
|
|
99
|
+
shutil.rmtree(candidate)
|
|
100
|
+
elif candidate.exists():
|
|
101
|
+
candidate.unlink()
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def _save_metadata(repo_path: Path, metadata_path: Path, indexed_at: datetime) -> None:
|
|
105
|
+
"""Write the index metadata (commit, time, grammar versions) via IndexMetadata.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
repo_path: Repository root, used for the git commit.
|
|
109
|
+
metadata_path: Destination beside the database (``metadata_path_for``), so
|
|
110
|
+
``require_index(..., override=db_path)`` finds it; for the default
|
|
111
|
+
database this is ``<repo>/.compass/metadata.json``.
|
|
112
|
+
indexed_at: When the ingest started (taken before discovery).
|
|
113
|
+
"""
|
|
114
|
+
commit = _get_git_commit(repo_path)
|
|
115
|
+
meta = IndexMetadata(
|
|
116
|
+
indexed_commit=None if commit == "unknown" else commit,
|
|
117
|
+
indexed_at=indexed_at,
|
|
118
|
+
schema_version=SCHEMA_VERSION,
|
|
119
|
+
grammar_versions=_grammar_versions(),
|
|
120
|
+
)
|
|
121
|
+
save_metadata(metadata_path, meta)
|
|
122
|
+
logger.debug("Metadata written: %s", meta)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def _get_git_commit(repo_path: Path) -> str:
|
|
126
|
+
"""Return the HEAD commit hash, or 'unknown' on any failure."""
|
|
127
|
+
try:
|
|
128
|
+
result = subprocess.run(
|
|
129
|
+
["git", "rev-parse", "HEAD"],
|
|
130
|
+
cwd=repo_path,
|
|
131
|
+
capture_output=True,
|
|
132
|
+
text=True,
|
|
133
|
+
timeout=5,
|
|
134
|
+
)
|
|
135
|
+
if result.returncode == 0:
|
|
136
|
+
return result.stdout.strip()
|
|
137
|
+
except (FileNotFoundError, subprocess.TimeoutExpired, OSError):
|
|
138
|
+
pass
|
|
139
|
+
return "unknown"
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def _grammar_versions() -> dict[Language, str]:
|
|
143
|
+
"""Pin the installed grammar package version for every registered
|
|
144
|
+
language — an unpinned grammar version means incremental diffing would
|
|
145
|
+
trust stale data unknowingly."""
|
|
146
|
+
versions: dict[Language, str] = {}
|
|
147
|
+
for language_id, package in _GRAMMAR_PACKAGES.items():
|
|
148
|
+
try:
|
|
149
|
+
versions[language_id] = version(package)
|
|
150
|
+
except PackageNotFoundError:
|
|
151
|
+
continue
|
|
152
|
+
return versions
|