sourcecode 2.3.0__tar.gz → 2.4.0__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-2.3.0 → sourcecode-2.4.0}/CHANGELOG.md +53 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/PKG-INFO +1 -1
- {sourcecode-2.3.0 → sourcecode-2.4.0}/pyproject.toml +1 -1
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/__init__.py +1 -1
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/cli.py +62 -1
- sourcecode-2.4.0/src/sourcecode/context_cache.py +637 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/explain.py +24 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/.gitignore +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/.ruff.toml +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/CONTRIBUTING.md +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/LICENSE +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/README.md +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/SECURITY.md +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/raw +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/scripts/compare_integration_engines.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/scripts/customer_smoke_test.sh +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/scripts/generate_jdk_exports.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/archetype.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/cache.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/call_surface.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/caller_metrics.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/canonical_ir.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/cir_graphs.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/classifier.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/confidence_analyzer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/context_graph.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/contract_pipeline.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/dynamic_argument_surface.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/endpoint_literals.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/endpoint_metrics.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/error_schema.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/evidence_provider.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/file_chunker.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/file_classifier.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/format_contract.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/fqn_utils.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/graph_evidence.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/hibernate_strat.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/jdk_exports.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/license.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/mcp/__init__.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/mcp/onboarding/__init__.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/mcp/onboarding/applier.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/mcp/onboarding/backup.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/mcp/onboarding/detector.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/mcp/onboarding/planner.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/mcp/orchestrator.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/mcp/registry.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/mcp/runner.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/mcp/server.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/mcp_nudge.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/migrate_check.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/openapi_surface.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/output_budget.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/path_filters.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/pr_comment_renderer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/pr_impact.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/prepare_context.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/progress.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/ranking_engine.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/redactor.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/rename_refactor.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/repository_ir.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/ris.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/scanner.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/schema.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/security_config.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/security_posture.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/semantic_impact_engine.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/semantic_integration_engine.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/semantic_services.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/serializer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/spring_event_topology.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/spring_findings.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/spring_impact.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/spring_model.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/spring_security_audit.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/spring_semantic.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/spring_tx_analyzer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/type_usage_surface.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/validation_inference.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/validation_surface.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/version_check.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/src/sourcecode/workspace.py +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/supabase/functions/README.md +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/supabase/functions/get-license/index.ts +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/supabase/functions/lemonsqueezy-webhook/index.ts +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/supabase/functions/telemetry/index.ts +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/supabase/sql/license_event_ordering.sql +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/supabase/sql/licensing_schema.sql +0 -0
- {sourcecode-2.3.0 → sourcecode-2.4.0}/supabase/sql/telemetry_events.sql +0 -0
|
@@ -1,5 +1,58 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.4.0] — 2026-07-12
|
|
4
|
+
|
|
5
|
+
**AI Context Cache — a provider-agnostic cache for ASK's reusable Knowledge
|
|
6
|
+
Context.** This is *not* a prompt cache: it never stores prompts, generated text,
|
|
7
|
+
or LLM responses. It caches the structured knowledge ASK derives from source —
|
|
8
|
+
so expensive commands stop re-parsing the same repository on every run. The cache
|
|
9
|
+
belongs entirely to ASK and is consumed identically by any AI provider (GPT,
|
|
10
|
+
Claude, Gemini, local models) or none at all; the LLM never participates in
|
|
11
|
+
producing or reading it.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **`context_cache.py` — the AI Context Cache component.** Operates at the
|
|
16
|
+
*knowledge* level: it caches the reusable Canonical IR (the expensive Java
|
|
17
|
+
parse) keyed **only by knowledge state**, never by command or prompt. The key
|
|
18
|
+
is `worktree_signature + KL_SCHEMA_VERSION + PRODUCER_VERSION + scope`, where
|
|
19
|
+
`worktree_signature` is the committed HEAD folded with a hash of the working-tree
|
|
20
|
+
diff when dirty — so a new commit *or* an uncommitted edit deterministically
|
|
21
|
+
invalidates the entry rather than serving stale context. Invalidation is
|
|
22
|
+
state-based, never TTL-based for correctness (TTL and a max-entry cap exist only
|
|
23
|
+
as cleanup). Entries are gzip'd, inspectable envelopes (no opaque blobs);
|
|
24
|
+
persistence survives across executions under `~/.sourcecode/context-cache/`.
|
|
25
|
+
- **`get_or_build_cir()` — the reusable-knowledge entry point.** Builds the
|
|
26
|
+
Canonical IR once and, on a hit, rebuilds the full CIR cheaply from the cached
|
|
27
|
+
raw IR via `ir_dict_to_canonical` — skipping the parse entirely, with the
|
|
28
|
+
`cir_hash` verified equal so the rebuilt CIR is provably faithful. Because the
|
|
29
|
+
key is command-agnostic, every command that needs a CIR shares one entry: once
|
|
30
|
+
wired, `impact` / `review-pr` / `modernize` reuse it for free.
|
|
31
|
+
- **`CachedContext`** — an inspectable structured record (`metadata`, `entities`,
|
|
32
|
+
`evidence`, `observations`, `summaries`, `graph_metrics`, `payload`,
|
|
33
|
+
`timestamps`, `producer_version`). Advisory metrics are tracked from day one:
|
|
34
|
+
hits, misses, invalidations, stores, hit ratio, average lookup/build time, bytes
|
|
35
|
+
stored, contexts reused.
|
|
36
|
+
- **`ask cache context-stats` / `ask cache context-clear`** — observability and
|
|
37
|
+
management for the context cache, kept distinct from the existing snapshot-cache
|
|
38
|
+
`cache status` / `cache clear` so neither clobbers the other.
|
|
39
|
+
- **`ask explain` is the first consumer.** It fetches its CIR through
|
|
40
|
+
`get_or_build_cir` and derives the class explanation cheaply from the shared
|
|
41
|
+
knowledge; each run reports `Context cache: HIT/MISS` with timing. Output is
|
|
42
|
+
byte-identical whether served from cache or a fresh build.
|
|
43
|
+
|
|
44
|
+
### Notes
|
|
45
|
+
|
|
46
|
+
- **Only `explain` is wired** — a deliberate reference integration to validate the
|
|
47
|
+
design before connecting `impact` / `onboard` / `prepare-context` / `archetype` /
|
|
48
|
+
`review-pr` / `modernize`. The SourceMap-based commands (`onboard`,
|
|
49
|
+
`prepare-context`, `archetype`) will use a separate cache scope.
|
|
50
|
+
- No AI-provider-specific logic, no embeddings, no RAG, no prompt/response caching.
|
|
51
|
+
- Env vars: `SOURCECODE_CONTEXT_CACHE_{DIR,DISABLE,TTL_DAYS,MAX_ENTRIES}`.
|
|
52
|
+
- Tests: `tests/test_context_cache.py` adds 23 tests (hit/miss, commit/dirty/version
|
|
53
|
+
invalidation, persistence, corruption recovery, concurrency, TTL GC, CIR
|
|
54
|
+
round-trip fidelity, cross-command reuse). No report or behaviour cutover.
|
|
55
|
+
|
|
3
56
|
## [2.3.0] — 2026-07-12
|
|
4
57
|
|
|
5
58
|
**Module graph promoted to a first-class Evidence Provider for architectural
|
|
@@ -5341,6 +5341,7 @@ def explain_cmd(
|
|
|
5341
5341
|
from sourcecode.context_graph import ContextGraph
|
|
5342
5342
|
from sourcecode.spring_model import SpringSemanticModel
|
|
5343
5343
|
from sourcecode.explain import explain_class
|
|
5344
|
+
from sourcecode import context_cache as _ctxcache
|
|
5344
5345
|
|
|
5345
5346
|
if not class_name.strip():
|
|
5346
5347
|
_emit_error_json(
|
|
@@ -5383,14 +5384,27 @@ def explain_cmd(
|
|
|
5383
5384
|
)
|
|
5384
5385
|
raise typer.Exit(code=1)
|
|
5385
5386
|
|
|
5387
|
+
# AI Context Cache — operates at the *knowledge* level: it caches the
|
|
5388
|
+
# reusable Canonical IR (the expensive Java parse), keyed only by knowledge
|
|
5389
|
+
# state, not by command. explain then derives its answer cheaply from that
|
|
5390
|
+
# shared CIR. The same cached CIR is reused for free by any other command.
|
|
5391
|
+
# Provider-agnostic and best-effort: any fault degrades to a fresh build.
|
|
5386
5392
|
_prog = Progress()
|
|
5387
5393
|
_prog.start(f"explaining {class_name} ({len(file_list)} files)")
|
|
5394
|
+
_cc_look = None
|
|
5388
5395
|
try:
|
|
5389
|
-
|
|
5396
|
+
try:
|
|
5397
|
+
cir, _cc_look = _ctxcache.get_or_build_cir(
|
|
5398
|
+
_resolve_repo_root(target), target, file_list
|
|
5399
|
+
)
|
|
5400
|
+
except Exception:
|
|
5401
|
+
cir = ContextGraph.build(file_list, target).cir # fallback: never break explain
|
|
5390
5402
|
model = SpringSemanticModel.build(cir)
|
|
5391
5403
|
explanation = explain_class(class_name, cir, model)
|
|
5392
5404
|
finally:
|
|
5393
5405
|
_prog.finish()
|
|
5406
|
+
if _cc_look is not None:
|
|
5407
|
+
typer.echo(_cc_look.render(), err=True)
|
|
5394
5408
|
|
|
5395
5409
|
if format == "json":
|
|
5396
5410
|
output = _json.dumps(explanation.to_dict(), indent=2, ensure_ascii=False)
|
|
@@ -7199,6 +7213,53 @@ def cache_freshness_cmd(
|
|
|
7199
7213
|
typer.echo(f"RIS updated: {result.get('ris_last_updated_at') or 'never'}")
|
|
7200
7214
|
|
|
7201
7215
|
|
|
7216
|
+
@cache_app.command("context-stats")
|
|
7217
|
+
def cache_context_stats_cmd(
|
|
7218
|
+
path: Path = typer.Argument(Path("."), help="Repository path (default: current directory)"),
|
|
7219
|
+
json_output: bool = typer.Option(False, "--json", help="Output as JSON."),
|
|
7220
|
+
) -> None:
|
|
7221
|
+
"""Show AI Context Cache statistics (structured-knowledge reuse metrics).
|
|
7222
|
+
|
|
7223
|
+
This is the provider-agnostic context cache — distinct from the snapshot
|
|
7224
|
+
cache reported by `ask cache status`. It measures reuse of ASK's structured
|
|
7225
|
+
context (entities/evidence/observations/summaries), never prompts or LLM output.
|
|
7226
|
+
"""
|
|
7227
|
+
from sourcecode import context_cache as _ctxcache
|
|
7228
|
+
target = _resolve_repo_root(Path(path))
|
|
7229
|
+
stats = _ctxcache.stats_for_repo(target)
|
|
7230
|
+
if json_output:
|
|
7231
|
+
import json as _j
|
|
7232
|
+
typer.echo(_j.dumps(stats, indent=2, ensure_ascii=False))
|
|
7233
|
+
else:
|
|
7234
|
+
typer.echo(f"Cache dir: {stats['cache_dir']}")
|
|
7235
|
+
typer.echo(f"Enabled: {stats['enabled']}")
|
|
7236
|
+
typer.echo(f"Contexts: {stats['contexts']}")
|
|
7237
|
+
typer.echo(f"Hits: {stats['hits']}")
|
|
7238
|
+
typer.echo(f"Misses: {stats['misses']}")
|
|
7239
|
+
typer.echo(f"Invalidations: {stats['invalidations']}")
|
|
7240
|
+
typer.echo(f"Stores: {stats['stores']}")
|
|
7241
|
+
typer.echo(f"Hit ratio: {stats['hit_ratio']}")
|
|
7242
|
+
typer.echo(f"Avg lookup: {stats['avg_lookup_ms']} ms")
|
|
7243
|
+
typer.echo(f"Avg build: {stats['avg_build_ms']} ms")
|
|
7244
|
+
typer.echo(f"Bytes stored: {stats['bytes_stored']}")
|
|
7245
|
+
typer.echo(f"KL version: {stats['kl_schema_version']} producer={stats['producer_version']}")
|
|
7246
|
+
|
|
7247
|
+
|
|
7248
|
+
@cache_app.command("context-clear")
|
|
7249
|
+
def cache_context_clear_cmd(
|
|
7250
|
+
path: Path = typer.Argument(Path("."), help="Repository path (default: current directory)"),
|
|
7251
|
+
yes: bool = typer.Option(False, "--yes", "-y", help="Skip confirmation prompt."),
|
|
7252
|
+
) -> None:
|
|
7253
|
+
"""Delete the AI Context Cache for a repository (structured context + stats)."""
|
|
7254
|
+
from sourcecode import context_cache as _ctxcache
|
|
7255
|
+
target = _resolve_repo_root(Path(path))
|
|
7256
|
+
if not yes and sys.stdin.isatty():
|
|
7257
|
+
import click as _click
|
|
7258
|
+
_click.confirm(f"Delete AI context cache for {target}?", abort=True, err=True)
|
|
7259
|
+
removed = _ctxcache.clear_for_repo(target)
|
|
7260
|
+
typer.echo(f"Removed {removed} context file(s).", err=True)
|
|
7261
|
+
|
|
7262
|
+
|
|
7202
7263
|
# ── Entry point ───────────────────────────────────────────────────────────────
|
|
7203
7264
|
|
|
7204
7265
|
def _stderr_is_interactive() -> bool:
|