sourcecode 1.33.3__tar.gz → 1.33.4__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 (93) hide show
  1. {sourcecode-1.33.3 → sourcecode-1.33.4}/PKG-INFO +3 -3
  2. {sourcecode-1.33.3 → sourcecode-1.33.4}/README.md +2 -2
  3. {sourcecode-1.33.3 → sourcecode-1.33.4}/pyproject.toml +1 -1
  4. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/__init__.py +1 -1
  5. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/cli.py +26 -11
  6. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/prepare_context.py +4 -0
  7. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/ris.py +31 -2
  8. {sourcecode-1.33.3 → sourcecode-1.33.4}/.github/workflows/build-windows.yml +0 -0
  9. {sourcecode-1.33.3 → sourcecode-1.33.4}/.gitignore +0 -0
  10. {sourcecode-1.33.3 → sourcecode-1.33.4}/.ruff.toml +0 -0
  11. {sourcecode-1.33.3 → sourcecode-1.33.4}/CHANGELOG.md +0 -0
  12. {sourcecode-1.33.3 → sourcecode-1.33.4}/CONTRIBUTING.md +0 -0
  13. {sourcecode-1.33.3 → sourcecode-1.33.4}/LICENSE +0 -0
  14. {sourcecode-1.33.3 → sourcecode-1.33.4}/SECURITY.md +0 -0
  15. {sourcecode-1.33.3 → sourcecode-1.33.4}/raw +0 -0
  16. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/adaptive_scanner.py +0 -0
  17. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/architecture_analyzer.py +0 -0
  18. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/architecture_summary.py +0 -0
  19. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/ast_extractor.py +0 -0
  20. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/cache.py +0 -0
  21. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/cache.tmp_new +0 -0
  22. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/canonical_ir.py +0 -0
  23. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/classifier.py +0 -0
  24. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/code_notes_analyzer.py +0 -0
  25. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/confidence_analyzer.py +0 -0
  26. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/context_scorer.py +0 -0
  27. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/context_summarizer.py +0 -0
  28. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/contract_model.py +0 -0
  29. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/contract_pipeline.py +0 -0
  30. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/coverage_parser.py +0 -0
  31. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/dependency_analyzer.py +0 -0
  32. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/detectors/__init__.py +0 -0
  33. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/detectors/base.py +0 -0
  34. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/detectors/csproj_parser.py +0 -0
  35. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/detectors/dart.py +0 -0
  36. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/detectors/dotnet.py +0 -0
  37. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/detectors/elixir.py +0 -0
  38. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/detectors/go.py +0 -0
  39. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/detectors/heuristic.py +0 -0
  40. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/detectors/hybrid.py +0 -0
  41. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/detectors/java.py +0 -0
  42. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/detectors/jvm_ext.py +0 -0
  43. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/detectors/nodejs.py +0 -0
  44. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/detectors/parsers.py +0 -0
  45. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/detectors/php.py +0 -0
  46. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/detectors/project.py +0 -0
  47. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/detectors/python.py +0 -0
  48. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/detectors/ruby.py +0 -0
  49. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/detectors/rust.py +0 -0
  50. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/detectors/systems.py +0 -0
  51. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/detectors/terraform.py +0 -0
  52. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/detectors/tooling.py +0 -0
  53. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/doc_analyzer.py +0 -0
  54. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/entrypoint_classifier.py +0 -0
  55. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/env_analyzer.py +0 -0
  56. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/file_classifier.py +0 -0
  57. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/flow_analyzer.py +0 -0
  58. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/git_analyzer.py +0 -0
  59. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/graph_analyzer.py +0 -0
  60. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/license.py +0 -0
  61. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/mcp/__init__.py +0 -0
  62. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
  63. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/mcp/onboarding/applier.py +0 -0
  64. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/mcp/onboarding/backup.py +0 -0
  65. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/mcp/onboarding/detector.py +0 -0
  66. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/mcp/onboarding/planner.py +0 -0
  67. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/mcp/runner.py +0 -0
  68. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/mcp/server.py +0 -0
  69. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/mcp_nudge.py +0 -0
  70. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/metrics_analyzer.py +0 -0
  71. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/output_budget.py +0 -0
  72. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/path_filters.py +0 -0
  73. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/pr_comment_renderer.py +0 -0
  74. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/progress.py +0 -0
  75. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/ranking_engine.py +0 -0
  76. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/redactor.py +0 -0
  77. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/relevance_scorer.py +0 -0
  78. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/repo_classifier.py +0 -0
  79. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/repository_ir.py +0 -0
  80. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/runtime_classifier.py +0 -0
  81. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/scanner.py +0 -0
  82. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/schema.py +0 -0
  83. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/semantic_analyzer.py +0 -0
  84. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/serializer.py +0 -0
  85. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/summarizer.py +0 -0
  86. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/telemetry/__init__.py +0 -0
  87. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/telemetry/config.py +0 -0
  88. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/telemetry/consent.py +0 -0
  89. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/telemetry/events.py +0 -0
  90. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/telemetry/filters.py +0 -0
  91. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/telemetry/transport.py +0 -0
  92. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/tree_utils.py +0 -0
  93. {sourcecode-1.33.3 → sourcecode-1.33.4}/src/sourcecode/workspace.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sourcecode
3
- Version: 1.33.3
3
+ Version: 1.33.4
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.3-blue)
42
+ ![Version](https://img.shields.io/badge/version-1.33.4-blue)
43
43
  ![Python](https://img.shields.io/badge/python-3.10%2B-green)
44
44
 
45
45
  ---
@@ -113,7 +113,7 @@ pipx install sourcecode
113
113
 
114
114
  ```bash
115
115
  sourcecode version
116
- # sourcecode 1.33.3
116
+ # sourcecode 1.33.4
117
117
  ```
118
118
 
119
119
  ---
@@ -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.3-blue)
5
+ ![Version](https://img.shields.io/badge/version-1.33.4-blue)
6
6
  ![Python](https://img.shields.io/badge/python-3.10%2B-green)
7
7
 
8
8
  ---
@@ -76,7 +76,7 @@ pipx install sourcecode
76
76
 
77
77
  ```bash
78
78
  sourcecode version
79
- # sourcecode 1.33.3
79
+ # sourcecode 1.33.4
80
80
  ```
81
81
 
82
82
  ---
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "sourcecode"
7
- version = "1.33.3"
7
+ version = "1.33.4"
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.3"
3
+ __version__ = "1.33.4"
@@ -658,7 +658,6 @@ def main(
658
658
  env_map: bool = typer.Option(
659
659
  False,
660
660
  "--env-map",
661
- hidden=True,
662
661
  help="Map environment variables referenced across the codebase.",
663
662
  ),
664
663
  code_notes: bool = typer.Option(
@@ -1880,8 +1879,9 @@ def main(
1880
1879
  if _gc_early and not (_bad_gc & set(_gc_early.limitations)):
1881
1880
  _uc = _gc_early.uncommitted_changes
1882
1881
  if _uc:
1883
- # WORKTREE_UNSTAGED + WORKTREE_STAGED only; untracked excluded
1884
- _allowed_changed_files = set(_uc.staged) | set(_uc.unstaged)
1882
+ # Include untracked (new files not yet staged) so new source files
1883
+ # are analyzed under --changed-only, not silently treated as "clean".
1884
+ _allowed_changed_files = set(_uc.staged) | set(_uc.unstaged) | set(_uc.untracked)
1885
1885
  if not _allowed_changed_files:
1886
1886
  # Git is available and confirms no uncommitted changes.
1887
1887
  # Do NOT fall back to a full scan — that would silently produce
@@ -1900,10 +1900,10 @@ def main(
1900
1900
  changed_only = False
1901
1901
  if _git_confirmed_clean:
1902
1902
  _nc_payload = json.dumps({
1903
- "status": "working_tree_clean",
1904
- "no_changes": True,
1905
1903
  "changed_files": [],
1906
- "message": "No uncommitted changes detected — working tree is clean.",
1904
+ "message": "no uncommitted changes detected",
1905
+ "analysis_scope": "empty",
1906
+ "_meta": {"changed_only": True},
1907
1907
  }, ensure_ascii=False)
1908
1908
  write_output(_nc_payload, output=output)
1909
1909
  raise typer.Exit()
@@ -2626,7 +2626,14 @@ def prepare_context_cmd(
2626
2626
  if _task_include("improvement_opportunities") and output.improvement_opportunities:
2627
2627
  out["improvement_opportunities"] = output.improvement_opportunities
2628
2628
  if _task_include("test_gaps") and output.test_gaps:
2629
- out["test_gaps"] = output.test_gaps
2629
+ # Emit both the canonical name (untested_sources) and the compat alias (test_gaps)
2630
+ # so agents can use either. untested_sources is the correct semantic name.
2631
+ out["untested_sources"] = output.test_gaps
2632
+ out["test_gaps"] = output.test_gaps # backward compat alias
2633
+ if task == "generate-tests":
2634
+ _et_count = getattr(output, "existing_test_count", None)
2635
+ if _et_count is not None:
2636
+ out["existing_test_count"] = _et_count
2630
2637
  # P0-2: fast-mode truncation transparency — always emit when truncated, even if test_gaps is []
2631
2638
  # Use `is True` (strict) so MagicMock objects in tests don't trigger this branch.
2632
2639
  if getattr(output, "truncated", False) is True:
@@ -3543,6 +3550,12 @@ def fix_bug_cmd(
3543
3550
  sourcecode impact <target> — Propagate impact from a specific class
3544
3551
  sourcecode onboard . — Full architecture context first
3545
3552
  """
3553
+ if not symptom:
3554
+ typer.echo(
3555
+ "[fix-bug] Results are significantly better with --symptom. "
3556
+ "Example: --symptom 'NullPointerException in PaymentService'",
3557
+ err=True,
3558
+ )
3546
3559
  ctx.invoke(
3547
3560
  prepare_context_cmd,
3548
3561
  task="fix-bug",
@@ -4298,19 +4311,21 @@ def cache_status_cmd(
4298
4311
  def cache_clear_cmd(
4299
4312
  path: Path = typer.Argument(Path("."), help="Repository path (default: current directory)"),
4300
4313
  yes: bool = typer.Option(False, "--yes", "-y", help="Skip confirmation prompt."),
4301
- include_ris: bool = typer.Option(False, "--include-ris", help="Also delete the RIS snapshot (ris.json.gz). By default, RIS is preserved across clears."),
4314
+ include_ris: bool = typer.Option(False, "--include-ris", hidden=True, help="Alias for --all. Preserved for backward compatibility."),
4315
+ all_: bool = typer.Option(False, "--all", help="Also delete the RIS snapshot (ris.json.gz). By default, RIS is preserved across clears."),
4302
4316
  ) -> None:
4303
4317
  """Delete cached snapshots for a repository.
4304
4318
 
4305
4319
  By default, RIS (ris.json.gz) is preserved — it is the persistent structural
4306
- index used for cold-start bootstrapping. Use --include-ris to also clear it.
4320
+ index used for cold-start bootstrapping. Use --all to also clear it.
4307
4321
  """
4308
4322
  from sourcecode import cache as _cm
4309
4323
  target = Path(path).resolve()
4324
+ _clear_ris = include_ris or all_
4310
4325
  if not yes:
4311
- _ris_note = " (including RIS)" if include_ris else " (RIS preserved — use --include-ris to also clear it)"
4326
+ _ris_note = " (including RIS)" if _clear_ris else " (RIS preserved — use --all to also clear it)"
4312
4327
  typer.confirm(f"Delete all cache files for {target}{_ris_note}?", abort=True)
4313
- removed = _cm.clear(target, clear_ris=include_ris)
4328
+ removed = _cm.clear(target, clear_ris=_clear_ris)
4314
4329
  typer.echo(f"Removed {removed} file(s).")
4315
4330
 
4316
4331
 
@@ -391,6 +391,8 @@ class TaskOutput:
391
391
  # P0-2: fast-mode truncation transparency
392
392
  truncated: bool = False
393
393
  truncated_reason: Optional[str] = None
394
+ # generate-tests: count of existing test files found (complements untested_sources)
395
+ existing_test_count: Optional[int] = None
394
396
 
395
397
 
396
398
  @dataclass
@@ -2237,6 +2239,8 @@ class TaskContextBuilder:
2237
2239
  # P0-2: fast-mode truncation transparency
2238
2240
  truncated=_fast_truncated,
2239
2241
  truncated_reason=_fast_truncated_reason,
2242
+ # generate-tests: count of test files found alongside untested_sources
2243
+ existing_test_count=len(test_set) if task_name == "generate-tests" else None,
2240
2244
  )
2241
2245
 
2242
2246
  def render_prompt(self, output: TaskOutput) -> str:
@@ -393,12 +393,40 @@ def get_cold_start_context(repo_root: Path) -> dict:
393
393
  # An empty list does NOT mean "no endpoints exist" — it means the endpoint
394
394
  # index has not been built yet. Agents must call get_endpoints to populate.
395
395
  _api_complete = not _is_java or bool(endpoints)
396
+
397
+ # Build structural validation for Java/Spring repos.
398
+ # Detects when the RIS snapshot is structurally incomplete (controllers found
399
+ # but endpoint index was never built), so agents can decide whether to rebuild.
400
+ _controllers_in_map = ris.structural_map.get("controllers", [])
401
+ _controllers_in_api = ris.api_surface.get("controllers_index", [])
402
+ _controllers_found = len(_controllers_in_map) or len(_controllers_in_api)
403
+ _endpoints_found = len(endpoints)
404
+ # Spring is detected when controllers exist in structural map or api surface.
405
+ _spring_detected = bool(_controllers_found) or bool(_controllers_in_api)
406
+ _validation_status = (
407
+ "incomplete_snapshot"
408
+ if _is_java and _spring_detected and _endpoints_found == 0
409
+ else "valid"
410
+ )
411
+ _validation: dict = {
412
+ "spring_detected": _spring_detected,
413
+ "controllers_found": _controllers_found,
414
+ "endpoints_found": _endpoints_found,
415
+ "status": _validation_status,
416
+ }
417
+
418
+ # When the snapshot is structurally incomplete, downgrade status so agents
419
+ # don't assume cold_start_ready when critical sections are missing.
420
+ _status_base = "cold_start_stale" if stale else "cold_start_ready"
421
+ if _validation_status == "incomplete_snapshot" and not stale:
422
+ _status_base = "cold_start_incomplete"
423
+
396
424
  result: dict = {
397
- "status": "cold_start_stale" if stale else "cold_start_ready",
425
+ "status": _status_base,
398
426
  "repo_id": ris.repo_id,
399
427
  "git_head": ris.git_head,
400
428
  "current_git_head": current_head,
401
- "stale": stale,
429
+ "stale": stale or (_validation_status == "incomplete_snapshot"),
402
430
  "has_uncommitted_changes": uncommitted,
403
431
  "last_updated_at": ris.last_updated_at,
404
432
  "cache_source": "RIS",
@@ -408,6 +436,7 @@ def get_cold_start_context(repo_root: Path) -> dict:
408
436
  "entrypoints": ris.structural_map.get("entrypoints", []),
409
437
  "endpoints": endpoints,
410
438
  "hotspots": ris.git_context_snapshot.get("hotspots", []),
439
+ "validation": _validation,
411
440
  }
412
441
  if not endpoints and _is_java:
413
442
  result["endpoints_hint"] = (
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes