sourcecode 2.0.0__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.
@@ -1,925 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: sourcecode
3
- Version: 2.0.0
4
- Summary: Persistent structural context and ultra-fast repeated analysis for AI coding agents
5
- License-File: LICENSE
6
- Keywords: agents,ai,codebase,context,developer-tools,llm
7
- Classifier: Development Status :: 4 - Beta
8
- Classifier: Environment :: Console
9
- Classifier: Intended Audience :: Developers
10
- Classifier: License :: OSI Approved :: Apache Software License
11
- Classifier: Operating System :: OS Independent
12
- Classifier: Programming Language :: Python :: 3
13
- Classifier: Programming Language :: Python :: 3.9
14
- Classifier: Programming Language :: Python :: 3.10
15
- Classifier: Programming Language :: Python :: 3.11
16
- Classifier: Programming Language :: Python :: 3.12
17
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
- Classifier: Topic :: Utilities
19
- Requires-Python: >=3.9
20
- Requires-Dist: defusedxml>=0.7
21
- Requires-Dist: mcp>=1.0.0
22
- Requires-Dist: pathspec>=1.0
23
- Requires-Dist: ruamel-yaml>=0.18
24
- Requires-Dist: tomli>=2.0; python_version < '3.11'
25
- Requires-Dist: typer>=0.24
26
- Provides-Extra: ast
27
- Requires-Dist: tree-sitter-javascript>=0.21; extra == 'ast'
28
- Requires-Dist: tree-sitter-typescript>=0.21; extra == 'ast'
29
- Requires-Dist: tree-sitter>=0.21; extra == 'ast'
30
- Provides-Extra: dev
31
- Requires-Dist: mcp>=1.0.0; extra == 'dev'
32
- Requires-Dist: mypy>=1.10; extra == 'dev'
33
- Requires-Dist: pytest>=8; extra == 'dev'
34
- Requires-Dist: ruff>=0.15; extra == 'dev'
35
- Provides-Extra: mcp
36
- Requires-Dist: mcp>=1.0.0; extra == 'mcp'
37
- Description-Content-Type: text/markdown
38
-
39
- # ASK Engine
40
-
41
- **Persistent structural context and ultra-fast repeated analysis for AI coding agents.**
42
-
43
- ![Version](https://img.shields.io/badge/version-2.0.0-blue)
44
- ![Python](https://img.shields.io/badge/python-3.9%2B-green)
45
-
46
- > **ASK Engine** is the product. The CLI command is **`ask`**. The legacy
47
- > **`sourcecode`** command still works as a deprecated compatibility alias (it prints
48
- > a one-line notice and forwards to `ask`) and remains the Python/PyPI package name
49
- > for now. The authoritative version is whatever `ask version` reports. See
50
- > [docs/PRODUCT_IDENTITY.md](docs/PRODUCT_IDENTITY.md).
51
-
52
- ---
53
-
54
- ## The problem
55
-
56
- Every time an AI coding agent starts a new session, it has to re-parse the repository from scratch. For a large Java or TypeScript monolith, that means 5–15 seconds per invocation. Multiply by dozens of agent turns per hour, and repo context acquisition becomes a real bottleneck — not just latency, but tokens, compute, and iteration velocity.
57
-
58
- ASK Engine solves this with a persistent structural cache keyed on file content hashes. After the first scan, every subsequent invocation returns pre-built context in milliseconds. The repo doesn't change? The cache doesn't expire.
59
-
60
- **The cache is not a performance optimization. It is what makes ASK Engine usable as infrastructure rather than a one-off tool.**
61
-
62
- ---
63
-
64
- ## Cache performance — measured on real repos
65
-
66
- | Repo | Size | Cold scan | Cache hit | Speedup |
67
- |------|------|-----------|-----------|---------|
68
- | Keycloak | 7,885 Java files | 10.5s | 0.6s | **~17x** |
69
- | BroadleafCommerce | 2,985 Java files | 2.7s | 0.3s | **~9x** |
70
-
71
- Cache keyed on content hashes — invalidated only when source changes. On repeated agent sessions against the same codebase, nearly every invocation is a cache hit.
72
-
73
- **Token output (measured):**
74
-
75
- | Mode | BroadleafCommerce | Keycloak |
76
- |------|------------------|---------|
77
- | `--compact` | ~2,900 | ~4,000 |
78
- | `--agent` | ~4,800 | ~5,500 |
79
- | `onboard` | ~2,600 | n/a |
80
- | `fix-bug` (trimmed) | ~27,000 | ~4,600 |
81
-
82
- ---
83
-
84
- ## What changes at 0.3s vs 2.7s
85
-
86
- At 2.7s per call, you use ASK Engine to occasionally inspect a repo.
87
-
88
- At 0.3s per call, you use ASK Engine as **constant infrastructure** inside agent loops:
89
-
90
- ```
91
- agent loop iteration:
92
- 1. ask . --compact # 0.3s — instant structural context
93
- 2. ask impact PaymentService . --depth 1 # 0.4s — blast radius check
94
- 3. agent makes targeted change
95
- 4. repeat
96
- ```
97
-
98
- Sub-second context retrieval changes the cost model for agent workflows. You can call ASK Engine before every edit, before every PR review, before every test run — without batching or caching calls manually.
99
-
100
- ---
101
-
102
- ## Installation
103
-
104
- ### Homebrew (macOS / Linux)
105
-
106
- ```bash
107
- brew tap haroundominique/sourcecode
108
- brew install sourcecode
109
- ```
110
-
111
- ### pip / pipx
112
-
113
- ```bash
114
- pip install sourcecode
115
- # or with isolation:
116
- pipx install sourcecode
117
- ```
118
-
119
- > **Package vs. command.** The install package is still named `sourcecode` this
120
- > release (renaming the PyPI/Homebrew distribution is a separate, breaking change).
121
- > Installing it gives you the canonical **`ask`** command plus the deprecated
122
- > **`sourcecode`** alias. A future release will publish `ask-engine` and drop the
123
- > alias.
124
-
125
- ### Verify
126
-
127
- ```bash
128
- ask version
129
- # ask 2.0.0
130
-
131
- # the deprecated alias still works (prints a one-line notice to stderr):
132
- sourcecode version
133
- ```
134
-
135
- ---
136
-
137
- ## Quickstart
138
-
139
- ```bash
140
- # High-signal summary — warm cache: ~0.3s, cold: 2–10s depending on repo size
141
- ask --compact
142
-
143
- # Add git hotspots and uncommitted file count
144
- ask --compact --git-context
145
-
146
- # Structured output for AI agents — bounded, noise-free, ready to inject
147
- ask --agent
148
-
149
- # Blast radius: what breaks if this class changes?
150
- ask impact OrderService /path/to/repo
151
-
152
- # Spring Boot 2→3 migration readiness: javax→jakarta blockers, removed APIs
153
- ask migrate-check /path/to/repo
154
-
155
- # Spring semantic audit: TX anomalies + security surface (free)
156
- ask spring-audit /path/to/repo
157
-
158
- # Impact chain: systemic blast radius with TX/SEC enrichment (free)
159
- ask impact-chain OrderService /path/to/repo
160
-
161
- # Event topology: publisher → event → consumer graph (free)
162
- ask impact-chain OrderPlacedEvent /path/to/repo --type events
163
-
164
- # REST endpoint surface
165
- ask endpoints /path/to/repo
166
-
167
- # Request-body validation per endpoint: constraints + custom validators (free)
168
- # Recovers constraints from the OpenAPI spec, or directly from Java DTO
169
- # bean-validation annotations when no spec is present.
170
- ask validation /path/to/repo
171
-
172
- # Onboard to an unfamiliar codebase
173
- ask onboard /path/to/repo
174
-
175
- # PR review: risk, test gaps, changed modules
176
- ask review-pr /path/to/repo --since main
177
-
178
- # Bug triage: risk-ranked files by symptom
179
- ask fix-bug /path/to/repo --symptom "NullPointerException in checkout"
180
- ```
181
-
182
- ---
183
-
184
- ## Cache system
185
-
186
- ASK Engine maintains a persistent cache at `.sourcecode-cache/` inside each repository. Two layers:
187
-
188
- - **L1 (core):** analysis result keyed by `(git_sha, analysis_flags)`. Survives format changes — you can regenerate `--compact` vs `--agent` views from the same core.
189
- - **L2 (view):** rendered output keyed by `(core_hash, view_flags)`. Exact output match — no recomputation.
190
-
191
- **Lookup order:** L2 exact hit → L1 hit + view rebuild → full cold scan
192
-
193
- **Cache invalidation:** Keyed on git commit SHA. Any commit invalidates the core cache for that repo. Uncommitted changes are not cached.
194
-
195
- ```bash
196
- # Inspect cache state
197
- ask cache status
198
-
199
- # Warm the cache ahead of an agent session
200
- ask cache warm
201
-
202
- # Clear cache
203
- ask cache clear
204
-
205
- # Check RIS freshness relative to current git HEAD
206
- ask cache freshness
207
- ```
208
-
209
- **`--no-cache`** bypasses both layers and forces a fresh scan. Use in CI or when you need to verify a fresh result.
210
-
211
- **Visibility:** Cache hits are silent. Use `ask cache status` to see cache size, hit keys, and last-warmed timestamp.
212
-
213
- ---
214
-
215
- ## Agent workflow patterns
216
-
217
- ### Start of session — structural grounding
218
-
219
- ```bash
220
- # Inject as first message to agent (bounded, deterministic)
221
- ask /repo --compact # ~2,500–4,000 tokens
222
- ask /repo --agent # ~4,500–5,500 tokens — more detail
223
- ask onboard /repo # task-structured: entry points, key files, gaps
224
- ```
225
-
226
- ### Before every change — blast radius + TX/SEC check
227
-
228
- ```bash
229
- # Always target the INTERFACE in Spring projects, not the implementation:
230
- ask impact OrderService /repo # ✓ 30 callers, 11 endpoints
231
- ask impact OrderServiceImpl /repo # ✗ 0 callers (Spring DI blindness)
232
-
233
- # Impact chain: blast radius enriched with TX boundary and security surfaces
234
- ask impact-chain OrderService /repo
235
-
236
- # Event topology: who publishes/consumes this event, and in what TX phase?
237
- ask impact-chain OrderPlacedEvent /repo --type events
238
-
239
- # Spring audit: catch TX anomalies before they hit production
240
- ask spring-audit /repo --scope tx
241
- ```
242
-
243
- ### Continuous agent loop — delta context
244
-
245
- ```bash
246
- # Only changed files + their transitive importers — minimal token cost:
247
- ask prepare-context delta /repo --since HEAD~1
248
- ask . --changed-only --git-context
249
- ```
250
-
251
- ### PR review — structured risk signal
252
-
253
- ```bash
254
- # JSON for programmatic use:
255
- ask review-pr /repo --since main --output review.json
256
- jq '.ci_decision' review.json # "analysis_success" | "git_ref_error"
257
-
258
- # Markdown for GitHub comment:
259
- ask review-pr /repo --since main --format github-comment
260
- ```
261
-
262
- ### Bug triage — symptom-driven
263
-
264
- ```bash
265
- # Specific symptoms produce the best signal:
266
- ask fix-bug /repo --symptom "OIDC token refresh fails after realm update"
267
- ask fix-bug /repo --symptom "NullPointerException in OrderService during checkout"
268
-
269
- # Generic symptoms produce noisy output — be specific.
270
- ask fix-bug /repo --symptom "payment timeout" --output triage.json
271
- ```
272
-
273
- ### In CI — cached, deterministic, fast
274
-
275
- ```bash
276
- # Content-hash cached — safe to run on every commit; cold only when code changes
277
- ask /repo --compact --output context.json
278
-
279
- # PR gate
280
- ask review-pr /repo --since $BASE_REF --output review.json
281
- DECISION=$(jq -r '.ci_decision' review.json)
282
- if [ "$DECISION" != "analysis_success" ]; then echo "Review failed: $DECISION"; fi
283
- ```
284
-
285
- ---
286
-
287
- ## What ASK Engine does (and doesn't)
288
-
289
- **ASK Engine reduces exploration cost.** It accelerates context acquisition and minimizes repeated repo parsing. It does not replace reading code — it reduces how often an agent needs to.
290
-
291
- Specifically:
292
-
293
- - Extracts structural signals: entry points, Spring roles, REST surfaces, dependency graphs, transactional boundaries
294
- - Builds and caches these on first scan; serves from cache on subsequent calls
295
- - Produces bounded, noise-free JSON designed for direct injection into agent context windows
296
- - Computes blast radius (impact graph) from a class or interface, traversing reverse dependencies
297
-
298
- **What it does NOT do:**
299
-
300
- - No runtime analysis — all signals are static (annotation, import graph, file structure)
301
- - No semantic code understanding — reads structure, not logic
302
- - No replacement for reading code — reduces how often that's needed, not whether
303
- - Architecture pattern detection best for Spring MVC layered apps; SPI/plugin architectures (e.g. Quarkus extension model) may be misclassified
304
- - Endpoint recall for JAX-RS subresource locator pattern is ~65%
305
- - `impact` on implementation classes (e.g. `OrderServiceImpl`) returns 0 callers in Spring Boot — callers inject the interface via `@Autowired`. Always target the interface. When `direct_callers: []` with `confidence_level: high` for a `@Service` class, re-query the interface.
306
- - `no_security_signal` on endpoints means no recognized method-level annotation found — does **not** mean the endpoint is unsecured. Projects using Spring Security filter chains show 100% `no_security_signal` even when fully secured. Projects using a custom authorization annotation can teach the scanner via [`sourcecode.config.json`](#sourcecodeconfigjson-repo-root).
307
- - `spring-audit` and `impact-chain` are **Java/Spring only** — non-Java repos return `spring_detected: false`
308
- - Event topology via `--type events` does not resolve Kafka/RabbitMQ/Redis message routes — only Spring ApplicationEvent and `@EventListener` chains
309
- - Self-invocation TX bypass (calling `@Transactional` method from the same class without going through the proxy) is not detected
310
-
311
- ---
312
-
313
- ## Pricing
314
-
315
- > **🎉 Early-adoption: Pro is currently unlocked for everyone.** During this phase
316
- > every install runs with full Pro entitlements — no size gate, no key required. The
317
- > tiers below describe the model the paywall will return to later.
318
-
319
- Two tiers. **Gating is by repo size and automation — never by command.** Every
320
- command runs at full power on Free for small and mid-size repos. You upgrade
321
- when the work gets bigger or automated.
322
-
323
- | | **Free** — €0 | **Pro** — €19/mo · €190/yr per dev |
324
- |---|---|---|
325
- | Repo size | ≤ 500 Java source files | **> 500 Java files** (enterprise monoliths) |
326
- | Commands | All of them, full output | Same commands, unlocked at scale |
327
- | `impact` / `fix-bug` / `review-pr` / `modernize` | ✅ full on small repos | ✅ full on large repos (Free gets a capped preview) |
328
- | `--full`, git-churn ranking, uncapped graph/semantic | ✅ on small repos | ✅ on large repos |
329
- | `prepare-context delta` | 30 free runs/repo | unlimited — CI/CD automation |
330
- | `prepare-context generate-tests` | small repos | large repos |
331
- | MCP local server (`mcp serve`) | ✅ | ✅ |
332
- | Offline, no data egress, no account | ✅ | ✅ |
333
-
334
- **Non-Java repos are free at any size** — the size limit counts Java source
335
- files only, by design. ASK Engine monetises enterprise Java monoliths.
336
-
337
- ```bash
338
- ask activate <key> # activate a license key
339
- ```
340
-
341
- Full breakdown: [docs/PRODUCT_TIERS.md](docs/PRODUCT_TIERS.md).
342
-
343
- ---
344
-
345
- ## Command reference
346
-
347
- ### `--compact` and `--agent`
348
-
349
- Core flags. Feed directly to AI agents as first-message context.
350
-
351
- | Flag | Output | Tokens |
352
- |------|--------|--------|
353
- | `--compact` | High-signal summary: stacks, entry points, dependencies, confidence, gaps | ~2,500–4,000 |
354
- | `--agent` | Structured JSON: identity, entry points, architecture, event flows | ~4,500–5,500 |
355
-
356
- ### `impact` — blast-radius analysis [free ≤500 Java files · Pro above]
357
-
358
- ```bash
359
- ask impact ClassName /path/to/repo
360
- ask impact org.example.OrderService /path/to/repo # FQN also accepted
361
- ask impact OrderService . --depth 2 # limit BFS depth
362
- ```
363
-
364
- | Field | Description |
365
- |-------|-------------|
366
- | `direct_callers` | Classes that directly import or inject the target |
367
- | `indirect_callers` | Transitive callers up to `--depth` (default: 4) |
368
- | `endpoints_affected` | HTTP endpoints whose call chain includes the target |
369
- | `transactional_boundaries_touched` | `@Transactional` classes in the blast cone |
370
- | `mappers_affected` | `@Repository` / `@Mapper` / DAO classes in the blast cone |
371
- | `security_surface_affected` | Security policies on affected endpoints |
372
- | `cross_module_impact` | Subsystems touched, ordered by affected symbol count |
373
- | `risk_score` | 0–100 quantified change risk |
374
- | `confidence_score` | 0–1 confidence in the analysis |
375
- | `explanation` | Human-readable risk summary |
376
- | `candidates` | On partial match: up to 10 FQNs ranked by relevance |
377
-
378
- **Best practices:**
379
- - Target **interfaces**, not implementations: `impact OrderService` > `impact OrderServiceImpl`
380
- - Use `--depth 1` when target has 200+ callers — direct endpoints are already the most actionable signal
381
- - Second `impact` run on the same repo is significantly faster (cache applies to underlying IR scan)
382
-
383
- ### `endpoints` — REST API surface
384
-
385
- ```bash
386
- ask endpoints /path/to/repo
387
- ask endpoints /path/to/repo --output endpoints.json
388
- ask endpoints /path/to/repo --by-controller
389
- ```
390
-
391
- Extracts all Spring MVC (`@GetMapping`, `@PostMapping`, `@RequestMapping`, etc.) and JAX-RS (`@GET`, `@POST`, `@Path`) endpoint methods. Returns HTTP method, path, controller class, and handler method. Each endpoint also carries its `return_type`. `--by-controller` groups the surface per controller (`{by_controller, controller_count, total}`) for an API-surface view.
392
-
393
- **Functional / WebFlux routing (honest limitation).** Routes registered via the functional DSL — `route().GET("/path", handler)` / `RouterFunction` / `CustomEndpoint`, common in reactive Spring apps — are **not** modeled (their real paths depend on `nest()`/group-version prefixes that can't be resolved statically). Rather than emit partial paths that would mislead, the output reports a `functional_routing` block (`files`, `route_registrations`, `modeled: false`) plus a warning. When the annotation surface is empty but functional routes exist, the warning explicitly tells you not to read it as "no endpoints". Annotation-based (MVC/JAX-RS) repos are unaffected.
394
-
395
- **Non-Spring REST frameworks (never "no API").** When the Spring-MVC surface is empty but the repo exposes REST another way — Alfresco WebScripts (`*.desc.xml` descriptors + classes extending `AbstractWebScript`/`DeclarativeWebScript`), JAX-RS, or mapped Servlets — `security_model` is reported as `"undetermined"` (never `"unknown"`, which downstream reads as "no security"), a `non_spring_rest_surface` block names the detected frameworks, and a warning states the surface is unmodeled. `total: 0` therefore can never be read as "this application exposes no API".
396
-
397
- **Custom security annotations.** Enterprise repos often guard endpoints with a bespoke annotation instead of `@PreAuthorize`/`@Secured`. Drop a `sourcecode.config.json` at the repo root to teach the scanner about it — otherwise those endpoints report `policy: "none_detected"`:
398
-
399
- ```json
400
- {
401
- "customSecurityAnnotations": [
402
- {
403
- "fullyQualifiedName": "com.example.security.M3FiltroSeguridad",
404
- "shortName": "M3FiltroSeguridad",
405
- "resourceParam": "nombreRecurso",
406
- "levelParam": "nivelRequerido"
407
- }
408
- ]
409
- }
410
- ```
411
-
412
- Matching endpoints then report `policy: "custom"` with `annotation`, `resourceName`, and `requiredLevel`, and are no longer counted in `no_security_signal`. Repos without the config behave exactly as before.
413
-
414
- ### `export` — architecture views for downstream tooling
415
-
416
- ```bash
417
- ask export /path/to/repo --by-directory # code map, path:line refs
418
- ask export /path/to/repo --module-graph # module→module dependencies
419
- ask export /path/to/repo --integrations # outbound HTTP/LDAP/JMS clients
420
- ask export /path/to/repo --c4 # unified architecture + manifest
421
- ```
422
-
423
- Emits **structured, tool-agnostic** codebase views as plain JSON/YAML — the kind of input an architecture-doc generator, diagram renderer, or code-search agent can consume directly instead of walking the tree file by file. Section labels map to the open [C4 model](https://c4model.com) (an open architecture notation, not a product); the schema is vendor-neutral.
424
-
425
- | Flag | Output |
426
- |------|--------|
427
- | `--by-directory` | One group per source directory, each symbol with a `source_file:line` reference. |
428
- | `--module-graph` | `{nodes, edges, summary}` — directories as modules, inter-module dependencies rolled up from class-level relation edges with hit counts + edge types. |
429
- | `--integrations` | Outbound integrations across Spring **and** plain-Java/Jakarta stacks: HTTP (`RestTemplate`, `WebClient`, `@FeignClient`, JDK `HttpClient`, Apache, OkHttp), LDAP (`LdapTemplate`, JNDI `InitialDirContext`/`LdapContext`), SMTP (`JavaMailSender`, JavaMail `Transport`/`MimeMessage`), and JMS — with `file:line` evidence and a literal `target` when present. Emits an explicit `confidence` (`observed` / `not_analyzed`), a structured `coverage_confidence` (`low` / `partial` / `high`) with `coverage_confidence_reason`, and a prose `coverage_note`: a count of `0` — or a low count on a large repo (≥300 files, <10 constructs) — is flagged `low`, so a low count is never read as low external coupling (custom protocol/SPI clients are not statically visible). |
430
- | `--c4` | Unified document: `c4.{context, containers, components, code}` + `api_surface` + a `manifest` with per-directory content hashes for **incremental** consumers (skip directories whose hash is unchanged). `components.module_roots` rolls leaf source dirs up to architectural module roots and classifies each `layered` (DDD: ≥2 of `domain`/`application`/`infrastructure`) vs `flat` (legacy/flat package), with a verifiable `module_count` — so a consumer enumerates real modules instead of inferring boundaries from leaf directories. |
431
-
432
- The section flags compose (pass several for one multi-section document); `--c4` assembles the full export on its own. URLs assembled at runtime yield `target: null` (honest absence, never a guess); containers are derived from build files (Maven/Gradle) and reported as a limitation when none are found.
433
-
434
- ### `spring-audit` — Spring semantic audit [free]
435
-
436
- ```bash
437
- ask spring-audit /path/to/repo
438
- ask spring-audit /path/to/repo --scope tx # TX anomalies only
439
- ask spring-audit /path/to/repo --scope security # security surface only
440
- ask spring-audit /path/to/repo --min-severity high
441
-
442
- # CI/CD gate: exit 1 on any finding
443
- ask spring-audit . --ci
444
- ask spring-audit . --ci --min-severity high # exit 1 only on high/critical
445
- ask spring-audit . --ci --format github-comment # Markdown output + exit 1
446
- ```
447
-
448
- Detects structural Spring anomalies that survive code review and tests, but cause production failures:
449
-
450
- | Pattern | Description |
451
- |---------|-------------|
452
- | `TX-001` | `@Transactional` on private/final method — CGLIB proxy bypass, TX silently ignored |
453
- | `TX-002` | `REQUIRES_NEW` nested inside `REQUIRED` call chain — unexpected transaction nesting |
454
- | `TX-003` | `readOnly=true` boundary propagating to write operation |
455
- | `TX-004` | `NOT_SUPPORTED`/`NEVER` called within active TX chain |
456
- | `TX-005` | Exception swallowing inside `@Transactional` — silent TX rollback suppression |
457
- | `SEC-001` | Unsecured endpoint in annotation-based security model |
458
- | `SEC-002` | CVE-2025-41248: `@PreAuthorize` on inherited method from generic supertype |
459
- | `SEC-003` | `@Transactional` on `@Controller`/`@RestController` — TX in wrong layer |
460
-
461
- Returns structured findings with `severity`, `confidence`, `symbol`, `source_file`, `evidence`, `explanation`, and `fix_hint`. JAVA/SPRING ONLY.
462
-
463
- Endpoints guarded by a project-specific authorization annotation are treated as secured (not flagged `SEC-001`) once declared in [`sourcecode.config.json`](#sourcecodeconfigjson-repo-root).
464
-
465
- ### `impact-chain` — systemic blast radius with TX/SEC enrichment [free]
466
-
467
- ```bash
468
- ask impact-chain OrderService /path/to/repo
469
- ask impact-chain com.example.OrderService#placeOrder /path/to/repo
470
- ask impact-chain PaymentService . --depth 6
471
- ```
472
-
473
- Unlike `impact` (which traces the caller graph), `impact-chain` builds on the SpringSemanticModel to enrich every step of the blast cone with transaction and security context:
474
-
475
- | Field | Description |
476
- |-------|-------------|
477
- | `direct_callers` | Symbols that directly call the target |
478
- | `indirect_callers` | Transitive callers (BFS up to `--depth` hops, default: 4) |
479
- | `endpoints_affected` | HTTP endpoints reachable through the call chain |
480
- | `transaction_boundary` | `@Transactional` semantics on the target: propagation, isolation, readOnly |
481
- | `security_surfaces` | Per-endpoint security policy + SEC finding IDs |
482
- | `impact_findings` | TX-001..005 and SEC-001..003 findings that touch the call chain |
483
- | `risk_level` | `critical` \| `high` \| `medium` \| `low` |
484
- | `confidence` | `high` \| `medium` \| `low` — `low` on a detected blind spot, `medium` on partial resolution or capped traversal. Informational interface↔impl expansion notices do **not** lower it, so a clean resolved query stays `high`. |
485
- | `metadata.blind_spots` | `framework_di` and/or `value_type` when an empty result is unmodeled-edge driven, not real dead code (CH-007 drops `framework_di` once it recovers the wiring callers) |
486
- | `metadata.external_iface_callers_recovered` / `external_iface_binding_ambiguous` | CH-007 — count of in-repo wiring callers recovered through an external interface, and whether the impl→bean binding is ambiguous (multiple in-repo implementors) |
487
-
488
- **Framework/DI blind spot (CH-005).** An empty blast radius is ambiguous: genuinely unused, or invoked through an edge the static graph does not model. When the target class implements/extends an **external** framework type (e.g. Spring Security's `RedirectStrategy`, a servlet `Filter`) it is typically wired by framework DI/config and invoked polymorphically — no in-repo edge names its methods, so `direct_callers` is `0`. Rather than report that as `risk:low` at high confidence (a dangerous false negative that reads as "safe to change"), `impact-chain` detects the external supertype, drops `confidence` to `low`, lists it in `metadata.external_supertypes`, and emits a `CH-005` warning telling you to search the DI/security/config wiring for the supertype. Inert markers (`Serializable`, `Cloneable`) and concrete JDK base classes extended for reuse (`ArrayList`, `InputStream`, …) are excluded.
489
-
490
- **External-interface DI caller recovery (CH-007).** When the target is wired through an external interface, the consumers that inject that interface never name the target, so the static caller graph misses them — but the wiring sites are still in-repo. `impact-chain` reads the dependency edges to recover the in-repo classes that inject/use the external supertype and attributes them as callers (so their endpoints map too). If exactly one in-repo class implements the interface the binding is unambiguous (`confidence:medium`); if several do, `metadata.external_iface_binding_ambiguous` is `true` and confidence stays `low`. `metadata.external_iface_callers_recovered` reports the count. Recovered callers reach the target only if it is the bean configured for that interface (which may also have framework/third-party implementations) — the warning says so. Validated on BroadleafCommerce: querying a `UserDetailsService` implementation recovers the security-config and login-service classes that wire it.
491
-
492
- **Caller precision (CH-006).** `implements`/`extends` are structural type declarations, not calls — so they are excluded from the caller graph. Querying a class that implements a high-fanout interface (e.g. a 40-implementor `CustomEndpoint` or a shared `Mapper<E,D>` base) does **not** report its sibling implementors as callers; only real `injects`/`calls` edges count. This prevents a leaf class from being inflated to a large false blast radius.
493
-
494
- **Event topology** — query the publisher/consumer graph for a Spring event class:
495
-
496
- ```bash
497
- ask impact-chain OrderPlacedEvent /path/to/repo --type events
498
- ```
499
-
500
- | Field | Description |
501
- |-------|-------------|
502
- | `publishers` | FQNs that publish this event class |
503
- | `consumers` | Listeners with TX phase metadata (`AFTER_COMMIT`, `BEFORE_COMMIT`, etc.) |
504
- | `event_graph` | Publisher → event → consumer edges (BFS ≤ 2 hops) |
505
- | `transaction_context` | `AFTER_COMMIT` consumers, `BEFORE_COMMIT` risks |
506
- | `risk_level` | Derived from TX phase and consumer count |
507
-
508
- **Limitations of event topology:**
509
- - Resolves Spring `ApplicationEvent` / `@EventListener` chains only
510
- - Does not trace Kafka, RabbitMQ, Redis, or other message brokers
511
- - Does not detect self-invocation proxy bypass
512
- - Conditional beans (`@ConditionalOnProperty`) are not evaluated at analysis time
513
-
514
- ### `cold-start` — RIS bootstrap context
515
-
516
- ```bash
517
- ask cold-start /path/to/repo
518
- ask cold-start /path/to/repo --compact # ~10K token subset
519
- ```
520
-
521
- Returns the Repository Intelligence Snapshot (RIS) instantly — zero re-analysis. The RIS is built by a prior warm cache pass and includes stacks, entry points, endpoint surface, and Spring semantic signals. Status field: `cold_start_ready` | `cold_start_stale` | `no_ris`.
522
-
523
- Use `--compact` to get a ~10K token subset safe for direct LLM injection. Full snapshot ranges from ~100K–200K tokens on medium repos — use `--output FILE` for local search tooling.
524
-
525
- ### `repo-ir` — symbol-level IR
526
-
527
- ```bash
528
- ask repo-ir /path/to/repo --summary-only # ~20K tokens
529
- ask repo-ir /path/to/repo --since HEAD~1 # symbol-level diff
530
- ask repo-ir /path/to/repo --files src/.../OrderService.java
531
- ask repo-ir /path/to/repo --max-nodes 200 --max-edges 500 # limit graph size
532
- ask repo-ir /path/to/repo --output ir.json.gz --gzip # compressed output (~70-80% smaller)
533
- ask repo-ir /path/to/repo --include-tests # include test files
534
- ```
535
-
536
- Builds a deterministic symbol graph: classes, methods, import/injection edges, Spring roles, subsystems.
537
-
538
- **Size control flags:**
539
-
540
- | Flag | Description |
541
- |------|-------------|
542
- | `--summary-only` | Omit full graph nodes/edges; keep analysis summary, impact, and change_set (<300KB typical) |
543
- | `--max-nodes N` | Keep top N nodes by impact score |
544
- | `--max-edges N` | Keep top N edges (priority: edges between kept nodes) |
545
- | `--gzip` | Compress output with gzip. Requires `--output`. ~70–80% smaller. |
546
- | `--force` | Bypass the 50K-token size guard and emit output anyway |
547
- | `--include-tests` | Include test source files (excluded by default) |
548
-
549
- **Size warning:** Without `--summary-only`, output can exceed 1MB for mid-size repos. Always use `--summary-only` unless you need the full graph for downstream tooling.
550
-
551
- ### `explain` — architectural summary for a class
552
-
553
- ```bash
554
- ask explain UserService
555
- ask explain OrderController /path/to/repo
556
- ask explain UserService --format json
557
- ```
558
-
559
- Human-readable architectural summary derived entirely from static analysis: Spring stereotype, public methods, incoming callers, outgoing dependencies, events published/consumed, `@Transactional` boundaries, security constraints, and related REST endpoints. JAVA/SPRING ONLY.
560
-
561
- ### `pr-impact` — PR blast-radius report
562
-
563
- ```bash
564
- ask pr-impact --files changed_files.txt
565
- ask pr-impact /path/to/repo --files diff.txt --format json
566
- ```
567
-
568
- Takes a file listing changed Java files (one path per line) and produces a consolidated report: modified classes, affected REST endpoints reachable through the call chain, direct callers of each changed class, event publishers/consumers triggered, `@Transactional` methods in changed classes, and a consolidated risk level (`CRITICAL` / `HIGH` / `MEDIUM` / `LOW`). JAVA/SPRING ONLY.
569
-
570
- ```bash
571
- # Typical CI usage: pipe git diff to a file, then run
572
- git diff --name-only main | grep '\.java$' > changed.txt
573
- ask pr-impact . --files changed.txt --format json
574
- ```
575
-
576
- ### `onboard` — codebase orientation
577
-
578
- ```bash
579
- ask onboard /path/to/repo
580
- ```
581
-
582
- Entry points, architecture summary, key files, confidence level, and gaps. Designed to be injected as agent context at the start of a session.
583
-
584
- ### `review-pr` — PR review context [free ≤500 Java files · Pro above]
585
-
586
- ```bash
587
- ask review-pr /path/to/repo --since main
588
- ask review-pr /path/to/repo --since HEAD~3
589
- ```
590
-
591
- Changed files, risk ranking, test coverage gaps, affected modules, and blast radius of changed classes. Returns a `ci_decision` field for CI/CD integration.
592
-
593
- ### `fix-bug` — Bug triage context [free ≤500 Java files · Pro above]
594
-
595
- ```bash
596
- ask fix-bug /path/to/repo --symptom "NullPointerException in checkout"
597
- ```
598
-
599
- Risk-ranked file list correlated to the symptom: keyword extraction, path matching, content matching, git commit correlation.
600
-
601
- ### `modernize` — Modernization planning [free ≤500 Java files · Pro above]
602
-
603
- ```bash
604
- ask modernize /path/to/repo
605
- ```
606
-
607
- High-coupling nodes (high fan-in = risky to change), dead zone candidates (isolated symbols), subsystem tangles.
608
-
609
- ### `migrate-check` — Spring Boot 2→3 migration readiness
610
-
611
- ```bash
612
- ask migrate-check /path/to/repo
613
- ask migrate-check . --min-severity high
614
- ask migrate-check . --format text
615
- ask migrate-check . --output migration.json
616
- ```
617
-
618
- Detects migration blockers across Java source files, Spring XML config files, and Maven/Gradle build files. 27 rules organized by target:
619
-
620
- **Jakarta namespace (MIG-001..009) — javax→jakarta**
621
-
622
- | Rule | Severity | Pattern |
623
- |------|----------|---------|
624
- | `MIG-001` | critical | `javax.persistence` import — JPA will not compile |
625
- | `MIG-002` | high | `javax.servlet` import — Servlet API changed |
626
- | `MIG-003` | high | `javax.validation` import — Bean Validation changed |
627
- | `MIG-004` | high | `javax.transaction` import — TX API changed |
628
- | `MIG-006` | medium¹ | `javax.annotation` import — CDI annotations changed (¹`javax.annotation.Generated` in autogenerated code → **low**, bucketed `generated`; explanation names the actual symbol) |
629
- | `MIG-007` | medium | `javax.inject` import — DI annotations changed |
630
- | `MIG-008` | medium | `javax.ws.rs` import — JAX-RS changed |
631
- | `MIG-009` | medium | `javax.jms` import — JMS API changed |
632
-
633
- **Spring Security 6 (MIG-005, MIG-019, MIG-020)**
634
-
635
- | Rule | Severity | Pattern |
636
- |------|----------|---------|
637
- | `MIG-005` | high | `extends WebSecurityConfigurerAdapter` — removed in Spring Security 6 |
638
- | `MIG-019` | high | SpringFox / `@EnableSwagger2` — incompatible with Spring Boot 3 |
639
- | `MIG-020` | high | `antMatchers()` / `authorizeRequests()` — replaced in Spring Security 6 |
640
-
641
- **Java version compatibility (MIG-010..025)**
642
-
643
- | Rule | Severity | Pattern |
644
- |------|----------|---------|
645
- | `MIG-010` | critical | `SecurityManager` / `AccessController` — removed in Java 17 (JEP 411) |
646
- | `MIG-011` | high | `sun.*` / `com.sun.net.*` internal API imports — strong encapsulation since Java 9 |
647
- | `MIG-012` | high | Nashorn `ScriptEngine` — removed in Java 15 |
648
- | `MIG-013` | high | `sun.misc.Unsafe` — requires `--add-opens` on Java 9+ |
649
- | `MIG-014` | medium | `setAccessible(true)` — may throw `InaccessibleObjectException` on Java 17+ |
650
- | `MIG-015` | medium | `finalize()` override — deprecated for removal since Java 18 |
651
- | `MIG-016` | low | `java.util.Date` / `Calendar` / `SimpleDateFormat` — use `java.time` |
652
- | `MIG-021` | high | `javax.xml.bind` (JAXB) — removed from JDK in Java 11 |
653
- | `MIG-022` | high | `javax.xml.ws` (JAX-WS) — removed from JDK in Java 11 |
654
- | `MIG-023` | critical | `org.omg.*` / CORBA APIs — removed from JDK in Java 11 |
655
- | `MIG-024` | medium | `Thread.stop()` / `Thread.suspend()` / `Thread.resume()` — deprecated for removal |
656
- | `MIG-025` | medium | `ReflectionFactory` / `MethodHandles.privateLookupIn` — JPMS deep-reflection risk |
657
-
658
- **Spring XML config (MIG-030..032)**
659
-
660
- | Rule | Severity | Pattern |
661
- |------|----------|---------|
662
- | `MIG-030` | high | `javax.*` class reference in Spring XML bean definitions |
663
- | `MIG-031` | high | `<http auto-config>` or versioned spring-security ≤5 schema in XML |
664
- | `MIG-032` | high | `web.xml` with Servlet ≤4 namespace — must migrate to `jakarta.ee` |
665
-
666
- **Build file dependencies (MIG-040..043)**
667
-
668
- | Rule | Severity | Pattern |
669
- |------|----------|---------|
670
- | `MIG-040` | high | `io.springfox` dependency — incompatible with Spring Boot 3 |
671
- | `MIG-041` | high | Hibernate 5.x explicitly pinned — Spring Boot 3 requires Hibernate 6 |
672
- | `MIG-042` | medium | ByteBuddy < 1.12.x — may not support Java 17+ strong encapsulation |
673
- | `MIG-043` | high | EhCache 2.x (`net.sf.ehcache`) — incompatible with Spring Boot 3 |
674
-
675
- Each finding includes `severity`, `title`, `source_file`, `first_line`, `explanation`, `fix_hint`, `migration_target`, and `openrewrite_recipe` (when an automated recipe exists).
676
-
677
- #### Hibernate 5.x → 6.x stratification (the `hibernate` output section)
678
-
679
- A Hibernate major upgrade is **not** a single dependency bump for systems that use
680
- dynamic persistence. `migrate-check` stratifies Hibernate exposure into four
681
- independent migration domains — never one aggregated score — and emits **actionable,
682
- machine-readable rewrite targets** so a migration agent can consume the output
683
- directly instead of re-parsing the repo. Sub-`schema_version`: `2.1`.
684
-
685
- > **Evidence-gated (no false blockers).** Hibernate detection requires real proof —
686
- > an `org.hibernate:*` build dependency, a parsed `import org.hibernate.*`, or a
687
- > parsed `import {jakarta,javax}.persistence.*`. Absent all three,
688
- > `hibernate.detected` is `false` (no `hibernate_rewrite` headline, no phantom
689
- > effort). Scanning runs on source with comments + string/char literals stripped, so
690
- > an `org.hibernate.*` substring in Javadoc or a classpath resource path never
691
- > triggers a verdict; bare-name SPI matches (`implements XInterceptor`) require an
692
- > `org.hibernate` import in the same file. The proof is recorded under
693
- > `hibernate.evidence{}` with a `confidence`.
694
-
695
- **Four layers** (each on its own risk axis):
696
-
697
- | Layer | Baseline | Escalates to |
698
- |-------|----------|--------------|
699
- | `jpa_annotations` | LOW (namespace handled by jakarta) | HIGH on deprecated `@Type(type=)` / `@TypeDef` / `@GenericGenerator` |
700
- | `criteria_api` | HIGH (JPA Criteria semantics changed; legacy `org.hibernate.Criteria` removed) | **CRITICAL** when built via reflection / abstraction DAOs (`DynamicEntityDao`, `GenericDao`, `BasicPersistenceModule`) |
701
- | `hql_string_queries` | MEDIUM (revalidate against H6 parser) | HIGH on string concatenation (SQL shape not statically inferable) |
702
- | `hibernate_spi_internal` | CRITICAL blocker | `UserType`, `CompositeUserType`, `Interceptor`, `EventListener`, `org.hibernate.engine.spi` |
703
-
704
- **Output keys (under `hibernate`):**
705
-
706
- - `classification` — `upgrade_zone` / `upgrade_with_care` / `rewrite_zone`. Any of
707
- {dynamic Criteria, custom SPI, reflection-built queries, concatenated query
708
- strings} forces **`rewrite_zone`** ("HIGH RISK REWRITE ZONE, NOT UPGRADE ZONE").
709
- - `risk_matrix[]` — per layer: `risk`, `reason`, `effort_range {low, high, confidence}`,
710
- `file_count`, `occurrence_count`, migration-kind sub-counts (`manual_count`,
711
- `assisted_count`, `mechanical_count`, `review_count`); Criteria adds
712
- `static_count` vs `dynamic_count`; SPI adds `userType_rewrite_count` vs
713
- `userType_resolvable_count`.
714
- - `rewrite_targets[]` — one actionable target per call site: `id`, `layer`,
715
- `source_file`, `line_start`/`line_end`, `current_pattern`, `current_snippet`,
716
- `target_api` (the Hibernate-6 destination), `migration_kind`
717
- (`manual_rewrite` / `assisted` / `mechanical` / `review`), `auto_migratable`,
718
- `blocking_reason`, `symbol` (enclosing `Class#method`), `module`, `dynamic`.
719
- - `module_exposure_map` — per Maven/Gradle module: `max_risk`, layers present, and
720
- `dynamic-criteria` / `custom-SPI` / `reflection` tags.
721
- - `critical_call_chains[]` — dynamic query-generation paths (reflection-based DAOs).
722
- - `golden_sql_hotspots[]` — classes/methods ranked by dynamic-query volume — where
723
- to pin golden-SQL behaviour tests before migrating.
724
- - `total_effort_range_days` + `effort_model` — aggregate range plus the auditable
725
- formula (and the caveat that layers may share files, so the total is an upper bound).
726
- - `stop_conditions_triggered[]`, `risk_separation` (observable vs inferred runtime risk).
727
-
728
- The report also exposes **`hibernate_readiness`** (0–100) as a fourth readiness
729
- dimension alongside `jakarta_readiness` / `boot3_readiness` / `jdk_modernization`.
730
- Hibernate is an orthogonal rewrite axis, so it does not sink the headline
731
- `readiness_score`; instead, in a rewrite zone the top-level `headline_blocker` is set
732
- to `"hibernate_rewrite"` so a reader of the headline score is not misled.
733
-
734
- A dimension that does not apply (e.g. Hibernate on a repo with no Hibernate) is
735
- reported as **N/A** (`score: null`), never as `0`. The top-level
736
- `applicable_dimensions{}` records which dimensions apply and `readiness_note`
737
- states that `readiness_score` is a derived aggregate over applicable dimensions
738
- only — for decisions, read the per-dimension breakdown + `blocking_count`.
739
-
740
- #### Reliability guarantees (no version, no verdict)
741
-
742
- A migration verdict shown to a decision-maker must never contradict its own
743
- evidence. `migrate-check` enforces:
744
-
745
- - **Version-gated framework axes.** The Hibernate 5→6 axis applies only when the
746
- effective Hibernate version (resolved from `pom.xml`/Gradle, following Maven
747
- `${properties}` and BOM-managed `<hibernate*.version>`) is `< 6`. A resolved
748
- Hibernate **6+** repo is reported `migration_applicable: false` (N/A) — no
749
- `hibernate_rewrite` headline. An **unresolved** version degrades to a
750
- low-confidence hypothesis with no headline blocker. See
751
- `hibernate.effective_version` / `version_major` / `version_confidence`.
752
- - **Boot3 needs Spring _Boot_, not just Spring.** `boot3.applicable` requires
753
- positive Spring Boot evidence — a `spring-boot*` coordinate / Gradle plugin (or
754
- `@SpringBootApplication`), **or** a concrete `spring_boot_3` / `spring_security_6`
755
- finding. A repo that merely carries a Spring library (e.g. `spring-security-web`
756
- with no Boot — Jenkins core) reports `boot3` as N/A with a reason and is excluded
757
- from the aggregate; `spring_present: true` but `spring_boot_present: false`. Quarkus
758
- / Micronaut / Helidon / Jakarta-pure repos likewise report `boot3` N/A. jakarta
759
- findings alone never enable boot3.
760
- - **Frozen-legacy `@Deprecated` shims aren't blockers.** A `javax→jakarta` finding
761
- on a **class-level `@Deprecated`** type (kept for binary compat, replaced
762
- elsewhere) is classified `code_context: "deprecated_shim"` and excluded from
763
- `blocking_count` / readiness / effort — surfaced under `non_blocking` with a
764
- "verify before removing" note. A `@Deprecated` **method** on a live class still
765
- blocks.
766
- - **Permanent `javax.*` are never jakarta debt.** JDK/JSR namespaces
767
- (`javax.cache`, `javax.sql`, `javax.xml` JAXP, `javax.crypto`, `javax.naming`,
768
- `javax.management`, `javax.security.auth`, `javax.annotation.processing`, …) are
769
- allowlisted across every jakarta scorer (single source of truth:
770
- `serializer._JAVAX_PERMANENT_NAMESPACES` + `migrate_check._JAKARTA_NO_MIGRATE_PREFIXES`).
771
- The `javax→jakarta` dependency flag decides via **longest-prefix match**, so
772
- `javax.xml.bind` (JAXB — moved) flags while `javax.xml` (JAXP) does not, and
773
- `javax.annotation` (JSR-250 — moved) flags while `javax.annotation.processing`
774
- (JSR-269) does not. The allowlist never silences a real migration.
775
- - **`readiness_score` is a traceable aggregate.** It is `min` over the applicable
776
- **migration** dimensions (`jakarta` / `boot3` / `hibernate`); `jdk_modernization`
777
- is orthogonal upkeep and is excluded. The exact inputs are in `readiness_aggregate{}`
778
- and an invariant (`readiness_score == min(applicable migration dims)`) is asserted in
779
- code. When the Hibernate version is undeclared it is inferred from the Spring Boot
780
- BOM (Boot ≥3 → Hibernate ≥6 → N/A; Boot 2 → Hibernate 5 → applicable; no BOM →
781
- `status: unresolved`, never a heuristic score).
782
- - **Three buckets: blocker ≠ hygiene ≠ test.** Only product (`main`) code counts
783
- toward `blocking_count`, readiness, and effort. Test harnesses
784
- (`testsuite/`, `test-framework/`, `integration-arquillian/`, `*-test*`,
785
- `src/test/`) and autogenerated sources are tagged `code_context` and surfaced in
786
- `non_blocking{}`. Best-practice hygiene (`java.util.Date`) is reported as
787
- `hygiene_findings` and never sinks a dimension. Each finding carries
788
- `code_context: main | test | generated`.
789
-
790
- ```bash
791
- # inspect only the Hibernate rewrite targets
792
- ask migrate-check . --format json | jq '.hibernate.rewrite_targets[]'
793
-
794
- # product blockers only (excludes test/fixtures + hygiene)
795
- ask migrate-check . --format json | jq '.blocking_count, .non_blocking, .hygiene_findings'
796
- ```
797
-
798
- ### `rename-class` — Java class rename
799
-
800
- ```bash
801
- ask rename-class . --from ServiceA --to ServiceB
802
- ask rename-class /path/to/repo --from OrderManager --to OrderService
803
- ask rename-class . --from OldName --to NewName --dry-run
804
- ask rename-class . --from OldName --to NewName --no-tests # src/main only
805
- ```
806
-
807
- Renames a Java class safely throughout the repository: declaration, constructor, all import statements, type references (fields, params, return types), `extends`/`implements`, generics, casts, and Spring `@Qualifier` names. Renames the physical `.java` file. Emits a structured change audit trail (`file`, `before_lines`, `after_lines`, `intent`, `diff`).
808
-
809
- Use `--dry-run` to preview changes without writing to disk.
810
-
811
- ### `chunk-file` — split large Java files for agent consumption
812
-
813
- ```bash
814
- ask chunk-file BigService.java
815
- ask chunk-file BigService.java --max-lines 300
816
- ask chunk-file BigService.java --chunk 5 # read chunk 5 only
817
- ask chunk-file BigService.java --metadata-only # boundaries only, no content
818
- ```
819
-
820
- Splits a large Java file at method/class boundaries so AI agents can read files with 10K–25K+ lines in context-sized pieces. Each chunk includes `chunk_id`, `start_line`, `end_line`, `chunk_type`, symbol name, a `context_header` (package + class + imports summary), and `content`. A `size_warning` flag marks methods that exceed `--max-lines` and cannot be split further.
821
-
822
- ### `prepare-context` — task-specific context
823
-
824
- Low-level access to all tasks with full options:
825
-
826
- ```bash
827
- ask prepare-context TASK [PATH] [OPTIONS]
828
- ```
829
-
830
- | Task | What it surfaces |
831
- |------|-----------------|
832
- | `explain` | Architecture, entry points, key dependencies |
833
- | `onboard` | Full structural context for new agents/developers |
834
- | `fix-bug` | Files ranked by symptom correlation, risk, annotations |
835
- | `refactor` | Structural issues, improvement opportunities |
836
- | `generate-tests` | Source files without test pairs, coverage gap analysis |
837
- | `review-pr` | PR diff with risk ranking, test gaps, module impact |
838
- | `delta` | Incremental context: git-changed files + transitive import graph |
839
-
840
- ---
841
-
842
- ## Flags reference
843
-
844
- | Flag | Alias | Default | Description |
845
- |------|-------|---------|-------------|
846
- | `--compact` | | off | High-signal summary (typically 2,500–4,000 tokens for mid-to-large Java repos): stacks, entry points, dependencies, confidence, gaps. |
847
- | `--agent` | | off | Structured JSON for AI agents: project identity, entry points, architecture, dependencies, confidence. ~4,500–5,500 tokens. |
848
- | `--full` | | off | Remove truncation limits on `transactional_boundaries`, `mybatis.dto_mappers`, and other capped lists. |
849
- | `--git-context` | `-g` | off | Include git activity: recent commits, change hotspots, and uncommitted file count. |
850
- | `--changed-only` | | off | Limit output to git-modified files (staged, unstaged, untracked). |
851
- | `--depth` | | `4` | File tree traversal depth (1–20). Java/Maven projects auto-adjust to 12. |
852
- | `--format` | `-f` | `json` | Output format: `json` or `yaml`. |
853
- | `--output` | `-o` | stdout | Write output to a file instead of stdout. |
854
- | `--no-cache` | | off | Bypass scan cache and force a fresh analysis. |
855
- | `--copy` | `-c` | off | Copy output to clipboard after a successful run. |
856
- | `--no-redact` | | off | Disable automatic secret redaction. |
857
- | `--version` | `-v` | — | Show version and exit. |
858
-
859
- ---
860
-
861
- ## Output schema
862
-
863
- All outputs include:
864
- - `schema_version`: output format version
865
- - `confidence_summary`: `overall`, `stack`, `entry_points` confidence levels (`high`/`medium`/`low`)
866
- - `analysis_gaps`: list of what could not be analyzed and why
867
-
868
- ### Java/Spring-specific fields (when detected)
869
-
870
- | Field | Description |
871
- |-------|-------------|
872
- | `language_version` | Java version from `maven.compiler.source` or equivalent |
873
- | `deployment.spring_boot_version` | Spring Boot version |
874
- | `deployment.packaging` | `jar` or `war` |
875
- | `mybatis` | Mapper interface / XML file pairing summary |
876
- | `transactional_boundaries` | Classes annotated with `@Transactional` |
877
- | `deployment_risks` | Static risk flags: `spring-boot-2.x-eol`, `legacy-java-runtime` |
878
-
879
- ---
880
-
881
- ## Telemetry
882
-
883
- Anonymous, **on by default (opt-out)**. Collects: version, OS, commands, flags, duration, repo size range, errors. No source code, paths, secrets, or output content. A one-time notice is shown on first interactive run.
884
-
885
- ```bash
886
- ask telemetry status
887
- ask telemetry enable
888
- ask telemetry disable
889
- ```
890
-
891
- Disable any time: `export SOURCECODE_TELEMETRY=0` (or `DO_NOT_TRACK=1`)
892
-
893
- ---
894
-
895
- ## Configuration
896
-
897
- ```bash
898
- ask config # show version, config file path, telemetry status
899
- ```
900
-
901
- ### `sourcecode.config.json` (repo root)
902
-
903
- Optional, per-repo. Loaded from the root of the repo being analyzed. Absent or
904
- malformed config is ignored — the tool behaves exactly as without it.
905
-
906
- **Custom security annotations.** Teach `endpoints`, `spring-audit`, and `explain`
907
- about project-specific authorization annotations (otherwise reported as
908
- `policy: "none_detected"`):
909
-
910
- ```json
911
- {
912
- "customSecurityAnnotations": [
913
- {
914
- "fullyQualifiedName": "com.example.security.M3FiltroSeguridad",
915
- "shortName": "M3FiltroSeguridad",
916
- "resourceParam": "nombreRecurso",
917
- "levelParam": "nivelRequerido"
918
- }
919
- ]
920
- }
921
- ```
922
-
923
- `resourceParam` / `levelParam` are optional and name the annotation attributes to
924
- surface as `resourceName` / `requiredLevel`. Matching endpoints report
925
- `policy: "custom"` and drop out of the `no_security_signal` count.