sourcecode 1.32.6__tar.gz → 1.32.7__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.
- {sourcecode-1.32.6 → sourcecode-1.32.7}/PKG-INFO +1 -1
- {sourcecode-1.32.6 → sourcecode-1.32.7}/pyproject.toml +1 -1
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/__init__.py +1 -1
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/cli.py +21 -1
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/prepare_context.py +77 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/ris.py +13 -2
- {sourcecode-1.32.6 → sourcecode-1.32.7}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/.gitignore +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/.ruff.toml +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/CHANGELOG.md +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/CONTRIBUTING.md +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/LICENSE +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/README.md +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/SECURITY.md +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/raw +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/cache.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/cache.tmp_new +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/canonical_ir.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/classifier.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/confidence_analyzer.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/contract_pipeline.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/file_classifier.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/flow_analyzer.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/license.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/mcp/__init__.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/mcp/onboarding/applier.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/mcp/onboarding/backup.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/mcp/onboarding/detector.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/mcp/onboarding/planner.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/mcp/runner.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/mcp/server.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/mcp_nudge.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/output_budget.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/path_filters.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/pr_comment_renderer.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/progress.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/ranking_engine.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/redactor.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/repository_ir.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/scanner.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/schema.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/serializer.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-1.32.6 → sourcecode-1.32.7}/src/sourcecode/workspace.py +0 -0
|
@@ -3753,6 +3753,24 @@ def config_cmd() -> None:
|
|
|
3753
3753
|
typer.echo(" sourcecode telemetry status")
|
|
3754
3754
|
|
|
3755
3755
|
|
|
3756
|
+
# ── cold-start (RIS bootstrap for external MCP and agents) ───────────────────
|
|
3757
|
+
|
|
3758
|
+
@app.command("cold-start")
|
|
3759
|
+
def cold_start_cmd(
|
|
3760
|
+
path: Path = typer.Argument(Path("."), help="Repository path (default: current directory)"),
|
|
3761
|
+
) -> None:
|
|
3762
|
+
"""Output Repository Intelligence Snapshot bootstrap context as JSON.
|
|
3763
|
+
|
|
3764
|
+
Returns instantly from persisted RIS — zero re-analysis cost.
|
|
3765
|
+
status: cold_start_ready | cold_start_stale | no_ris
|
|
3766
|
+
"""
|
|
3767
|
+
import json as _json
|
|
3768
|
+
from sourcecode.ris import get_cold_start_context as _gcs
|
|
3769
|
+
target = Path(path).resolve()
|
|
3770
|
+
result = _gcs(target)
|
|
3771
|
+
typer.echo(_json.dumps(result, indent=2, ensure_ascii=False))
|
|
3772
|
+
|
|
3773
|
+
|
|
3756
3774
|
# ── analyze (legacy alias) ────────────────────────────────────────────────────
|
|
3757
3775
|
|
|
3758
3776
|
@app.command("analyze", hidden=True)
|
|
@@ -4207,11 +4225,13 @@ def cache_warm_cmd(
|
|
|
4207
4225
|
agent: bool = typer.Option(False, "--agent", help="Also warm agent view."),
|
|
4208
4226
|
) -> None:
|
|
4209
4227
|
"""Pre-populate the cache by running a fresh analysis."""
|
|
4228
|
+
import shutil as _shutil
|
|
4210
4229
|
import subprocess as _sub
|
|
4211
4230
|
import sys as _sys
|
|
4212
4231
|
target = Path(path).resolve()
|
|
4213
4232
|
typer.echo(f"Warming cache for {target} …", err=True)
|
|
4214
|
-
|
|
4233
|
+
_sc_bin = _shutil.which("sourcecode") or _sys.argv[0]
|
|
4234
|
+
cmd = [_sc_bin, str(target)]
|
|
4215
4235
|
if compact:
|
|
4216
4236
|
cmd.append("--compact")
|
|
4217
4237
|
if agent:
|
|
@@ -734,6 +734,77 @@ class TaskContextBuilder:
|
|
|
734
734
|
def __init__(self, root: Path) -> None:
|
|
735
735
|
self.root = root
|
|
736
736
|
|
|
737
|
+
# ------------------------------------------------------------------
|
|
738
|
+
# RIS fast-path: serve onboard/explain from warm snapshot (<50ms)
|
|
739
|
+
# ------------------------------------------------------------------
|
|
740
|
+
|
|
741
|
+
def _try_ris_fast_path(self, task_name: str, spec: "TaskSpec") -> Optional[TaskOutput]:
|
|
742
|
+
"""Return TaskOutput from a warm RIS without running the full scan.
|
|
743
|
+
|
|
744
|
+
Only activated for onboard/explain when git HEAD matches stored RIS.
|
|
745
|
+
Falls through (returns None) on any error or cache miss.
|
|
746
|
+
"""
|
|
747
|
+
try:
|
|
748
|
+
import subprocess as _sp
|
|
749
|
+
from sourcecode.ris import load_ris as _lris
|
|
750
|
+
_ris = _lris(self.root)
|
|
751
|
+
if _ris is None or not _ris.compact_summary:
|
|
752
|
+
return None
|
|
753
|
+
_r = _sp.run(
|
|
754
|
+
["git", "-C", str(self.root), "rev-parse", "--short", "HEAD"],
|
|
755
|
+
capture_output=True, text=True, timeout=2,
|
|
756
|
+
)
|
|
757
|
+
if _r.returncode != 0 or _r.stdout.strip() != _ris.git_head:
|
|
758
|
+
return None
|
|
759
|
+
|
|
760
|
+
compact = _ris.compact_summary
|
|
761
|
+
struct = _ris.structural_map
|
|
762
|
+
|
|
763
|
+
entry_points = struct.get("entrypoints") or compact.get("entry_points") or []
|
|
764
|
+
controllers = struct.get("controllers") or []
|
|
765
|
+
services = struct.get("services") or []
|
|
766
|
+
|
|
767
|
+
_seen: set = set()
|
|
768
|
+
relevant: list[RelevantFile] = []
|
|
769
|
+
for fp in entry_points[:10]:
|
|
770
|
+
if isinstance(fp, str) and fp not in _seen:
|
|
771
|
+
_seen.add(fp)
|
|
772
|
+
relevant.append(RelevantFile(path=fp, role="entrypoint", score=1.0, reason="entry_point", why="Primary entry point"))
|
|
773
|
+
for fp in controllers[:8]:
|
|
774
|
+
if isinstance(fp, str) and fp not in _seen:
|
|
775
|
+
_seen.add(fp)
|
|
776
|
+
relevant.append(RelevantFile(path=fp, role="source", score=0.9, reason="controller", why="Controller"))
|
|
777
|
+
for fp in services[:8]:
|
|
778
|
+
if isinstance(fp, str) and fp not in _seen:
|
|
779
|
+
_seen.add(fp)
|
|
780
|
+
relevant.append(RelevantFile(path=fp, role="source", score=0.8, reason="service", why="Service layer"))
|
|
781
|
+
|
|
782
|
+
# compact_summary uses "analysis_gaps" (list[dict]) not "gaps" (list[str])
|
|
783
|
+
_raw_gaps = compact.get("gaps") or compact.get("analysis_gaps") or []
|
|
784
|
+
_gap_strs: list[str] = [
|
|
785
|
+
g.get("reason", str(g)) if isinstance(g, dict) else str(g)
|
|
786
|
+
for g in _raw_gaps
|
|
787
|
+
if g
|
|
788
|
+
]
|
|
789
|
+
|
|
790
|
+
return TaskOutput(
|
|
791
|
+
task=task_name,
|
|
792
|
+
goal=spec.goal,
|
|
793
|
+
project_summary=compact.get("project_summary") or compact.get("summary"),
|
|
794
|
+
architecture_summary=compact.get("architecture_summary"),
|
|
795
|
+
relevant_files=relevant,
|
|
796
|
+
suspected_areas=[],
|
|
797
|
+
improvement_opportunities=[],
|
|
798
|
+
test_gaps=[],
|
|
799
|
+
key_dependencies=compact.get("key_dependencies") or [],
|
|
800
|
+
code_notes_summary=None,
|
|
801
|
+
limitations=[],
|
|
802
|
+
confidence=compact.get("confidence") or compact.get("confidence_summary") or "high",
|
|
803
|
+
gaps=_gap_strs,
|
|
804
|
+
)
|
|
805
|
+
except Exception:
|
|
806
|
+
return None
|
|
807
|
+
|
|
737
808
|
def build(self, task_name: str, *, since: Optional[str] = None, symptom: Optional[str] = None, fast: bool = False, include_config: bool = False, all_gaps: bool = False) -> TaskOutput:
|
|
738
809
|
if task_name not in TASKS:
|
|
739
810
|
raise ValueError(
|
|
@@ -741,6 +812,12 @@ class TaskContextBuilder:
|
|
|
741
812
|
)
|
|
742
813
|
spec = TASKS[task_name]
|
|
743
814
|
|
|
815
|
+
# ── RIS fast-path (onboard / explain only) ────────────────────────────
|
|
816
|
+
if task_name in ("onboard", "explain") and not fast:
|
|
817
|
+
_warm = self._try_ris_fast_path(task_name, spec)
|
|
818
|
+
if _warm is not None:
|
|
819
|
+
return _warm
|
|
820
|
+
|
|
744
821
|
# ── 0. review-pr: git-first scope resolution (before any filesystem scan) ─
|
|
745
822
|
_pr_git_root: Optional[Path] = None
|
|
746
823
|
_pr_scope_files: Optional[list[str]] = None
|
|
@@ -362,7 +362,8 @@ def get_cold_start_context(repo_root: Path) -> dict:
|
|
|
362
362
|
current_head = _current_git_head(repo_root)
|
|
363
363
|
stale = bool(current_head and ris.git_head and current_head != ris.git_head)
|
|
364
364
|
|
|
365
|
-
|
|
365
|
+
endpoints = ris.api_surface.get("endpoints", [])
|
|
366
|
+
result: dict = {
|
|
366
367
|
"status": "cold_start_stale" if stale else "cold_start_ready",
|
|
367
368
|
"repo_id": ris.repo_id,
|
|
368
369
|
"git_head": ris.git_head,
|
|
@@ -370,8 +371,18 @@ def get_cold_start_context(repo_root: Path) -> dict:
|
|
|
370
371
|
"last_updated_at": ris.last_updated_at,
|
|
371
372
|
"summary": ris.compact_summary,
|
|
372
373
|
"entrypoints": ris.structural_map.get("entrypoints", []),
|
|
373
|
-
"endpoints":
|
|
374
|
+
"endpoints": endpoints,
|
|
374
375
|
"hotspots": ris.git_context_snapshot.get("hotspots", []),
|
|
375
376
|
}
|
|
377
|
+
if not endpoints:
|
|
378
|
+
_is_java = (repo_root / "pom.xml").exists() or \
|
|
379
|
+
(repo_root / "build.gradle").exists() or \
|
|
380
|
+
(repo_root / "build.gradle.kts").exists()
|
|
381
|
+
if _is_java:
|
|
382
|
+
result["endpoints_hint"] = (
|
|
383
|
+
"Java repo detected but no endpoint index found. "
|
|
384
|
+
"Call get_endpoints (or: sourcecode endpoints <path>) to populate."
|
|
385
|
+
)
|
|
386
|
+
return result
|
|
376
387
|
except Exception:
|
|
377
388
|
return {"status": "no_ris"}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|