sourcecode 1.35.6__tar.gz → 1.35.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.35.6 → sourcecode-1.35.7}/PKG-INFO +1 -1
- {sourcecode-1.35.6 → sourcecode-1.35.7}/pyproject.toml +1 -1
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/__init__.py +1 -1
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/mcp/registry.py +178 -6
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/mcp/server.py +23 -4
- {sourcecode-1.35.6 → sourcecode-1.35.7}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/.gitignore +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/.ruff.toml +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/CHANGELOG.md +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/CONTRIBUTING.md +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/LICENSE +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/README.md +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/SECURITY.md +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/raw +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/cache.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/canonical_ir.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/cir_graphs.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/classifier.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/cli.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/confidence_analyzer.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/contract_pipeline.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/error_schema.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/file_classifier.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/flow_analyzer.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/license.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/mcp/__init__.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/mcp/onboarding/applier.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/mcp/onboarding/backup.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/mcp/onboarding/detector.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/mcp/onboarding/planner.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/mcp/orchestrator.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/mcp/runner.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/mcp_nudge.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/output_budget.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/path_filters.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/pr_comment_renderer.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/prepare_context.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/progress.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/ranking_engine.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/redactor.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/repository_ir.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/ris.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/scanner.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/schema.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/serializer.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/spring_event_topology.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/spring_findings.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/spring_impact.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/spring_model.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/spring_security_audit.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/spring_semantic.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/spring_tx_analyzer.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-1.35.6 → sourcecode-1.35.7}/src/sourcecode/workspace.py +0 -0
|
@@ -10,7 +10,7 @@ Internal helpers remain explicitly marked and are not exported to MCP.
|
|
|
10
10
|
"""
|
|
11
11
|
from __future__ import annotations
|
|
12
12
|
|
|
13
|
-
from dataclasses import dataclass, field
|
|
13
|
+
from dataclasses import dataclass, field, replace
|
|
14
14
|
import inspect
|
|
15
15
|
from functools import lru_cache
|
|
16
16
|
from typing import Any, Callable, Mapping
|
|
@@ -69,6 +69,7 @@ class ToolSpec:
|
|
|
69
69
|
aliases: tuple[str, ...] = ()
|
|
70
70
|
internal: bool = False
|
|
71
71
|
not_exposed_to_cli: bool = False
|
|
72
|
+
mcp_hidden: bool = False
|
|
72
73
|
docstring: str = ""
|
|
73
74
|
runtime_command: str = ""
|
|
74
75
|
_argv_builder: Callable[[Mapping[str, Any]], list[str]] | None = field(
|
|
@@ -82,6 +83,10 @@ class ToolSpec:
|
|
|
82
83
|
def public(self) -> bool:
|
|
83
84
|
return not self.internal and not self.not_exposed_to_cli
|
|
84
85
|
|
|
86
|
+
@property
|
|
87
|
+
def mcp_visible(self) -> bool:
|
|
88
|
+
return self.public and not self.mcp_hidden
|
|
89
|
+
|
|
85
90
|
def build_argv(self, inputs: Mapping[str, Any]) -> list[str]:
|
|
86
91
|
if self._argv_builder is None:
|
|
87
92
|
raise RuntimeError(f"ToolSpec '{self.name}' has no argv builder")
|
|
@@ -488,8 +493,11 @@ def _alias_spec(
|
|
|
488
493
|
aliases: tuple[str, ...] = (),
|
|
489
494
|
internal: bool = False,
|
|
490
495
|
not_exposed_to_cli: bool = False,
|
|
496
|
+
mcp_hidden: bool = False,
|
|
497
|
+
docstring_override: str | None = None,
|
|
491
498
|
validator: Callable[[Mapping[str, Any]], str | None] | None = None,
|
|
492
499
|
) -> ToolSpec:
|
|
500
|
+
doc = docstring_override or _build_contract_doc(description, params, cli_path, supported_targets, unsupported_targets)
|
|
493
501
|
return ToolSpec(
|
|
494
502
|
name=name,
|
|
495
503
|
description=description,
|
|
@@ -500,7 +508,8 @@ def _alias_spec(
|
|
|
500
508
|
aliases=aliases,
|
|
501
509
|
internal=internal,
|
|
502
510
|
not_exposed_to_cli=not_exposed_to_cli,
|
|
503
|
-
|
|
511
|
+
mcp_hidden=mcp_hidden,
|
|
512
|
+
docstring=doc,
|
|
504
513
|
runtime_command=" ".join(cli_path) if cli_path else "sourcecode",
|
|
505
514
|
_argv_builder=argv_builder,
|
|
506
515
|
validator=validator,
|
|
@@ -788,17 +797,169 @@ def _internal_specs() -> list[ToolSpec]:
|
|
|
788
797
|
]
|
|
789
798
|
|
|
790
799
|
|
|
800
|
+
# Canonical CLI tools that are MCP-noise: raw passthroughs, meta-commands, and duplicates
|
|
801
|
+
# superseded by cleaner alias variants. Still tracked by validate_registry(); just not served.
|
|
802
|
+
_MCP_HIDDEN_CANONICAL_TOOLS: frozenset[str] = frozenset({
|
|
803
|
+
# Raw CLI passthroughs (clean alias exists)
|
|
804
|
+
"sourcecode_root", # 40+ flags, no agent guidance; use get_compact_context / get_agent_context
|
|
805
|
+
"prepare_context", # requires knowing subtask string; use task-specific aliases
|
|
806
|
+
"repo_ir", # raw IR dump; use get_ir_summary
|
|
807
|
+
"fix_bug", # raw Pro command; use fix_bug_context for MCP
|
|
808
|
+
"review_pr", # raw Pro command; use review_pr_context for MCP
|
|
809
|
+
"onboard", # raw with llm_prompt/copy flags; use onboard_context
|
|
810
|
+
# Duplicates (inferior params — cleaner alias exists)
|
|
811
|
+
"impact", # path/target order reversed vs get_impact_context; use get_impact_context
|
|
812
|
+
"cold_start", # duplicate of get_cold_start_context
|
|
813
|
+
"cache_freshness", # duplicate of check_freshness
|
|
814
|
+
"modernize", # duplicate of modernize_context
|
|
815
|
+
# Curated overrides — canonical CLI spec replaced by cleaner alias with same name.
|
|
816
|
+
# Listed here so validate_registry() skips CLI param-drift checks on the alias.
|
|
817
|
+
"spring_audit", # curated: repo_path + scope + min_severity only (strips output_path/format/copy)
|
|
818
|
+
"impact_chain", # curated: repo_path + symbol + depth + query_type with choices
|
|
819
|
+
# MCP self-management (an agent is not the MCP client admin)
|
|
820
|
+
"mcp_init",
|
|
821
|
+
"mcp_serve",
|
|
822
|
+
"mcp_status",
|
|
823
|
+
"mcp_remove",
|
|
824
|
+
"mcp_list_tools",
|
|
825
|
+
# Telemetry sub-commands (consolidated into telemetry(action=))
|
|
826
|
+
"telemetry_status",
|
|
827
|
+
"telemetry_enable",
|
|
828
|
+
"telemetry_disable",
|
|
829
|
+
})
|
|
830
|
+
|
|
831
|
+
|
|
832
|
+
def _java_spring_aliases() -> list[ToolSpec]:
|
|
833
|
+
"""Curated MCP overrides for Java/Spring tools.
|
|
834
|
+
|
|
835
|
+
These replace the auto-generated canonical specs with cleaner param surfaces:
|
|
836
|
+
- repo_path (not raw `path`) for consistency with all other MCP tools
|
|
837
|
+
- MCP-irrelevant CLI flags (output_path, format, copy) stripped
|
|
838
|
+
- query_type choices documented so agents discover event topology
|
|
839
|
+
- Rich docstrings instead of contract-format stubs
|
|
840
|
+
"""
|
|
841
|
+
validate_repo_path = _repo_path_validator()
|
|
842
|
+
|
|
843
|
+
_SPRING_AUDIT_DOC = """\
|
|
844
|
+
Spring semantic audit: TX anomalies + security surface. JAVA/SPRING ONLY.
|
|
845
|
+
|
|
846
|
+
Do NOT call on non-Java repositories — returns spring_detected=false with no findings.
|
|
847
|
+
|
|
848
|
+
Patterns detected:
|
|
849
|
+
TX-001: @Transactional missing rollbackFor for checked exceptions
|
|
850
|
+
TX-002: propagation=NEVER/NOT_SUPPORTED inside @Transactional scope
|
|
851
|
+
TX-003: readOnly=true method calling write operations
|
|
852
|
+
TX-004: REQUIRES_NEW nested inside REQUIRED (TX isolation breach risk)
|
|
853
|
+
TX-005: @Async method called within @Transactional context (TX context lost)
|
|
854
|
+
SEC-001: public endpoint with no security annotation (none_detected policy)
|
|
855
|
+
SEC-002: security annotation on non-endpoint method (misplaced)
|
|
856
|
+
SEC-003: missing auth on admin-pattern operations
|
|
857
|
+
|
|
858
|
+
Returns: schema_version, spring_detected, scope, summary, findings[], limitations, metadata.
|
|
859
|
+
findings fields: id, pattern_id, category, severity, confidence, title, symbol,
|
|
860
|
+
source_file, evidence, explanation, fix_hint.
|
|
861
|
+
|
|
862
|
+
repo_path: absolute path to the Java repository (default: current working directory).
|
|
863
|
+
scope: "all" (default) | "tx" (TX-001..005 only) | "security" (SEC-001..003 only)
|
|
864
|
+
min_severity: "low" (default) | "medium" | "high" | "critical"
|
|
865
|
+
"""
|
|
866
|
+
|
|
867
|
+
_IMPACT_CHAIN_DOC = """\
|
|
868
|
+
Spring impact-chain: blast radius of a symbol with TX/SEC semantic enrichment. JAVA/SPRING ONLY.
|
|
869
|
+
|
|
870
|
+
Do NOT call on non-Java repositories — returns resolution=not_found.
|
|
871
|
+
|
|
872
|
+
Two query modes via query_type:
|
|
873
|
+
"impact" (default) — BFS call graph: direct_callers, indirect_callers, endpoints_affected,
|
|
874
|
+
transaction_boundary, security_surfaces, impact_findings (TX/SEC patterns in call chain).
|
|
875
|
+
"events" — event topology: publishers, consumers, propagation graph for an event class
|
|
876
|
+
or event publisher. Use when symbol is an event class (e.g. OrderPlacedEvent).
|
|
877
|
+
|
|
878
|
+
Returns: schema_version, symbol, resolution, direct_callers, indirect_callers,
|
|
879
|
+
endpoints_affected, transaction_boundary, security_surfaces, impact_findings,
|
|
880
|
+
analysis_warnings, risk_level, confidence, metadata.
|
|
881
|
+
|
|
882
|
+
symbol: FQN, class name, or Class#method.
|
|
883
|
+
Examples: "OrderService", "com.example.OrderService#placeOrder",
|
|
884
|
+
"OrderPlacedEvent" (with query_type="events" for event topology)
|
|
885
|
+
repo_path: absolute path to the Java repository (default: current working directory).
|
|
886
|
+
depth: BFS traversal depth 1–8 (default 4).
|
|
887
|
+
query_type: "impact" (default) | "events"
|
|
888
|
+
"""
|
|
889
|
+
|
|
890
|
+
spring_audit = _alias_spec(
|
|
891
|
+
"spring_audit",
|
|
892
|
+
"Spring semantic audit: TX anomalies + security surface. JAVA/SPRING ONLY.",
|
|
893
|
+
("spring-audit",),
|
|
894
|
+
(
|
|
895
|
+
ToolParamSpec("repo_path", "argument", str, required=False, default=".", is_path=True,
|
|
896
|
+
help="Absolute path to the Java repository."),
|
|
897
|
+
ToolParamSpec("scope", "option", str, required=False, default="all",
|
|
898
|
+
option_names=("--scope",), choices=("all", "tx", "security"),
|
|
899
|
+
help="all (default) | tx | security"),
|
|
900
|
+
ToolParamSpec("min_severity", "option", str, required=False, default="low",
|
|
901
|
+
option_names=("--min-severity",), choices=("low", "medium", "high", "critical"),
|
|
902
|
+
help="low (default) | medium | high | critical"),
|
|
903
|
+
),
|
|
904
|
+
lambda inputs: [
|
|
905
|
+
"spring-audit",
|
|
906
|
+
str(inputs.get("repo_path", ".")),
|
|
907
|
+
"--scope", str(inputs.get("scope", "all")),
|
|
908
|
+
"--min-severity", str(inputs.get("min_severity", "low")),
|
|
909
|
+
],
|
|
910
|
+
supported_targets=("repo_path",),
|
|
911
|
+
unsupported_targets=("file_path",),
|
|
912
|
+
validator=validate_repo_path,
|
|
913
|
+
docstring_override=_SPRING_AUDIT_DOC,
|
|
914
|
+
)
|
|
915
|
+
|
|
916
|
+
impact_chain = _alias_spec(
|
|
917
|
+
"impact_chain",
|
|
918
|
+
"Spring impact-chain: blast radius + TX/SEC enrichment. JAVA/SPRING ONLY.",
|
|
919
|
+
("impact-chain",),
|
|
920
|
+
(
|
|
921
|
+
ToolParamSpec("symbol", "argument", str, required=True, default=None,
|
|
922
|
+
help="FQN, class name, or Class#method."),
|
|
923
|
+
ToolParamSpec("repo_path", "argument", str, required=False, default=".", is_path=True,
|
|
924
|
+
help="Absolute path to the Java repository."),
|
|
925
|
+
ToolParamSpec("depth", "option", int, required=False, default=4,
|
|
926
|
+
option_names=("--depth",), help="BFS depth 1–8 (default 4)."),
|
|
927
|
+
ToolParamSpec("query_type", "option", str, required=False, default="impact",
|
|
928
|
+
option_names=("--type",), choices=("impact", "events"),
|
|
929
|
+
help="impact (default) = call-chain blast radius; events = event topology"),
|
|
930
|
+
),
|
|
931
|
+
lambda inputs: [
|
|
932
|
+
"impact-chain",
|
|
933
|
+
str(inputs["symbol"]),
|
|
934
|
+
str(inputs.get("repo_path", ".")),
|
|
935
|
+
"--depth", str(inputs.get("depth", 4)),
|
|
936
|
+
"--type", str(inputs.get("query_type", "impact")),
|
|
937
|
+
],
|
|
938
|
+
supported_targets=("repo_path", "class_name"),
|
|
939
|
+
unsupported_targets=("file_path",),
|
|
940
|
+
validator=validate_repo_path,
|
|
941
|
+
docstring_override=_IMPACT_CHAIN_DOC,
|
|
942
|
+
)
|
|
943
|
+
|
|
944
|
+
return [spring_audit, impact_chain]
|
|
945
|
+
|
|
946
|
+
|
|
791
947
|
@lru_cache(maxsize=1)
|
|
792
948
|
def build_tool_specs() -> tuple[ToolSpec, ...]:
|
|
793
949
|
"""Build the full MCP registry from the live CLI runtime."""
|
|
794
|
-
|
|
950
|
+
canonical_raw = [
|
|
795
951
|
_canonical_spec_for_runtime_command(runtime)
|
|
796
952
|
for runtime in discover_runtime_commands()
|
|
797
953
|
if (runtime.callback is not None or runtime.path == ())
|
|
798
954
|
and (not runtime.hidden or runtime.path == ("analyze",))
|
|
799
955
|
]
|
|
956
|
+
# Mark canonical tools that should not be served via MCP (validate_registry still checks them)
|
|
957
|
+
canonical = [
|
|
958
|
+
replace(spec, mcp_hidden=True) if spec.name in _MCP_HIDDEN_CANONICAL_TOOLS else spec
|
|
959
|
+
for spec in canonical_raw
|
|
960
|
+
]
|
|
800
961
|
|
|
801
|
-
aliases = _root_aliases() + _prepare_context_aliases()
|
|
962
|
+
aliases = _root_aliases() + _prepare_context_aliases() + _java_spring_aliases()
|
|
802
963
|
internals = _internal_specs()
|
|
803
964
|
|
|
804
965
|
merged: dict[str, ToolSpec] = {}
|
|
@@ -842,6 +1003,11 @@ def validate_registry() -> list[str]:
|
|
|
842
1003
|
spec = registry_by_path.get(path)
|
|
843
1004
|
if spec is None:
|
|
844
1005
|
continue
|
|
1006
|
+
# Skip docstring/param drift for mcp_hidden tools and intentional curated overrides.
|
|
1007
|
+
# Curated aliases (e.g. spring_audit, impact_chain) replace canonical CLI specs with
|
|
1008
|
+
# cleaner MCP surfaces — their params diverge from the raw CLI by design.
|
|
1009
|
+
if spec.name in _MCP_HIDDEN_CANONICAL_TOOLS or spec.mcp_hidden:
|
|
1010
|
+
continue
|
|
845
1011
|
expected_doc = _first_doc_line(runtime.docstring or runtime.help or "")
|
|
846
1012
|
if expected_doc and expected_doc not in spec.description:
|
|
847
1013
|
issues.append(f"docstring_mismatch:{spec.name}")
|
|
@@ -853,9 +1019,15 @@ def validate_registry() -> list[str]:
|
|
|
853
1019
|
return issues
|
|
854
1020
|
|
|
855
1021
|
|
|
1022
|
+
@lru_cache(maxsize=1)
|
|
1023
|
+
def build_mcp_tool_specs() -> tuple[ToolSpec, ...]:
|
|
1024
|
+
"""Tool specs actually served via MCP: public and not mcp_hidden."""
|
|
1025
|
+
return tuple(spec for spec in build_tool_specs() if spec.mcp_visible)
|
|
1026
|
+
|
|
1027
|
+
|
|
856
1028
|
def mcp_tool_specs() -> tuple[ToolSpec, ...]:
|
|
857
|
-
"""
|
|
858
|
-
return
|
|
1029
|
+
"""Tool specs served via MCP (public, not mcp_hidden)."""
|
|
1030
|
+
return build_mcp_tool_specs()
|
|
859
1031
|
|
|
860
1032
|
|
|
861
1033
|
def mcp_internal_tool_specs() -> tuple[ToolSpec, ...]:
|
|
@@ -1179,17 +1179,36 @@ def telemetry(action: str) -> dict:
|
|
|
1179
1179
|
return _execute(["telemetry", action])
|
|
1180
1180
|
|
|
1181
1181
|
|
|
1182
|
+
_NATIVE_MCP_TOOLS: frozenset[str] = frozenset({
|
|
1183
|
+
"start_session",
|
|
1184
|
+
"analyze_task",
|
|
1185
|
+
"run_pr_review_flow",
|
|
1186
|
+
"run_bug_investigation_flow",
|
|
1187
|
+
"run_feature_flow",
|
|
1188
|
+
})
|
|
1189
|
+
|
|
1190
|
+
|
|
1182
1191
|
def _finalize_mcp_registry() -> None:
|
|
1183
|
-
"""
|
|
1184
|
-
|
|
1192
|
+
"""Sync the MCP server with the runtime-generated registry.
|
|
1193
|
+
|
|
1194
|
+
Removes every tool except the 5 native orchestration tools (start_session,
|
|
1195
|
+
analyze_task, flow runners) which are registered via @mcp.tool() in this
|
|
1196
|
+
module and have no backing CLI command. All other tools are rebuilt from the
|
|
1197
|
+
runtime-derived registry (build_mcp_tool_specs).
|
|
1198
|
+
"""
|
|
1199
|
+
from sourcecode.mcp.registry import build_mcp_tool_specs, make_tool_callable, validate_registry
|
|
1200
|
+
|
|
1201
|
+
mcp_specs = build_mcp_tool_specs()
|
|
1185
1202
|
|
|
1203
|
+
# Remove everything except the native orchestration tools
|
|
1186
1204
|
try:
|
|
1187
1205
|
for tool in list(mcp._tool_manager.list_tools()): # type: ignore[attr-defined]
|
|
1188
|
-
|
|
1206
|
+
if tool.name not in _NATIVE_MCP_TOOLS:
|
|
1207
|
+
mcp.remove_tool(tool.name)
|
|
1189
1208
|
except Exception:
|
|
1190
1209
|
pass
|
|
1191
1210
|
|
|
1192
|
-
for spec in
|
|
1211
|
+
for spec in mcp_specs:
|
|
1193
1212
|
tool_fn = make_tool_callable(spec)
|
|
1194
1213
|
tool_fn.__doc__ = spec.docstring
|
|
1195
1214
|
globals()[spec.name] = tool_fn
|
|
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
|
|
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
|