sourcecode 1.35.26__tar.gz → 1.35.27__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.35.26 → sourcecode-1.35.27}/PKG-INFO +3 -3
- {sourcecode-1.35.26 → sourcecode-1.35.27}/README.md +2 -2
- {sourcecode-1.35.26 → sourcecode-1.35.27}/pyproject.toml +1 -1
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/__init__.py +1 -1
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/cli.py +238 -0
- sourcecode-1.35.27/src/sourcecode/file_chunker.py +397 -0
- sourcecode-1.35.27/src/sourcecode/rename_refactor.py +299 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/repository_ir.py +18 -1
- {sourcecode-1.35.26 → sourcecode-1.35.27}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/.gitignore +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/.ruff.toml +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/CHANGELOG.md +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/CONTRIBUTING.md +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/LICENSE +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/SECURITY.md +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/raw +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/cache.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/canonical_ir.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/cir_graphs.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/classifier.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/confidence_analyzer.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/contract_pipeline.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/error_schema.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/explain.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/file_classifier.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/flow_analyzer.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/fqn_utils.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/license.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/mcp/__init__.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/mcp/onboarding/applier.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/mcp/onboarding/backup.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/mcp/onboarding/detector.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/mcp/onboarding/planner.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/mcp/orchestrator.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/mcp/registry.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/mcp/runner.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/mcp/server.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/mcp_nudge.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/migrate_check.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/output_budget.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/path_filters.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/pr_comment_renderer.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/pr_impact.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/prepare_context.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/progress.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/ranking_engine.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/redactor.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/ris.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/scanner.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/schema.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/serializer.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/spring_event_topology.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/spring_findings.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/spring_impact.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/spring_model.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/spring_security_audit.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/spring_semantic.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/spring_tx_analyzer.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-1.35.26 → sourcecode-1.35.27}/src/sourcecode/workspace.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sourcecode
|
|
3
|
-
Version: 1.35.
|
|
3
|
+
Version: 1.35.27
|
|
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
|
|
@@ -40,7 +40,7 @@ Description-Content-Type: text/markdown
|
|
|
40
40
|
|
|
41
41
|
**Persistent structural context and ultra-fast repeated analysis for AI coding agents.**
|
|
42
42
|
|
|
43
|
-

|
|
44
44
|

|
|
45
45
|
|
|
46
46
|
---
|
|
@@ -114,7 +114,7 @@ pipx install sourcecode
|
|
|
114
114
|
|
|
115
115
|
```bash
|
|
116
116
|
sourcecode version
|
|
117
|
-
# sourcecode 1.35.
|
|
117
|
+
# sourcecode 1.35.27
|
|
118
118
|
```
|
|
119
119
|
|
|
120
120
|
---
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**Persistent structural context and ultra-fast repeated analysis for AI coding agents.**
|
|
4
4
|
|
|
5
|
-

|
|
6
6
|

|
|
7
7
|
|
|
8
8
|
---
|
|
@@ -76,7 +76,7 @@ pipx install sourcecode
|
|
|
76
76
|
|
|
77
77
|
```bash
|
|
78
78
|
sourcecode version
|
|
79
|
-
# sourcecode 1.35.
|
|
79
|
+
# sourcecode 1.35.27
|
|
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.35.
|
|
7
|
+
version = "1.35.27"
|
|
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"
|
|
@@ -242,6 +242,10 @@ _SUBCOMMANDS: frozenset[str] = frozenset(
|
|
|
242
242
|
"explain",
|
|
243
243
|
# Spring Boot 2→3 migration readiness
|
|
244
244
|
"migrate-check",
|
|
245
|
+
# Native file rename (BLOCKER-A)
|
|
246
|
+
"rename-class",
|
|
247
|
+
# Large file semantic chunking (BLOCKER-B)
|
|
248
|
+
"chunk-file",
|
|
245
249
|
}
|
|
246
250
|
)
|
|
247
251
|
|
|
@@ -5009,6 +5013,240 @@ def modernize_cmd(
|
|
|
5009
5013
|
_copy_to_clipboard(output)
|
|
5010
5014
|
|
|
5011
5015
|
|
|
5016
|
+
# ── rename-class ──────────────────────────────────────────────────────────────
|
|
5017
|
+
|
|
5018
|
+
@app.command("rename-class")
|
|
5019
|
+
def rename_class_cmd(
|
|
5020
|
+
path: Path = typer.Argument(
|
|
5021
|
+
Path("."),
|
|
5022
|
+
help="Repository root to operate on (default: current directory)",
|
|
5023
|
+
),
|
|
5024
|
+
old_name: str = typer.Option(
|
|
5025
|
+
..., "--from", "-f",
|
|
5026
|
+
help="Current class name (PascalCase, e.g. ServiceA)",
|
|
5027
|
+
),
|
|
5028
|
+
new_name: str = typer.Option(
|
|
5029
|
+
..., "--to", "-t",
|
|
5030
|
+
help="New class name (PascalCase, e.g. ServiceB)",
|
|
5031
|
+
),
|
|
5032
|
+
dry_run: bool = typer.Option(
|
|
5033
|
+
False, "--dry-run",
|
|
5034
|
+
help="Compute changes but do not write any files or rename on disk.",
|
|
5035
|
+
),
|
|
5036
|
+
no_tests: bool = typer.Option(
|
|
5037
|
+
False, "--no-tests",
|
|
5038
|
+
help="Exclude test files from the rename (src/main only).",
|
|
5039
|
+
),
|
|
5040
|
+
output_path: Optional[Path] = typer.Option(
|
|
5041
|
+
None, "--output", "-o",
|
|
5042
|
+
help="Write change audit JSON to a file instead of stdout.",
|
|
5043
|
+
),
|
|
5044
|
+
copy: bool = typer.Option(
|
|
5045
|
+
False, "--copy", "-c",
|
|
5046
|
+
help="Copy output to clipboard after a successful run.",
|
|
5047
|
+
),
|
|
5048
|
+
format: str = typer.Option(
|
|
5049
|
+
"json", "--format",
|
|
5050
|
+
help="Output format: json (default) or yaml.",
|
|
5051
|
+
),
|
|
5052
|
+
) -> None:
|
|
5053
|
+
"""Rename a Java class throughout the repository (BLOCKER-A fix).
|
|
5054
|
+
|
|
5055
|
+
\b
|
|
5056
|
+
Renames a Java class safely:
|
|
5057
|
+
- Updates class/interface/enum declaration
|
|
5058
|
+
- Updates constructor name
|
|
5059
|
+
- Updates all import statements
|
|
5060
|
+
- Updates all type references (fields, params, return types)
|
|
5061
|
+
- Updates extends / implements
|
|
5062
|
+
- Updates generics, casts, Spring @Qualifier names
|
|
5063
|
+
- Renames the physical .java file
|
|
5064
|
+
- Emits a structured change audit trail (BLOCKER-C)
|
|
5065
|
+
|
|
5066
|
+
\b
|
|
5067
|
+
Examples:
|
|
5068
|
+
sourcecode rename-class . --from ServiceA --to ServiceB
|
|
5069
|
+
sourcecode rename-class /path/to/repo --from OrderManager --to OrderService
|
|
5070
|
+
sourcecode rename-class . --from OldName --to NewName --dry-run
|
|
5071
|
+
sourcecode rename-class . --from OldName --to NewName --output rename-audit.json
|
|
5072
|
+
"""
|
|
5073
|
+
import json as _json
|
|
5074
|
+
from sourcecode.rename_refactor import rename_class
|
|
5075
|
+
|
|
5076
|
+
root = path.resolve()
|
|
5077
|
+
if not root.is_dir():
|
|
5078
|
+
_emit_error_json(
|
|
5079
|
+
INVALID_INPUT_CODE,
|
|
5080
|
+
f"'{root}' is not a valid directory.",
|
|
5081
|
+
path=str(root),
|
|
5082
|
+
hint="Pass an existing repository directory.",
|
|
5083
|
+
expected="A directory path.",
|
|
5084
|
+
)
|
|
5085
|
+
raise typer.Exit(1)
|
|
5086
|
+
|
|
5087
|
+
result = rename_class(
|
|
5088
|
+
root,
|
|
5089
|
+
old_name,
|
|
5090
|
+
new_name,
|
|
5091
|
+
dry_run=dry_run,
|
|
5092
|
+
include_tests=not no_tests,
|
|
5093
|
+
)
|
|
5094
|
+
|
|
5095
|
+
if result.errors:
|
|
5096
|
+
_emit_error_json(
|
|
5097
|
+
"RENAME_ERROR",
|
|
5098
|
+
result.errors[0],
|
|
5099
|
+
errors=result.errors,
|
|
5100
|
+
old_name=old_name,
|
|
5101
|
+
new_name=new_name,
|
|
5102
|
+
)
|
|
5103
|
+
raise typer.Exit(1)
|
|
5104
|
+
|
|
5105
|
+
result_dict = result.to_dict()
|
|
5106
|
+
|
|
5107
|
+
if format == "yaml":
|
|
5108
|
+
from sourcecode.serializer import to_yaml as _to_yaml
|
|
5109
|
+
output = _to_yaml(result_dict)
|
|
5110
|
+
else:
|
|
5111
|
+
output = _json.dumps(result_dict, indent=2, ensure_ascii=False)
|
|
5112
|
+
|
|
5113
|
+
if output_path:
|
|
5114
|
+
output_path.write_text(output, encoding="utf-8")
|
|
5115
|
+
action = "dry-run simulated" if dry_run else "applied"
|
|
5116
|
+
typer.echo(
|
|
5117
|
+
f"[rename-class] {action}: {old_name} → {new_name} "
|
|
5118
|
+
f"({result.files_modified} file(s) changed). "
|
|
5119
|
+
f"Audit written to {output_path}",
|
|
5120
|
+
err=True,
|
|
5121
|
+
)
|
|
5122
|
+
else:
|
|
5123
|
+
try:
|
|
5124
|
+
sys.stdout.buffer.write(output.encode("utf-8"))
|
|
5125
|
+
sys.stdout.buffer.write(b"\n")
|
|
5126
|
+
sys.stdout.buffer.flush()
|
|
5127
|
+
except AttributeError:
|
|
5128
|
+
sys.stdout.write(output + "\n")
|
|
5129
|
+
|
|
5130
|
+
if copy:
|
|
5131
|
+
_copy_to_clipboard(output)
|
|
5132
|
+
|
|
5133
|
+
if not dry_run and not output_path:
|
|
5134
|
+
action = "Renamed"
|
|
5135
|
+
typer.echo(
|
|
5136
|
+
f"[rename-class] {action}: {old_name} → {new_name} "
|
|
5137
|
+
f"({result.files_modified} file(s) updated, file renamed to {result.new_file})",
|
|
5138
|
+
err=True,
|
|
5139
|
+
)
|
|
5140
|
+
|
|
5141
|
+
|
|
5142
|
+
# ── chunk-file ────────────────────────────────────────────────────────────────
|
|
5143
|
+
|
|
5144
|
+
@app.command("chunk-file")
|
|
5145
|
+
def chunk_file_cmd(
|
|
5146
|
+
file: Path = typer.Argument(
|
|
5147
|
+
...,
|
|
5148
|
+
help="Java file to chunk (absolute or relative path)",
|
|
5149
|
+
),
|
|
5150
|
+
max_lines: int = typer.Option(
|
|
5151
|
+
500, "--max-lines", "-n",
|
|
5152
|
+
help="Target max lines per chunk (default: 500). Methods > max_lines emit size_warning.",
|
|
5153
|
+
),
|
|
5154
|
+
chunk_id: Optional[int] = typer.Option(
|
|
5155
|
+
None, "--chunk", "-c",
|
|
5156
|
+
help="Return only this chunk by ID (1-based). Omit to return all chunks.",
|
|
5157
|
+
),
|
|
5158
|
+
metadata_only: bool = typer.Option(
|
|
5159
|
+
False, "--metadata-only",
|
|
5160
|
+
help="Return chunk boundaries and metadata without file content.",
|
|
5161
|
+
),
|
|
5162
|
+
output_path: Optional[Path] = typer.Option(
|
|
5163
|
+
None, "--output", "-o",
|
|
5164
|
+
help="Write output to a file instead of stdout.",
|
|
5165
|
+
),
|
|
5166
|
+
format: str = typer.Option(
|
|
5167
|
+
"json", "--format",
|
|
5168
|
+
help="Output format: json (default) or yaml.",
|
|
5169
|
+
),
|
|
5170
|
+
copy: bool = typer.Option(
|
|
5171
|
+
False, "--copy",
|
|
5172
|
+
help="Copy output to clipboard after a successful run.",
|
|
5173
|
+
),
|
|
5174
|
+
) -> None:
|
|
5175
|
+
"""Split a large Java file into semantic chunks for AI agent consumption (BLOCKER-B fix).
|
|
5176
|
+
|
|
5177
|
+
\b
|
|
5178
|
+
Splits a Java file at method/class boundaries so AI agents can read
|
|
5179
|
+
large files (10K–25K+ lines) in context-sized pieces without timeout
|
|
5180
|
+
or fragmented analysis.
|
|
5181
|
+
|
|
5182
|
+
Each chunk includes:
|
|
5183
|
+
- chunk_id, start_line, end_line, chunk_type, symbol name
|
|
5184
|
+
- context_header: package + class + imports summary
|
|
5185
|
+
- content: source lines for that chunk
|
|
5186
|
+
- size_warning: True if chunk > max_lines (cannot split mid-method)
|
|
5187
|
+
|
|
5188
|
+
\b
|
|
5189
|
+
Examples:
|
|
5190
|
+
sourcecode chunk-file NominasCalculoService.java
|
|
5191
|
+
sourcecode chunk-file BigService.java --max-lines 300
|
|
5192
|
+
sourcecode chunk-file BigService.java --chunk 5 # read chunk 5 only
|
|
5193
|
+
sourcecode chunk-file BigService.java --metadata-only # sizes/boundaries only
|
|
5194
|
+
"""
|
|
5195
|
+
import json as _json
|
|
5196
|
+
from sourcecode.file_chunker import chunk_java_file
|
|
5197
|
+
|
|
5198
|
+
abs_file = file.resolve()
|
|
5199
|
+
if not abs_file.is_file():
|
|
5200
|
+
_emit_error_json(
|
|
5201
|
+
INVALID_INPUT_CODE,
|
|
5202
|
+
f"'{abs_file}' is not a valid file.",
|
|
5203
|
+
path=str(abs_file),
|
|
5204
|
+
hint="Pass an existing Java source file.",
|
|
5205
|
+
expected="A .java file path.",
|
|
5206
|
+
)
|
|
5207
|
+
raise typer.Exit(1)
|
|
5208
|
+
|
|
5209
|
+
result = chunk_java_file(abs_file, max_lines=max_lines, include_content=not metadata_only)
|
|
5210
|
+
|
|
5211
|
+
if chunk_id is not None:
|
|
5212
|
+
# Return single chunk
|
|
5213
|
+
matching = [c for c in result.chunks if c.chunk_id == chunk_id]
|
|
5214
|
+
if not matching:
|
|
5215
|
+
_emit_error_json(
|
|
5216
|
+
INVALID_INPUT_CODE,
|
|
5217
|
+
f"Chunk {chunk_id} not found. File has {result.total_chunks} chunks.",
|
|
5218
|
+
chunk_id=chunk_id,
|
|
5219
|
+
total_chunks=result.total_chunks,
|
|
5220
|
+
)
|
|
5221
|
+
raise typer.Exit(1)
|
|
5222
|
+
result_dict = matching[0].to_dict()
|
|
5223
|
+
else:
|
|
5224
|
+
result_dict = result.to_dict()
|
|
5225
|
+
|
|
5226
|
+
if format == "yaml":
|
|
5227
|
+
from sourcecode.serializer import to_yaml as _to_yaml
|
|
5228
|
+
output = _to_yaml(result_dict)
|
|
5229
|
+
else:
|
|
5230
|
+
output = _json.dumps(result_dict, indent=2, ensure_ascii=False)
|
|
5231
|
+
|
|
5232
|
+
if output_path:
|
|
5233
|
+
output_path.write_text(output, encoding="utf-8")
|
|
5234
|
+
typer.echo(
|
|
5235
|
+
f"[chunk-file] {result.total_chunks} chunks written to {output_path}",
|
|
5236
|
+
err=True,
|
|
5237
|
+
)
|
|
5238
|
+
else:
|
|
5239
|
+
try:
|
|
5240
|
+
sys.stdout.buffer.write(output.encode("utf-8"))
|
|
5241
|
+
sys.stdout.buffer.write(b"\n")
|
|
5242
|
+
sys.stdout.buffer.flush()
|
|
5243
|
+
except AttributeError:
|
|
5244
|
+
sys.stdout.write(output + "\n")
|
|
5245
|
+
|
|
5246
|
+
if copy:
|
|
5247
|
+
_copy_to_clipboard(output)
|
|
5248
|
+
|
|
5249
|
+
|
|
5012
5250
|
# ── version ───────────────────────────────────────────────────────────────────
|
|
5013
5251
|
|
|
5014
5252
|
@app.command("activate")
|