sourcecode 1.33.15__tar.gz → 1.33.17__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 (95) hide show
  1. {sourcecode-1.33.15 → sourcecode-1.33.17}/PKG-INFO +2 -2
  2. {sourcecode-1.33.15 → sourcecode-1.33.17}/README.md +1 -1
  3. {sourcecode-1.33.15 → sourcecode-1.33.17}/pyproject.toml +1 -1
  4. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/__init__.py +1 -1
  5. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/cli.py +20 -4
  6. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/mcp/runner.py +5 -4
  7. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/mcp/server.py +50 -1
  8. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/prepare_context.py +6 -0
  9. {sourcecode-1.33.15 → sourcecode-1.33.17}/.github/workflows/build-windows.yml +0 -0
  10. {sourcecode-1.33.15 → sourcecode-1.33.17}/.gitignore +0 -0
  11. {sourcecode-1.33.15 → sourcecode-1.33.17}/.ruff.toml +0 -0
  12. {sourcecode-1.33.15 → sourcecode-1.33.17}/CHANGELOG.md +0 -0
  13. {sourcecode-1.33.15 → sourcecode-1.33.17}/CONTRIBUTING.md +0 -0
  14. {sourcecode-1.33.15 → sourcecode-1.33.17}/LICENSE +0 -0
  15. {sourcecode-1.33.15 → sourcecode-1.33.17}/SECURITY.md +0 -0
  16. {sourcecode-1.33.15 → sourcecode-1.33.17}/raw +0 -0
  17. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/adaptive_scanner.py +0 -0
  18. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/architecture_analyzer.py +0 -0
  19. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/architecture_summary.py +0 -0
  20. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/ast_extractor.py +0 -0
  21. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/cache.py +0 -0
  22. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/canonical_ir.py +0 -0
  23. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/classifier.py +0 -0
  24. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/code_notes_analyzer.py +0 -0
  25. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/confidence_analyzer.py +0 -0
  26. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/context_scorer.py +0 -0
  27. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/context_summarizer.py +0 -0
  28. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/contract_model.py +0 -0
  29. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/contract_pipeline.py +0 -0
  30. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/coverage_parser.py +0 -0
  31. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/dependency_analyzer.py +0 -0
  32. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/detectors/__init__.py +0 -0
  33. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/detectors/base.py +0 -0
  34. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/detectors/csproj_parser.py +0 -0
  35. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/detectors/dart.py +0 -0
  36. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/detectors/dotnet.py +0 -0
  37. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/detectors/elixir.py +0 -0
  38. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/detectors/go.py +0 -0
  39. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/detectors/heuristic.py +0 -0
  40. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/detectors/hybrid.py +0 -0
  41. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/detectors/java.py +0 -0
  42. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/detectors/jvm_ext.py +0 -0
  43. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/detectors/nodejs.py +0 -0
  44. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/detectors/parsers.py +0 -0
  45. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/detectors/php.py +0 -0
  46. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/detectors/project.py +0 -0
  47. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/detectors/python.py +0 -0
  48. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/detectors/ruby.py +0 -0
  49. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/detectors/rust.py +0 -0
  50. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/detectors/systems.py +0 -0
  51. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/detectors/terraform.py +0 -0
  52. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/detectors/tooling.py +0 -0
  53. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/doc_analyzer.py +0 -0
  54. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/entrypoint_classifier.py +0 -0
  55. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/env_analyzer.py +0 -0
  56. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/error_schema.py +0 -0
  57. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/file_classifier.py +0 -0
  58. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/flow_analyzer.py +0 -0
  59. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/git_analyzer.py +0 -0
  60. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/graph_analyzer.py +0 -0
  61. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/license.py +0 -0
  62. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/mcp/__init__.py +0 -0
  63. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
  64. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/mcp/onboarding/applier.py +0 -0
  65. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/mcp/onboarding/backup.py +0 -0
  66. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/mcp/onboarding/detector.py +0 -0
  67. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/mcp/onboarding/planner.py +0 -0
  68. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/mcp/orchestrator.py +0 -0
  69. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/mcp/registry.py +0 -0
  70. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/mcp_nudge.py +0 -0
  71. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/metrics_analyzer.py +0 -0
  72. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/output_budget.py +0 -0
  73. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/path_filters.py +0 -0
  74. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/pr_comment_renderer.py +0 -0
  75. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/progress.py +0 -0
  76. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/ranking_engine.py +0 -0
  77. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/redactor.py +0 -0
  78. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/relevance_scorer.py +0 -0
  79. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/repo_classifier.py +0 -0
  80. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/repository_ir.py +0 -0
  81. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/ris.py +0 -0
  82. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/runtime_classifier.py +0 -0
  83. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/scanner.py +0 -0
  84. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/schema.py +0 -0
  85. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/semantic_analyzer.py +0 -0
  86. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/serializer.py +0 -0
  87. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/summarizer.py +0 -0
  88. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/telemetry/__init__.py +0 -0
  89. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/telemetry/config.py +0 -0
  90. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/telemetry/consent.py +0 -0
  91. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/telemetry/events.py +0 -0
  92. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/telemetry/filters.py +0 -0
  93. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/telemetry/transport.py +0 -0
  94. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/tree_utils.py +0 -0
  95. {sourcecode-1.33.15 → sourcecode-1.33.17}/src/sourcecode/workspace.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sourcecode
3
- Version: 1.33.15
3
+ Version: 1.33.17
4
4
  Summary: Persistent structural context and ultra-fast repeated analysis for AI coding agents
5
5
  License-File: LICENSE
6
6
  Keywords: agents,ai,codebase,context,developer-tools,llm
@@ -39,7 +39,7 @@ Description-Content-Type: text/markdown
39
39
 
40
40
  **Persistent structural context and ultra-fast repeated analysis for AI coding agents.**
41
41
 
42
- ![Version](https://img.shields.io/badge/version-1.33.12-blue)
42
+ ![Version](https://img.shields.io/badge/version-1.33.17-blue)
43
43
  ![Python](https://img.shields.io/badge/python-3.10%2B-green)
44
44
 
45
45
  ---
@@ -2,7 +2,7 @@
2
2
 
3
3
  **Persistent structural context and ultra-fast repeated analysis for AI coding agents.**
4
4
 
5
- ![Version](https://img.shields.io/badge/version-1.33.12-blue)
5
+ ![Version](https://img.shields.io/badge/version-1.33.17-blue)
6
6
  ![Python](https://img.shields.io/badge/python-3.10%2B-green)
7
7
 
8
8
  ---
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "sourcecode"
7
- version = "1.33.15"
7
+ version = "1.33.17"
8
8
  description = "Persistent structural context and ultra-fast repeated analysis for AI coding agents"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -1,3 +1,3 @@
1
1
  """sourcecode — Deterministic codebase context maps for AI coding agents."""
2
2
 
3
- __version__ = "1.33.15"
3
+ __version__ = "1.33.17"
@@ -1141,9 +1141,23 @@ def main(
1141
1141
  capture_output=True, text=True, timeout=3,
1142
1142
  )
1143
1143
  _git_sha = _sha_r.stdout.strip()
1144
- # Only cache when target IS the git repo root (not a subdir of one),
1145
- # to avoid polluting sub-project directories used in tests.
1146
- if _git_sha and (target / ".git").exists():
1144
+
1145
+ # Detect actual git root (may be an ancestor of target for monorepos,
1146
+ # multi-project repos, or SVN-migrated trees where .git is in a parent).
1147
+ # The original "(target / '.git').exists()" check broke these layouts.
1148
+ _git_root_str = ""
1149
+ if _git_sha:
1150
+ try:
1151
+ _gr_r = _sub.run(
1152
+ ["git", "-C", str(target), "rev-parse", "--show-toplevel"],
1153
+ capture_output=True, text=True, timeout=3,
1154
+ )
1155
+ if _gr_r.returncode == 0:
1156
+ _git_root_str = _gr_r.stdout.strip()
1157
+ except Exception:
1158
+ pass
1159
+
1160
+ if _git_sha and _git_root_str:
1147
1161
  _excl_key = (
1148
1162
  ",".join(sorted(e.strip() for e in exclude.split(",") if e.strip()))
1149
1163
  if exclude else ""
@@ -2241,7 +2255,9 @@ def main(
2241
2255
  _atexit.register(_cache_write_thread.join, 5.0)
2242
2256
 
2243
2257
  # Update RIS with aggregated snapshot data (non-fatal side-effect).
2244
- if not no_cache and not _pipeline_error and _core_key:
2258
+ # Update RIS whenever git is available, even when L1/L2 cache is skipped
2259
+ # (e.g. target is a subdirectory of the git root — _core_key may be "").
2260
+ if not no_cache and not _pipeline_error and _git_sha:
2245
2261
  try:
2246
2262
  from sourcecode.serializer import core_view as _ris_core_view
2247
2263
  from sourcecode.ris import maybe_update_ris as _ris_update
@@ -39,11 +39,12 @@ def run_command(args: list[str]) -> Any:
39
39
  Returns parsed JSON dict when output is valid JSON, else the raw string.
40
40
  Raises CommandError on non-zero exit so MCP can preserve structured payloads.
41
41
  """
42
- from sourcecode.cli import _preprocess_args, _set_detected_path, app
42
+ from sourcecode.cli import app
43
43
 
44
- _set_detected_path(".")
45
- processed = _preprocess_args(list(args))
46
- result = _runner.invoke(app, processed)
44
+ # Pass raw args to invoke — the _cmd_main hook inside cli.py handles path
45
+ # extraction via _preprocess_args. Pre-processing here would strip the path
46
+ # from args, then _cmd_main would re-process the stripped list and lose it.
47
+ result = _runner.invoke(app, list(args))
47
48
 
48
49
  if result.exit_code != 0:
49
50
  stdout_raw = getattr(result, "output", "")
@@ -650,7 +650,56 @@ def check_freshness(repo_path: str = ".") -> dict:
650
650
  _path_err = _check_repo_path(repo_path)
651
651
  if _path_err is not None:
652
652
  return _path_err
653
- return _execute(["cache", "freshness", repo_path, "--json"])
653
+
654
+ # Call Python functions directly — avoids CliRunner/subprocess nesting
655
+ # that caused current_git_head to return "" on Windows parent-git repos.
656
+ import subprocess as _sp
657
+ from pathlib import Path as _Path
658
+ from sourcecode.cache import _get_git_head as _cache_head
659
+ from sourcecode.ris import load_ris as _load_ris, _has_uncommitted_changes as _huc
660
+
661
+ target = _Path(repo_path).resolve()
662
+ current_head = _cache_head(target)
663
+ ris = _load_ris(target)
664
+
665
+ if ris is None:
666
+ result: dict = {
667
+ "fresh": False,
668
+ "ris_exists": False,
669
+ "current_git_head": current_head,
670
+ "ris_git_head": None,
671
+ "delta_commits": None,
672
+ "has_uncommitted_changes": _huc(target),
673
+ "ris_last_updated_at": None,
674
+ }
675
+ else:
676
+ ris_head = ris.git_head
677
+ head_matches = bool(current_head and ris_head and current_head == ris_head)
678
+ uncommitted = _huc(target)
679
+ delta = None
680
+ if ris_head and current_head and ris_head != current_head:
681
+ try:
682
+ _r = _sp.run(
683
+ ["git", "-C", str(target), "rev-list", "--count", f"{ris_head}..HEAD"],
684
+ capture_output=True, text=True, timeout=5,
685
+ )
686
+ if _r.returncode == 0:
687
+ delta = int(_r.stdout.strip())
688
+ except Exception:
689
+ pass
690
+ elif head_matches:
691
+ delta = 0
692
+ result = {
693
+ "fresh": head_matches and not uncommitted,
694
+ "ris_exists": True,
695
+ "current_git_head": current_head,
696
+ "ris_git_head": ris_head,
697
+ "delta_commits": delta,
698
+ "has_uncommitted_changes": uncommitted,
699
+ "ris_last_updated_at": ris.last_updated_at,
700
+ }
701
+
702
+ return _ok(result)
654
703
  except Exception as exc:
655
704
  return _err(
656
705
  f"Internal error: {type(exc).__name__}: {exc} — repo_path: {_raw}",
@@ -1750,8 +1750,14 @@ class TaskContextBuilder:
1750
1750
  for _cr in _commits_scanned:
1751
1751
  _msg_lower = (_cr.message or "").lower()
1752
1752
  if _kw_re.search(_msg_lower):
1753
+ _rn_prefix = self.root.name + "/"
1753
1754
  for _cf in (_cr.files_changed or []):
1754
1755
  _cf_norm = _cf.replace("\\", "/")
1756
+ # Git reports paths relative to the git root, which may be
1757
+ # a parent of the analyzed directory (e.g. MSAS/saint-server/).
1758
+ # Strip the analyzed-dir prefix so paths match all_paths.
1759
+ if _cf_norm.startswith(_rn_prefix):
1760
+ _cf_norm = _cf_norm[len(_rn_prefix):]
1755
1761
  _commit_file_hits[_cf_norm] = _commit_file_hits.get(_cf_norm, 0) + 1
1756
1762
  _sx_commits.append({
1757
1763
  "message": (_cr.message or "")[:80],
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes