sourcecode 2.0.1__py3-none-any.whl → 2.1.0__py3-none-any.whl

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/license.py CHANGED
@@ -89,9 +89,25 @@ if _SUPABASE_URL != _DEFAULT_SUPABASE_URL:
89
89
  # which case prompts point to the documented Pro plans instead of a placeholder link.
90
90
  _PURCHASE_URL: str = os.environ.get("SOURCECODE_PURCHASE_URL", "").strip()
91
91
 
92
- _LICENSE_DIR: Path = Path.home() / ".sourcecode"
92
+ # Config home: ~/.ask is canonical (product = ASK Engine). The legacy ~/.sourcecode
93
+ # stays READABLE so no existing user loses their license — reads prefer ~/.ask and
94
+ # fall back to ~/.sourcecode; writes always land in ~/.ask. Backward-compatible.
95
+ _LICENSE_DIR: Path = Path.home() / ".ask"
96
+ _LEGACY_LICENSE_DIR: Path = Path.home() / ".sourcecode"
93
97
  _LICENSE_FILE: Path = _LICENSE_DIR / "license.json"
94
98
  _DELTA_RUNS_FILE: Path = _LICENSE_DIR / "delta_runs.json"
99
+
100
+
101
+ def _read_config_path(name: str) -> Path:
102
+ """Existing config file for `name`, preferring ~/.ask, else legacy ~/.sourcecode.
103
+ Returns the canonical ~/.ask path when neither exists (write target)."""
104
+ new = _LICENSE_DIR / name
105
+ if new.exists():
106
+ return new
107
+ legacy = _LEGACY_LICENSE_DIR / name
108
+ if legacy.exists():
109
+ return legacy
110
+ return new
95
111
  _CACHE_TTL_SECONDS: int = 1800 # 30 minutes default; CI env overrides to 24h (see _get_cache_ttl)
96
112
  _CACHE_TTL_CI_SECONDS: int = 86400 # 24 hours — CI containers must not re-validate mid-run
97
113
 
@@ -196,7 +212,7 @@ _PRO_UNLOCK_ALL = os.environ.get("SOURCECODE_PRO_UNLOCK", "1") != "0"
196
212
 
197
213
 
198
214
  def _secure_dir() -> None:
199
- """Create ~/.sourcecode owner-only (0700). Holds the license secret.
215
+ """Create ~/.ask owner-only (0700). Holds the license secret.
200
216
 
201
217
  ``mkdir(mode=...)`` is ignored when the dir already exists, so chmod
202
218
  unconditionally. Best-effort: a chmod failure (e.g. Windows) is non-fatal.
@@ -235,8 +251,9 @@ def _write_license_file(data: dict) -> None:
235
251
 
236
252
  def _read_delta_runs() -> dict:
237
253
  try:
238
- if _DELTA_RUNS_FILE.exists():
239
- return json.loads(_DELTA_RUNS_FILE.read_text(encoding="utf-8"))
254
+ src = _read_config_path("delta_runs.json")
255
+ if src.exists():
256
+ return json.loads(src.read_text(encoding="utf-8"))
240
257
  except Exception:
241
258
  pass
242
259
  return {}
@@ -268,11 +285,12 @@ def check_delta_free_tier(repo_path: str) -> "tuple[bool, int, int]":
268
285
 
269
286
 
270
287
  def _load_license_file() -> Optional[dict]:
271
- """Read ~/.sourcecode/license.json. Returns parsed dict or None."""
288
+ """Read the license file, preferring ~/.ask and falling back to the legacy
289
+ ~/.sourcecode. Returns parsed dict or None."""
272
290
  try:
273
- if _LICENSE_FILE.exists():
274
- raw = _LICENSE_FILE.read_text(encoding="utf-8")
275
- return json.loads(raw)
291
+ src = _read_config_path("license.json")
292
+ if src.exists():
293
+ return json.loads(src.read_text(encoding="utf-8"))
276
294
  except Exception:
277
295
  pass
278
296
  return None
@@ -409,7 +427,7 @@ def _emit_upgrade_and_exit(headline: str, body_lines: list[str], payload: dict)
409
427
  lines.append(" Unlock Pro:")
410
428
  where = _PURCHASE_URL or "see Pro plans (docs/PRODUCT_TIERS.md)"
411
429
  lines.append(f" 1. Get a license: {where}")
412
- lines.append(" 2. Activate: sourcecode activate <license_key>")
430
+ lines.append(" 2. Activate: ask activate <license_key>")
413
431
  lines.append("")
414
432
  sys.stderr.write("\n".join(lines) + "\n")
415
433
  sys.stderr.flush()
@@ -479,9 +497,9 @@ def require_feature(
479
497
  "feature": feature_name,
480
498
  "message": (
481
499
  f"'{display}' requires a Pro license. "
482
- "Run: sourcecode activate <license_key>"
500
+ "Run: ask activate <license_key>"
483
501
  ),
484
- "upgrade_hint": "sourcecode activate <license_key>",
502
+ "upgrade_hint": "ask activate <license_key>",
485
503
  }
486
504
  if extra_fields:
487
505
  payload.update(extra_fields)
@@ -530,9 +548,9 @@ def require_repo_or_pro(
530
548
  f"This repository exceeds the free-tier limit of "
531
549
  f"{_FREE_REPO_JAVA_FILE_LIMIT} Java source files. "
532
550
  "Pro unlocks enterprise-scale monoliths. "
533
- "Run: sourcecode activate <license_key>"
551
+ "Run: ask activate <license_key>"
534
552
  ),
535
- "upgrade_hint": "sourcecode activate <license_key>",
553
+ "upgrade_hint": "ask activate <license_key>",
536
554
  }
537
555
  if extra_fields:
538
556
  payload.update(extra_fields)
@@ -6,9 +6,10 @@ import os
6
6
  from pathlib import Path
7
7
 
8
8
  _MCP_SERVERS_KEY = "mcpServers"
9
- _ENTRY_NAME = "sourcecode"
9
+ _ENTRY_NAME = "ask" # canonical (product = ASK Engine)
10
+ _LEGACY_ENTRY_NAME = "sourcecode" # deprecated alias — still recognized/cleaned
10
11
  _ENTRY_VALUE: dict[str, object] = {
11
- "command": "sourcecode",
12
+ "command": "ask",
12
13
  "args": ["mcp", "serve"],
13
14
  }
14
15
 
@@ -25,24 +26,31 @@ def read_config(path: Path) -> dict:
25
26
 
26
27
 
27
28
  def is_installed(config: dict) -> bool:
28
- """True if sourcecode entry already present in mcpServers."""
29
- return _ENTRY_NAME in config.get(_MCP_SERVERS_KEY, {})
29
+ """True if the ASK Engine entry (canonical `ask` or legacy `sourcecode`) is
30
+ already present in mcpServers."""
31
+ servers = config.get(_MCP_SERVERS_KEY, {})
32
+ return _ENTRY_NAME in servers or _LEGACY_ENTRY_NAME in servers
30
33
 
31
34
 
32
35
  def apply_entry(config: dict) -> dict:
33
- """Return new config dict with sourcecode merged into mcpServers."""
36
+ """Return new config dict with the canonical `ask` entry merged into mcpServers.
37
+ Any legacy `sourcecode` entry is migrated away (removed) so the client launches
38
+ a single server."""
34
39
  config = dict(config)
35
40
  servers: dict = dict(config.get(_MCP_SERVERS_KEY, {}))
41
+ servers.pop(_LEGACY_ENTRY_NAME, None)
36
42
  servers[_ENTRY_NAME] = _ENTRY_VALUE
37
43
  config[_MCP_SERVERS_KEY] = servers
38
44
  return config
39
45
 
40
46
 
41
47
  def remove_entry(config: dict) -> dict:
42
- """Return new config dict with sourcecode removed from mcpServers."""
48
+ """Return new config dict with the ASK Engine entry removed both the canonical
49
+ `ask` key and any legacy `sourcecode` key."""
43
50
  config = dict(config)
44
51
  servers: dict = dict(config.get(_MCP_SERVERS_KEY, {}))
45
52
  servers.pop(_ENTRY_NAME, None)
53
+ servers.pop(_LEGACY_ENTRY_NAME, None)
46
54
  if servers:
47
55
  config[_MCP_SERVERS_KEY] = servers
48
56
  elif _MCP_SERVERS_KEY in config:
@@ -416,7 +416,7 @@ def make_tool_callable(spec: ToolSpec) -> Callable[..., Any]:
416
416
 
417
417
  def _canonical_spec_for_runtime_command(runtime: RuntimeCommand) -> ToolSpec:
418
418
  params = tuple(_click_to_param_spec(param) for param in runtime.command.params)
419
- runtime_command = " ".join(runtime.path) if runtime.path else "sourcecode"
419
+ runtime_command = " ".join(runtime.path) if runtime.path else "ask"
420
420
  name = _tool_name_for_path(runtime.path)
421
421
  doc = runtime.docstring or runtime.help or ""
422
422
  description = _first_doc_line(doc) or f"CLI command: {runtime_command}"
@@ -510,7 +510,7 @@ def _alias_spec(
510
510
  not_exposed_to_cli=not_exposed_to_cli,
511
511
  mcp_hidden=mcp_hidden,
512
512
  docstring=doc,
513
- runtime_command=" ".join(cli_path) if cli_path else "sourcecode",
513
+ runtime_command=" ".join(cli_path) if cli_path else "ask",
514
514
  _argv_builder=argv_builder,
515
515
  validator=validator,
516
516
  )
@@ -552,7 +552,7 @@ Returns: stacks, entry points, dependency summary, architecture summary, confide
552
552
  Includes security_surface, mybatis, and transactional_boundaries for Java/Spring projects.
553
553
  For richer machine-oriented detail (deeper signals, more sections), use get_agent_context.
554
554
 
555
- Maps to: sourcecode <repo_path> --compact [--git-context]
555
+ Maps to: ask <repo_path> --compact [--git-context]
556
556
  repo_path: absolute path to the repository (default: current working directory).
557
557
  git_context: include git log and branch context in the analysis.
558
558
  """
@@ -565,7 +565,7 @@ lacks sufficient detail. Includes all compact fields plus: env_map, code_notes,
565
565
  architecture layers, security surface, transactional boundaries, module graph summary.
566
566
  Prefer get_compact_context for quick orientation or token-constrained workflows.
567
567
 
568
- Maps to: sourcecode <repo_path> --agent [--git-context]
568
+ Maps to: ask <repo_path> --agent [--git-context]
569
569
  repo_path: absolute path to the repository (default: current working directory).
570
570
  git_context: include git log and branch context in the analysis.
571
571
  """
@@ -573,7 +573,7 @@ git_context: include git log and branch context in the analysis.
573
573
  _GET_MODULE_DOC = """\
574
574
  Compact analysis of a specific module or subdirectory within a repository.
575
575
 
576
- Maps to: sourcecode <repo_path>/<module> --compact
576
+ Maps to: ask <repo_path>/<module> --compact
577
577
  repo_path: absolute path to the repository root.
578
578
  module: subdirectory name relative to repo_path (e.g. 'src/auth', 'api', 'core').
579
579
  Returns: same fields as get_compact_context but scoped to the module subtree.
@@ -582,7 +582,7 @@ Returns: same fields as get_compact_context but scoped to the module subtree.
582
582
  _TELEMETRY_DOC = """\
583
583
  Manage telemetry settings.
584
584
 
585
- Maps to: sourcecode telemetry <action>
585
+ Maps to: ask telemetry <action>
586
586
  action: one of "status" (show current state), "enable" (opt in), "disable" (opt out).
587
587
  Valid values: "status" | "enable" | "disable"
588
588
  """
@@ -689,7 +689,7 @@ def _prepare_context_aliases() -> list[ToolSpec]:
689
689
  _GET_DELTA_DOC = """\
690
690
  Incremental context: git-changed files since a reference commit.
691
691
 
692
- Maps to: sourcecode prepare-context delta <repo_path> --since <since>
692
+ Maps to: ask prepare-context delta <repo_path> --since <since>
693
693
  repo_path: absolute path to the repository (default: current working directory).
694
694
  since: git ref to diff against (e.g. HEAD~3, main, origin/main).
695
695
  If empty or omitted, auto-detects merge-base with origin/main (or
@@ -700,7 +700,7 @@ since: git ref to diff against (e.g. HEAD~3, main, origin/main).
700
700
  _REVIEW_PR_DOC = """\
701
701
  Execution paths and risk analysis for changed files in a pull request.
702
702
 
703
- Maps to: sourcecode prepare-context review-pr <repo_path> [--since <since>]
703
+ Maps to: ask prepare-context review-pr <repo_path> [--since <since>]
704
704
  Returns: compact_base + execution_paths (diff-scoped) + hotspots for changed files.
705
705
  repo_path: absolute path to the repository (default: current working directory).
706
706
  since: git ref to diff against (e.g. HEAD~3, main, origin/main).
@@ -710,7 +710,7 @@ since: git ref to diff against (e.g. HEAD~3, main, origin/main).
710
710
  _FIX_BUG_DOC = """\
711
711
  Risk-ranked files for bug investigation, optionally focused by symptom.
712
712
 
713
- Maps to: sourcecode prepare-context fix-bug <repo_path> [--symptom <symptom>]
713
+ Maps to: ask prepare-context fix-bug <repo_path> [--symptom <symptom>]
714
714
  Includes compact_base: security_surface, transactional_boundaries, spring_profiles.
715
715
  repo_path: absolute path to the repository (default: current working directory).
716
716
  symptom: optional error message or class name to focus the file ranking
@@ -722,7 +722,7 @@ symptom: optional error message or class name to focus the file ranking
722
722
  _ONBOARD_DOC = """\
723
723
  Onboarding context: structured overview for new contributors.
724
724
 
725
- Maps to: sourcecode prepare-context onboard <repo_path>
725
+ Maps to: ask prepare-context onboard <repo_path>
726
726
  Returns: project structure, key entry points, architectural patterns, getting-started guide.
727
727
  repo_path: absolute path to the repository (default: current working directory).
728
728
  """
@@ -730,7 +730,7 @@ repo_path: absolute path to the repository (default: current working directory).
730
730
  _EXPLAIN_DOC = """\
731
731
  Architecture and entry-point explanation for a repository.
732
732
 
733
- Maps to: sourcecode prepare-context explain <repo_path>
733
+ Maps to: ask prepare-context explain <repo_path>
734
734
  Returns: project summary, architecture overview, entry points, key dependencies.
735
735
  repo_path: absolute path to the repository (default: current working directory).
736
736
  """
@@ -738,7 +738,7 @@ repo_path: absolute path to the repository (default: current working directory).
738
738
  _REFACTOR_DOC = """\
739
739
  Structural issues and refactor opportunities for a repository.
740
740
 
741
- Maps to: sourcecode prepare-context refactor <repo_path>
741
+ Maps to: ask prepare-context refactor <repo_path>
742
742
  Returns: structural issues, coupling hotspots, high-churn files, improvement opportunities.
743
743
  repo_path: absolute path to the repository (default: current working directory).
744
744
  """
@@ -746,7 +746,7 @@ repo_path: absolute path to the repository (default: current working directory).
746
746
  _GENERATE_TESTS_DOC = """\
747
747
  Untested source files and test gap analysis for a repository.
748
748
 
749
- Maps to: sourcecode prepare-context generate-tests <repo_path> [--all]
749
+ Maps to: ask prepare-context generate-tests <repo_path> [--all]
750
750
  Returns: test_gaps list of untested files ranked by risk.
751
751
  On large repos (>2000 classes) analysis is bounded by SOURCECODE_TESTS_TIMEOUT_MS
752
752
  (default: 15000 ms). If timeout elapses, returns truncated=true with partial results.
@@ -757,7 +757,7 @@ include_all: return full test_gaps list without truncating to top 20.
757
757
  _IR_SUMMARY_DOC = """\
758
758
  Deterministic symbol-level IR summary for Java repositories. Java only.
759
759
 
760
- Maps to: sourcecode repo-ir <repo_path> --summary-only
760
+ Maps to: ask repo-ir <repo_path> --summary-only
761
761
  Returns: reverse_graph, route_surface (top 50 endpoints),
762
762
  subsystems (top 15), impact, analysis. Full graph nodes/edges omitted.
763
763
 
@@ -770,7 +770,7 @@ subsystems: list of detected subsystem cluster dicts.
770
770
  analysis: metadata — total_classes, total_edges, analysis_ms.
771
771
 
772
772
  Output is bounded to ~100 KB for LLM safety. For full IR (can exceed 10 MB
773
- on large repos), use the CLI: sourcecode repo-ir <path> --output ir.json
773
+ on large repos), use the CLI: ask repo-ir <path> --output ir.json
774
774
  Use get_compact_context or get_agent_context for non-Java repos.
775
775
 
776
776
  repo_path: absolute path to the Java repository (default: current working directory).
@@ -779,7 +779,7 @@ repo_path: absolute path to the Java repository (default: current working direct
779
779
  _IMPACT_CONTEXT_DOC = """\
780
780
  Blast-radius analysis: who calls a class and what breaks if it changes? Java only.
781
781
 
782
- Maps to: sourcecode impact <target> <repo_path> [--depth <depth>]
782
+ Maps to: ask impact <target> <repo_path> [--depth <depth>]
783
783
  Returns: direct_callers, indirect_callers, endpoints_affected,
784
784
  transactional_boundaries_touched, risk_score, risk_level, stats.
785
785
 
@@ -797,7 +797,7 @@ depth: BFS depth for indirect caller traversal (1–8, default: 4).
797
797
  _MODERNIZE_DOC = """\
798
798
  Analyzes codebase for modernization opportunities: dead zones, hotspot scores, upgrade candidates.
799
799
 
800
- Maps to: sourcecode modernize <repo_path>
800
+ Maps to: ask modernize <repo_path>
801
801
  Returns: hotspot_candidates (high fan-in + git churn), statically_unreferenced (zero-caller classes — NOT confirmed dead; verify no framework dispatch) + framework_dispatched,
802
802
  high_coupling_nodes, subsystem_summary, cross_module_tangles, recommendation.
803
803
 
@@ -852,7 +852,7 @@ REST API endpoint surface extraction from Java source files. JAVA ONLY.
852
852
  Do NOT call this on non-Java repositories — it will return empty results.
853
853
  Use get_compact_context or get_agent_context for non-Java repos.
854
854
 
855
- Maps to: sourcecode endpoints <repo_path>
855
+ Maps to: ask endpoints <repo_path>
856
856
  Returns: endpoints list with method, path, controller, handler fields;
857
857
  security dict always present (policy: roles_allowed|permit_all|deny_all|
858
858
  authenticated|...|none_detected); none_detected = no auth annotation found.
@@ -879,7 +879,7 @@ must satisfy before generating a payload, a test, or reasoning about a 400:
879
879
  * hand-written custom validators (@Constraint + ConstraintValidator, e.g.
880
880
  PetAgeValidator), linked to fields via x-field-extra-annotation.
881
881
 
882
- Maps to: sourcecode validation <repo_path>
882
+ Maps to: ask validation <repo_path>
883
883
  Returns: endpoints[] (method, path, controller, handler, schema, validatedFields[
884
884
  {name, rules[{kind,value}], customValidators[{annotation,validators,message,resolved}]}]),
885
885
  custom_validators[] (catalog: annotation, validators, message, validatedTypes, targets),
@@ -894,7 +894,7 @@ gaps_only: when true, return only the gaps section (endpoints lacking validation
894
894
  _CACHE_STATUS_DOC = """\
895
895
  Report cache metadata for a repository.
896
896
 
897
- Maps to: sourcecode cache status <repo_path> --json
897
+ Maps to: ask cache status <repo_path> --json
898
898
  Returns: cache entries with git_head, timestamps, size info.
899
899
  Use check_freshness for RIS-specific freshness checking (faster, richer).
900
900
  repo_path: absolute path to the repository (default: current working directory).
@@ -903,7 +903,7 @@ repo_path: absolute path to the repository (default: current working directory).
903
903
  _CACHE_WARM_DOC = """\
904
904
  Warm the cache for a repository (builds compact and agent analysis snapshots).
905
905
 
906
- Maps to: sourcecode cache warm <repo_path>
906
+ Maps to: ask cache warm <repo_path>
907
907
  Builds or refreshes the Repository Intelligence Snapshot (RIS).
908
908
  Use before analytical workflows to ensure fast subsequent tool calls (~8s first run,
909
909
  instant after).
@@ -913,7 +913,7 @@ repo_path: absolute path to the repository (default: current working directory).
913
913
  _CACHE_CLEAR_DOC = """\
914
914
  Clear cached analysis for a repository.
915
915
 
916
- Maps to: sourcecode cache clear <repo_path> [--include-ris]
916
+ Maps to: ask cache clear <repo_path> [--include-ris]
917
917
  Removes cached context files. After clearing, run get_compact_context or cache_warm to rebuild.
918
918
  include_ris: also remove the RIS snapshot in addition to analysis cache (default: False).
919
919
  repo_path: absolute path to the repository (default: current working directory).
sourcecode/mcp/runner.py CHANGED
@@ -66,7 +66,7 @@ def run_command(args: list[str]) -> Any:
66
66
  payload = _parsed
67
67
  break
68
68
  raise CommandError(
69
- f"sourcecode command failed (exit {result.exit_code}). Args: {args}",
69
+ f"ask command failed (exit {result.exit_code}). Args: {args}",
70
70
  exit_code=result.exit_code,
71
71
  stdout=stdout,
72
72
  stderr=stderr,
@@ -76,7 +76,7 @@ def run_command(args: list[str]) -> Any:
76
76
  output = (result.output or "").strip()
77
77
  if not output:
78
78
  raise RuntimeError(
79
- f"sourcecode command produced no output.\n"
79
+ f"ask command produced no output.\n"
80
80
  f"Args: {args}"
81
81
  )
82
82
 
sourcecode/mcp/server.py CHANGED
@@ -108,14 +108,14 @@ def _coerce_cli_error(exc: Exception, default_message: str) -> CallToolResult:
108
108
  and "pro" in payload.get("error", "").lower()
109
109
  ):
110
110
  feature = payload.get("feature", "")
111
- msg = payload.get("message", f"'{feature}' requires a Pro license. Run: sourcecode activate <key>")
111
+ msg = payload.get("message", f"'{feature}' requires a Pro license. Run: ask activate <key>")
112
112
  structured = {
113
113
  "success": False,
114
114
  "data": None,
115
115
  "error": build_error_object(
116
116
  "PRO_REQUIRED",
117
117
  msg,
118
- hint="sourcecode activate <license_key>",
118
+ hint="ask activate <license_key>",
119
119
  expected="Active Pro license.",
120
120
  ),
121
121
  }
@@ -627,7 +627,7 @@ def get_compact_context(repo_path: str = ".", git_context: bool = False) -> dict
627
627
  Includes security_surface, mybatis, and transactional_boundaries for Java/Spring projects.
628
628
  For richer machine-oriented detail (deeper signals, more sections), use get_agent_context.
629
629
 
630
- Maps to: sourcecode <repo_path> --compact [--git-context]
630
+ Maps to: ask <repo_path> --compact [--git-context]
631
631
  repo_path: absolute path to the repository (default: current working directory).
632
632
  git_context: include git log and branch context in the analysis.
633
633
  """
@@ -661,7 +661,7 @@ def get_agent_context(repo_path: str = ".", git_context: bool = False) -> dict:
661
661
  architecture layers, security surface, transactional boundaries, module graph summary.
662
662
  Prefer get_compact_context for quick orientation or token-constrained workflows.
663
663
 
664
- Maps to: sourcecode <repo_path> --agent [--git-context]
664
+ Maps to: ask <repo_path> --agent [--git-context]
665
665
  repo_path: absolute path to the repository (default: current working directory).
666
666
  git_context: include git log and branch context in the analysis.
667
667
  """
@@ -696,7 +696,7 @@ def get_endpoints(repo_path: str = ".") -> dict:
696
696
  Do NOT call this on non-Java repositories — it will return empty results.
697
697
  Use get_compact_context or get_agent_context for non-Java repos.
698
698
 
699
- Maps to: sourcecode endpoints <repo_path>
699
+ Maps to: ask endpoints <repo_path>
700
700
  Returns: endpoints list with method, path, controller, handler fields;
701
701
  security dict always present (policy: roles_allowed|permit_all|deny_all|
702
702
  authenticated|...|none_detected); none_detected = no auth annotation found.
@@ -733,7 +733,7 @@ def get_spring_audit(repo_path: str = ".", scope: str = "all") -> dict:
733
733
 
734
734
  Do NOT call this on non-Java repositories — it will return spring_detected=false.
735
735
 
736
- Maps to: sourcecode spring-audit <repo_path> --scope <scope>
736
+ Maps to: ask spring-audit <repo_path> --scope <scope>
737
737
  Returns: SpringAuditResult with schema_version, spring_detected, scope, summary,
738
738
  findings list (id, pattern_id, category, severity, confidence, title,
739
739
  symbol, source_file, evidence, explanation, fix_hint), limitations, metadata.
@@ -790,7 +790,7 @@ def get_migration_readiness(repo_path: str = ".", min_severity: str = "low") ->
790
790
  the goal is migration planning — not ongoing audit.
791
791
  Do NOT call on non-Java repositories — returns readiness_score=null (N/A) with no findings.
792
792
 
793
- Maps to: sourcecode migrate-check <repo_path> --min-severity <min_severity>
793
+ Maps to: ask migrate-check <repo_path> --min-severity <min_severity>
794
794
  Returns: MigrationReport with schema_version, readiness_score (0–100, or null=N/A when no migration target applies; 100=ready to migrate),
795
795
  jakarta_readiness / boot3_readiness / jdk_modernization / hibernate_readiness
796
796
  (per-dimension 0–100), headline_blocker (e.g. "hibernate_rewrite" or null),
@@ -847,7 +847,7 @@ def get_impact_chain(repo_path: str = ".", symbol: str = "", depth: int = 4) ->
847
847
 
848
848
  Do NOT call this on non-Java repositories — it will return resolution=not_found.
849
849
 
850
- Maps to: sourcecode impact-chain <symbol> <repo_path> [--depth <depth>]
850
+ Maps to: ask impact-chain <symbol> <repo_path> [--depth <depth>]
851
851
  Returns: ImpactChainResult with schema_version, symbol, resolution,
852
852
  direct_callers, indirect_callers, endpoints_affected,
853
853
  transaction_boundary (propagation/isolation/read_only),
@@ -901,7 +901,7 @@ def get_impact_chain(repo_path: str = ".", symbol: str = "", depth: int = 4) ->
901
901
  def get_module_context(repo_path: str = ".", module: str = "") -> dict:
902
902
  """Compact analysis of a specific module or subdirectory within a repository.
903
903
 
904
- Maps to: sourcecode <repo_path>/<module> --compact
904
+ Maps to: ask <repo_path>/<module> --compact
905
905
  repo_path: absolute path to the repository root.
906
906
  module: subdirectory name relative to repo_path (e.g. 'src/auth', 'api', 'core').
907
907
  """
@@ -944,7 +944,7 @@ def _auto_since(repo_path: str) -> str:
944
944
  def get_delta(repo_path: str = ".", since: str = "") -> dict:
945
945
  """Incremental context: git-changed files since a reference commit.
946
946
 
947
- Maps to: sourcecode prepare-context delta <repo_path> --since <since>
947
+ Maps to: ask prepare-context delta <repo_path> --since <since>
948
948
  repo_path: absolute path to the repository (default: current working directory).
949
949
  since: git ref to diff against (e.g. HEAD~3, main, origin/main).
950
950
  If empty or omitted, auto-detects merge-base with origin/main (or
@@ -1055,12 +1055,12 @@ def check_freshness(repo_path: str = ".") -> dict:
1055
1055
  def get_ir_summary(repo_path: str = ".") -> dict:
1056
1056
  """Deterministic symbol-level IR summary for Java repositories. Java only.
1057
1057
 
1058
- Maps to: sourcecode repo-ir <repo_path> --summary-only
1058
+ Maps to: ask repo-ir <repo_path> --summary-only
1059
1059
  Returns: reverse_graph (top 10 hubs), route_surface (top 50 endpoints),
1060
1060
  subsystems (top 15), impact, analysis. Full graph nodes/edges omitted.
1061
1061
 
1062
1062
  Output is bounded to ~100 KB for LLM safety. For full IR (can exceed 10 MB
1063
- on large repos), use the CLI: sourcecode repo-ir <path> --output ir.json
1063
+ on large repos), use the CLI: ask repo-ir <path> --output ir.json
1064
1064
  Use get_compact_context or get_agent_context for non-Java repos.
1065
1065
 
1066
1066
  IR access paths (for full IR via CLI):
@@ -1097,7 +1097,7 @@ def get_ir_summary(repo_path: str = ".") -> dict:
1097
1097
  def fix_bug_context(repo_path: str = ".", symptom: str = "") -> dict:
1098
1098
  """Risk-ranked files for bug investigation, optionally focused by symptom.
1099
1099
 
1100
- Maps to: sourcecode prepare-context fix-bug <repo_path> [--symptom <symptom>]
1100
+ Maps to: ask prepare-context fix-bug <repo_path> [--symptom <symptom>]
1101
1101
  Includes compact_base: security_surface, transactional_boundaries, spring_profiles.
1102
1102
  repo_path: absolute path to the repository (default: current working directory).
1103
1103
  symptom: optional error message or class name to focus the file ranking
@@ -1126,7 +1126,7 @@ def fix_bug_context(repo_path: str = ".", symptom: str = "") -> dict:
1126
1126
  def review_pr_context(repo_path: str = ".", since: str = "") -> dict:
1127
1127
  """Execution paths and risk analysis for changed files in a pull request.
1128
1128
 
1129
- Maps to: sourcecode prepare-context review-pr <repo_path> [--since <since>]
1129
+ Maps to: ask prepare-context review-pr <repo_path> [--since <since>]
1130
1130
  Returns: compact_base + execution_paths (diff-scoped) + hotspots for changed files.
1131
1131
  repo_path: absolute path to the repository (default: current working directory).
1132
1132
  since: git ref to diff against (e.g. HEAD~3, main, origin/main).
@@ -1155,7 +1155,7 @@ def review_pr_context(repo_path: str = ".", since: str = "") -> dict:
1155
1155
  def onboard_context(repo_path: str = ".") -> dict:
1156
1156
  """Onboarding context: structured overview for new contributors.
1157
1157
 
1158
- Maps to: sourcecode prepare-context onboard <repo_path>
1158
+ Maps to: ask prepare-context onboard <repo_path>
1159
1159
  repo_path: absolute path to the repository (default: current working directory).
1160
1160
  """
1161
1161
  _raw = repo_path
@@ -1178,7 +1178,7 @@ def onboard_context(repo_path: str = ".") -> dict:
1178
1178
  def explain_context(repo_path: str = ".") -> dict:
1179
1179
  """Architecture and entry-point explanation for a repository.
1180
1180
 
1181
- Maps to: sourcecode prepare-context explain <repo_path>
1181
+ Maps to: ask prepare-context explain <repo_path>
1182
1182
  Returns: project summary, architecture, entry points, key dependencies.
1183
1183
  repo_path: absolute path to the repository (default: current working directory).
1184
1184
  """
@@ -1202,7 +1202,7 @@ def explain_context(repo_path: str = ".") -> dict:
1202
1202
  def refactor_context(repo_path: str = ".") -> dict:
1203
1203
  """Structural issues and refactor opportunities for a repository.
1204
1204
 
1205
- Maps to: sourcecode prepare-context refactor <repo_path>
1205
+ Maps to: ask prepare-context refactor <repo_path>
1206
1206
  Returns: structural issues, coupling hotspots, improvement opportunities.
1207
1207
  repo_path: absolute path to the repository (default: current working directory).
1208
1208
  """
@@ -1226,7 +1226,7 @@ def refactor_context(repo_path: str = ".") -> dict:
1226
1226
  def generate_tests_context(repo_path: str = ".", include_all: bool = False) -> dict:
1227
1227
  """Untested source files and test gap analysis for a repository.
1228
1228
 
1229
- Maps to: sourcecode prepare-context generate-tests <repo_path> [--all]
1229
+ Maps to: ask prepare-context generate-tests <repo_path> [--all]
1230
1230
  Returns: test_gaps list of untested files ranked by risk.
1231
1231
  On large repos (>2000 classes) analysis is bounded by SOURCECODE_TESTS_TIMEOUT_MS
1232
1232
  (default: 15000 ms). If timeout elapses, returns truncated=true with partial results.
@@ -1279,7 +1279,7 @@ def generate_tests_context(repo_path: str = ".", include_all: bool = False) -> d
1279
1279
  def get_impact_context(repo_path: str = ".", target: str = "", depth: int = 4) -> dict:
1280
1280
  """Blast-radius analysis: who calls a class and what breaks if it changes? Java only.
1281
1281
 
1282
- Maps to: sourcecode impact <target> <repo_path> [--depth <depth>]
1282
+ Maps to: ask impact <target> <repo_path> [--depth <depth>]
1283
1283
  Returns: direct_callers, indirect_callers, endpoints_affected,
1284
1284
  transactional_boundaries_touched, risk_score, risk_level, stats.
1285
1285
 
@@ -1334,7 +1334,7 @@ def get_impact_context(repo_path: str = ".", target: str = "", depth: int = 4) -
1334
1334
  def modernize_context(repo_path: str = ".", format: str = "json") -> dict:
1335
1335
  """Analyzes codebase for modernization opportunities: dead zones, hotspot scores, upgrade candidates.
1336
1336
 
1337
- Maps to: sourcecode modernize <repo_path>
1337
+ Maps to: ask modernize <repo_path>
1338
1338
  Returns: hotspot_candidates (high fan-in + git churn), statically_unreferenced (zero-caller classes — NOT confirmed dead; verify no framework dispatch) + framework_dispatched,
1339
1339
  high_coupling_nodes, subsystem_summary, cross_module_tangles, recommendation.
1340
1340
 
@@ -1368,9 +1368,9 @@ _TELEMETRY_ACTIONS = frozenset({"status", "enable", "disable"})
1368
1368
 
1369
1369
  @mcp.tool()
1370
1370
  def version() -> dict:
1371
- """Return sourcecode version and MCP compatibility metadata.
1371
+ """Return ASK Engine version and MCP compatibility metadata.
1372
1372
 
1373
- Maps to: sourcecode version
1373
+ Maps to: ask version
1374
1374
  Returns structured JSON: cli_version, mcp_schema_version, compatibility_schema_version.
1375
1375
  cli_version and mcp_schema_version are always identical (released together).
1376
1376
  """
@@ -1381,7 +1381,7 @@ def version() -> dict:
1381
1381
  def config() -> dict:
1382
1382
  """Show sourcecode CLI configuration.
1383
1383
 
1384
- Maps to: sourcecode config
1384
+ Maps to: ask config
1385
1385
  """
1386
1386
  return _execute(["config"])
1387
1387
 
@@ -1390,7 +1390,7 @@ def config() -> dict:
1390
1390
  def telemetry(action: str) -> dict:
1391
1391
  """Manage telemetry settings.
1392
1392
 
1393
- Maps to: sourcecode telemetry <action>
1393
+ Maps to: ask telemetry <action>
1394
1394
  action: one of "status" (show current state), "enable" (opt in), "disable" (opt out).
1395
1395
  Valid values: "status" | "enable" | "disable"
1396
1396
  """
sourcecode/mcp_nudge.py CHANGED
@@ -26,7 +26,7 @@ _FLAG: Path = Path.home() / ".sourcecode" / "nudge_shown"
26
26
 
27
27
  _MSG = (
28
28
  "→ Claude Desktop detected. "
29
- "Run `sourcecode mcp init` to enable agent integration.\n"
29
+ "Run `ask mcp init` to enable agent integration.\n"
30
30
  )
31
31
 
32
32
  # Module-level imports so names are patchable in tests.
@@ -5648,7 +5648,7 @@ def compute_blast_radius(
5648
5648
  "message": (
5649
5649
  f"No symbol matching {target!r} found in IR. "
5650
5650
  "Verify the class name or FQN. "
5651
- "Run `sourcecode repo-ir <repo> --output ir.json` to inspect available symbols."
5651
+ "Run `ask repo-ir <repo> --output ir.json` to inspect available symbols."
5652
5652
  ),
5653
5653
  "direct_callers": [],
5654
5654
  "indirect_callers": [],
sourcecode/ris.py CHANGED
@@ -506,7 +506,7 @@ def get_cold_start_context(repo_root: Path) -> dict:
506
506
  if not endpoints and _is_java:
507
507
  result["endpoints_hint"] = (
508
508
  "Java repo detected but no endpoint index found. "
509
- "Call get_endpoints (or: sourcecode endpoints <path>) to populate."
509
+ "Call get_endpoints (or: ask endpoints <path>) to populate."
510
510
  )
511
511
  return result
512
512
  except Exception: