Skip to main content

jskim

PyPI version Python License

Token-saving Java file reader for AI coding agents, optimized for Spring Boot. Summarizes Java files compactly using tree-sitter, saving 70-80% of input tokens compared to reading files directly. Zero setup, no index: every run parses the current working tree.

A human counted the tokens. An AI counted the getters. Both decided life's too short.

Installation

pip install jskim

Requires Python 3.10+.

Usage

jskim auto-detects the mode based on whether you pass a file or directory.

Summarize a Java file

jskim <file.java>
jskim <file.java> --grep <pattern>        # filter methods by name/signature
jskim <file.java> --annotation <@Ann>     # filter methods by annotation
jskim A.java B.java C.java                # multiple files

Java simple source files without an explicit type wrapper are summarized as implicit class <FileStem>. A package-info.java shows its package-level annotations (Spring Modulith @ApplicationModule).

The summary shows the class Javadoc's first sentence, instance fields and static constants separately (non-private short string constants with their value), collapses dependency-injection constructors to one line, keeps annotation arguments that change behaviour (@RequiresPermission("trip.create"), @Transactional(readOnly = true)), drops OpenAPI/Swagger documentation annotations, renders nested types with their members, and resolves mapping paths from class constants (@PostMapping(path = ONE_TRIP + "/start")@PostMapping("/trips/{tripId}/start")). Method line ranges start at the signature, not at the annotation block above it.

Project map

Generates a compact map of all Java files in a directory: packages (relative to the common root, with package-info.java annotations), classes, annotations, field/method counts, Lombok usage, enum constants, records by name. Build output directories (target/, build/) are skipped.

jskim <src_dir>
jskim <src_dir> --deps                 # package-to-package dependencies
jskim <src_dir> --endpoints             # REST endpoint map
jskim <src_dir> --beans                 # Spring bean DI graph + @Bean producers + config properties
jskim <src_dir> --callers Class.method  # upstream callers for a specific method
jskim <src_dir> --impact Class.method   # callers + direct callees for a specific method
jskim <src_dir> --impact Class.method --depth 2  # bounded hierarchy depth
jskim <src_dir> --package <text>        # filter by package (substring)
jskim <src_dir> --annotation <@Ann>     # filter by class annotation
jskim <src_dir> --extends <ClassName>   # filter by superclass
jskim <src_dir> --implements <Name>     # filter by implemented interface

Spring Boot flags:

  • --endpoints — lists all REST endpoints: HTTP method, full path (base + method), handler, line number, and the handler's guard annotations with constants resolved (@RequiresPermission("trip.create")). Paths built from constants (@RequestMapping(BASE_PATH), TRIPS + "/{id}", ApiPaths.ROOT) are resolved across the project
  • --beans — shows bean DI wiring (constructor parameters, or Lombok constructor + final fields, or @Autowired/@Inject fields), @Bean factory method producers (nested @Configuration classes included), and @ConfigurationProperties with prefix + field details
  • --callers Class.method — shows resolved upstream callers for a specific method; use a fully-qualified class name when class names collide
  • --impact Class.method — shows both upstream callers and downstream calls from the target method
  • --depth N — controls caller/impact traversal depth; defaults to 1 to keep output compact
  • --implements — filter classes by implemented interface name
  • --deps — one block per package listing the other project packages it imports, extends or implements, and the types involved. Same-package references are omitted, so the output is the module-boundary view

Call hierarchy mode resolves same-class calls, static calls on project classes, and field calls such as billingService.create() when the field type points to a project class. A call through an interface or superclass also counts for every project implementation, so --callers AuditEventService.write finds the callers of AuditApi.write. It intentionally skips unresolved local-variable/parameter calls and ambiguous overload edges rather than guessing. Classes are shown by simple name and fully qualified only when the simple name is ambiguous.

Example:

jskim src/ --callers BillingService.create --depth 2
// === Callers: BillingService.create (depth 2) ===
// target: BillingService.create(BillDTO)  src/.../BillingService.java:L45
//
// callers:
//   ← BillingController.createBill(BillDTO)  src/.../BillingController.java:L62
//     ← BillingJob.retryFailedBills()  src/.../BillingJob.java:L30
jskim src/ --impact BillingService.create
// === Impact: BillingService.create (depth 1) ===
// target: BillingService.create(BillDTO)  src/.../BillingService.java:L45
//
// callers:
//   ← BillingController.createBill(BillDTO)  src/.../BillingController.java:L62
//
// calls:
//   → BillingRepository.save(Bill)  src/.../BillingRepository.java:L20
//   → BillingService.validate(BillDTO)  src/.../BillingService.java:L80

Diff mode

Summarizes only the Java files and methods changed in a git diff. Ideal for PR reviews.

jskim --diff HEAD~1                    # changes since last commit
jskim --diff main                      # changes vs main branch
jskim --diff main...feature-branch     # merge-base comparison
jskim src/ --diff HEAD~1               # scoped to directory
git diff main | jskim --diff -         # read diff from stdin

Output marks methods as [NEW], [MODIFIED], or [DELETED], and added/removed instance fields or record components as [FIELDS] +Type name, -Type name, nested types included. Getters/setters/boilerplate and dependency-injection constructor changes are suppressed. Deleted methods are shown with their previous signature when a base ref is available, so overload removals stay distinguishable.

Extract methods

jskim <file.java> --list                          # list all methods
jskim <file.java> <method_name>                    # extract one method
jskim <file.java> <method1> <method2> <method3>    # extract multiple

The extracted source keeps the Javadoc and behaviour annotations above the method and skips documentation-only annotations (@Operation, @ApiResponse, @Schema).

Method calls ()

Each method in the skim output shows its direct method invocations:

// methods:
//     L45-L62 ( 18 lines): @PostMapping("/bills") public Bill createBill(@RequestBody BillDTO dto)
//                → auditLogger.log, billingService.create, notifyStakeholders, validator.validate
//     L64-L80 ( 17 lines): @GetMapping("/bills/{id}") public Bill getBill(@PathVariable Long id)
//                → billingService.findById

Every entry can be followed: an unqualified name is a method in the same class, field.method resolves through the fields: section (billingServiceBillingService, so skim BillingService.java next), and Class.method is a static call on a project class. Calls on local variables and parameters, JDK/Spring/library classes (Collectors.groupingBy, OffsetDateTime.now), static-imported members, ALL_CAPS constants, chained/fluent calls, logging, and collection plumbing are excluded because they cannot be followed from a summary.

Usage in Skill-enabled Agents

Any coding agent that can run shell commands can use jskim directly. The repo also includes a SKILL.md definition for environments that support skill-style tool packaging and auto-triggering.

One published install path for skill-enabled environments is the Vercel Skills Registry:

npx skills add garvit-joshi/jskim

In hosts that expose the skill as a slash command, invoke it with /jskim:

/jskim <file.java>              # summarize a file
/jskim <src_dir>                # project map
/jskim <file.java> <method>     # extract a method

Workflow

  1. Explorejskim src/ to understand project structure
  2. Narrowjskim src/ --package com.example.billing to focus on a package
  3. Spring contextjskim src/ --endpoints --beans to see REST API + DI wiring
  4. Understandjskim File.java to see class structure, fields, methods, and calls
  5. Trace — Follow calls by matching field types to find the next class to skim
  6. Impactjskim src/ --callers Class.method or --impact Class.method to see resolved upstream/downstream method edges
  7. Filterjskim File.java --grep billing for large classes
  8. Focusjskim File.java methodA methodB to read specific methods
  9. Edit — Read only the specific lines you need from the source file before editing

Dependencies

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jskim-0.4.0.tar.gz (103.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jskim-0.4.0-py3-none-any.whl (42.1 kB view details)

Uploaded Python 3

File details

Details for the file jskim-0.4.0.tar.gz.

File metadata

  • Download URL: jskim-0.4.0.tar.gz
  • Upload date:
  • Size: 103.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for jskim-0.4.0.tar.gz
Algorithm Hash digest
SHA256 ce6101a97b2e6b1f27cecc6e67c2c9fd9eb326b469e36c77a69ed8d07f1164c0
MD5 92e48335190e11c0d5c5bdbabd21c5a6
BLAKE2b-256 6dca280a3ff422053881e3675590812f9d69ac92f7dee0efe0a5d11109380d93

See more details on using hashes here.

Provenance

The following attestation bundles were made for jskim-0.4.0.tar.gz:

Publisher: publish.yml on garvit-joshi/jskim

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file jskim-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: jskim-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 42.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for jskim-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9cb839d3ac956c21e629635dfd4c9793e8cae23a0f4503b20e2f124181127499
MD5 49e48ef14bd2ee16f7c628c6c7337510
BLAKE2b-256 d0883f3d0203b7dd83c7d0805062086394c12411f918923566a8d57a45b43452

See more details on using hashes here.

Provenance

The following attestation bundles were made for jskim-0.4.0-py3-none-any.whl:

Publisher: publish.yml on garvit-joshi/jskim

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 files

0.3.0

2 files

0.2.5

2 files

0.2.4

2 files

0.2.3

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page