Skip to main content

CodeIntel CLI tool

Project description

AJA – Code Intelligence for Java & Python

Understand your codebase. Not just files — architecture.

AJA is a codebase intelligence CLI for Java and Python projects. It gives you structural visibility that no IDE provides by default — how services connect to models, what depends on what, and where code actually lives across layers.

Built for developers who work in real, messy, large codebases — not toy projects.


Why AJA?

Standard IDE tools give you:

  • Go to definition
  • File search
  • Text grep

That's not enough in real codebases where:

  • A single service touches a dozen models
  • Relationships are implicit and never documented
  • "Go to definition" sends you three layers deep with no map back

AJA gives you the layer above all of that:

Architectural navigation — understand the system, not just the file.


Core Workflow

AJA is built around three actions:

🔍 Analyze

Scan your project once. AJA builds a structural map of every service, model, repository, controller, and their relationships — across your entire codebase.

🧭 Jump

Navigate instantly to any file, model, or service by name. No folder browsing. No tab switching. No guessing.

📋 Act

Extract exactly the right context for code review, refactoring, documentation, or AI-assisted analysis.


Key Features

Feature Details
Java & Python support Static analysis, no compilation needed
Service → model → repository mapping Full architectural layer visibility
Forward dependency traversal What does this file depend on?
Reverse dependency traversal What depends on this file?
Symbol-level relationships Classes, methods, interfaces across files
Offline & local No network, no server, no telemetry
Read-only Zero modification to your project, ever

Getting Started

pip install aja-codeintel
cd your-project/
aja scan .
aja tree .

That's it. AJA is now aware of your project structure.


Commands — Full Reference


aja scan .

What it does: Indexes all Java and Python source files in your project. Builds the internal graph of imports, dependencies, and relationships that every other command relies on.

When to use it: Once when you first open a project. Again after major structural changes (adding services, moving files).

aja scan .

Run this first. Everything else depends on it.


aja tree .

What it does: Prints a clean, source-only tree of your project. Filters out build artifacts, cache folders, and non-source files so you see only what matters.

When to use it: Getting your bearings in an unfamiliar codebase. Understanding folder structure at a glance.

aja tree .

Example output:

project/
├── controller/
│   └── UserController.java
├── service/
│   └── UserService.java
├── model/
│   └── User.java
└── repository/
    └── UserRepository.java

aja open <name>

What it does: Fuzzy-searches your indexed project and opens the best matching file. You don't need the full path or exact name.

When to use it: When you know roughly what you're looking for but don't want to browse folders.

aja open UserService
aja open EmailService
aja open AppConfig

Saves you from clicking through 6 folders to find one file.


aja servicemap <service>

What it does: Maps a service to everything it touches — controllers that call it, models it uses, and repositories it depends on. Gives you a full architectural picture of one service in seconds.

When to use it: Before modifying a service. During code review. When onboarding to understand how a service fits into the system.

aja servicemap userservice

Example output:

UserService
├── Called by → UserController
├── Uses model → User, Address
└── Depends on → UserRepository, EmailService

This is the command that replaces 20 minutes of manual tracing.


aja modeltree <model>

What it does: Shows everywhere a domain model is referenced — which services use it, which repositories store it, which controllers expose it. Full vertical slice through your architecture for one model.

When to use it: Before renaming or modifying a model. Understanding the full impact of a data structure change.

aja modeltree User
aja modeltree Address
aja modeltree Order

Example output:

User (model)
├── UserService (service)
├── UserRepository (repository)
├── UserController (controller)
├── UserResponse (dto)
└── UserCreateRequest (dto)

Know the full blast radius before you touch anything.


aja related <file> --depth <n>

What it does: Shows all files that the given file directly or transitively imports and depends on. Depth controls how many layers deep to traverse.

When to use it: Understanding what a file pulls in. Checking for bloated dependencies. Preparing for a refactor.

aja related UserService --depth 1   # direct dependencies only
aja related UserService --depth 2   # dependencies of dependencies
aja related UserService --depth 3   # full transitive graph

Start at depth 1, go deeper only when you need to.


aja rrelated <file>

What it does: The reverse of related. Shows every file in your project that imports or depends on the given file. This is what standard IDEs almost never show you clearly.

When to use it: Before deleting or renaming a file. Understanding who will break if you change this. Identifying high-impact files in your codebase.

aja rrelated User
aja rrelated EmailService
aja rrelated ValidationUtil

Example output:

User.java is depended on by:
├── UserService.java
├── UserRepository.java
├── UserController.java
└── UserResponse.java

If this list is long, think twice before changing that file.


aja relsymbols <file>

What it does: Goes deeper than file-level relationships. Shows which specific classes, methods, and interfaces from this file are used across other files — and exactly where.

When to use it: Refactoring a class or method. Understanding which parts of a file are actually used vs. dead code candidates.

aja relsymbols UserService
aja relsymbols ValidationUtil

Example output:

UserService
├── createUser() → used in UserController.java
├── getUserById() → used in UserController.java, AdminService.java
└── deleteUser() → used in AdminController.java

Symbol-level precision, not just file-level noise.


aja imports <file>

What it does: Lists all local imports found in a given file — what it directly pulls in from your project (not third-party libraries).

When to use it: Quick check of what a file depends on without running the full graph.

aja imports UserService.java
aja imports orders.py

aja resolve <import-path>

What it does: Converts a logical import path (like a Java package path or Python module path) into the actual file location on disk.

When to use it: When you see an import in code and want to jump to the real file fast.

aja resolve com.example.service.UserService
aja resolve app.domain.entity.user

aja where <file>

What it does: The reverse of resolve. Takes a file path and tells you its import path — what you'd write if you were importing it from another file.

When to use it: When you need to write an import and don't want to manually construct the package path.

aja where src/main/java/com/example/service/UserService.java
aja where app/domain/entity/user.py

aja folder <path>

What it does: Lists all source files under a given folder recursively. Respects AJA's source-file filtering (Java and Python only).

When to use it: Quickly auditing what's inside a specific module or package folder.

aja folder src/main/java/com/example/service
aja folder app/domain

aja models

What it does: Lists all domain models and entities found in your project, detected from conventional model/entity folder patterns.

When to use it: Getting a full inventory of your data models. Onboarding. Architecture review.

aja models

aja fastapi-scan .

What it does: Full FastAPI project scan — resolves complete route paths including APIRouter prefixes and include_router prefix stacking, extracts Pydantic DTOs (with required/optional fields, default values, nested models), and extracts SQLAlchemy entity models (columns, types, primary keys, foreign keys, relationships). Produces structured JSON matching the same schema as the Java Spring Boot scanner.

When to use it: Deep analysis of a FastAPI codebase. Generating API + data model inventory. Feeding structured metadata into AI tools or documentation pipelines.

# JSON report (default) — same schema as Java scanner
aja fastapi-scan .

# Human-readable text
aja fastapi-scan . --format text

# Only paths under /api
aja fastapi-scan . --only-api

# Skip DTOs or models from output
aja fastapi-scan . --no-dtos
aja fastapi-scan . --no-models

Output schema (JSON):

{
  "endpoints": [
    {
      "method": "POST",
      "path": "/api/v1/users",
      "file": "app/routers/users.py",
      "line": 24,
      "handler": "create_user",
      "framework": "fastapi",
      "controller": "CreateUserRequest"
    }
  ],
  "dtos": [
    {
      "name": "CreateUserRequest",
      "file": "app/schemas/user.py",
      "kind": "pydantic",
      "bases": ["BaseModel"],
      "fields": [
        { "name": "name",  "type": "str",          "required": true,  "default": null },
        { "name": "email", "type": "str",          "required": true,  "default": null },
        { "name": "age",   "type": "Optional[int]","required": false, "default": "None" }
      ]
    }
  ],
  "models": [
    {
      "name": "User",
      "file": "app/models/user.py",
      "kind": "sqlalchemy",
      "table": "users",
      "columns": [
        { "name": "id",    "type": "Integer", "primary_key": true,  "foreign_key": null },
        { "name": "email", "type": "String",  "primary_key": false, "foreign_key": null }
      ],
      "relationships": [
        { "name": "posts", "target": "Post", "kind": "relationship" }
      ]
    }
  ]
}

What the FastAPI scanner resolves:

Pattern Resolved path
APIRouter(prefix="/users") + @router.get("/") /users
app.include_router(router, prefix="/api") /api/users
app.include_router(router, prefix="/v1") + router prefix /api /v1/api/users
@router.api_route("/ping", methods=["GET","HEAD"]) GET /ping + HEAD /ping

What the Pydantic extractor captures:

  • class X(BaseModel) — direct BaseModel subclass
  • class X(SomeBase) — inherited from another Pydantic model in the same project
  • Required vs optional fields (Optional[T], T | None, Field(...), no default)
  • Default values including Field(default=…)
  • List types (List[str], list[int])

What the SQLAlchemy extractor captures:

  • Classic declarative style: Column(Integer, primary_key=True)
  • Modern mapped style: id: Mapped[int] = mapped_column(primary_key=True)
  • Foreign keys: Column(Integer, ForeignKey("users.id"))
  • Relationships: relationship("Post", back_populates="author")
  • __tablename__

aja copy <file>

What it does: Copies the full contents of a file (or multiple files) to your clipboard — ready to paste into a code review, chat, or AI tool.

When to use it: Preparing context for AI-assisted analysis. Sharing code in reviews. Extracting content without opening the file.

aja copy src/main/java/com/example/service/UserService.java

aja context <file>

What it does: Builds a layered context bundle around a file — the file itself plus its most relevant related files. Designed to give AI tools or code reviewers exactly the right amount of context, nothing more.

When to use it: Before asking an AI tool to review or refactor a component. Preparing a PR description.

aja context UserService
aja context UserService --depth 2

aja version

aja version

Prints the current AJA version.


Supported Languages

Language Analysis Imports Symbols Services Models Endpoints
Java (Spring Boot)
Python (FastAPI) ✅ (Pydantic + SQLAlchemy) ✅ (prefix-resolved)

Static analysis only — no compilation, no runtime, no build tools required.


When to Use AJA

Situation Best Command
Just opened an unfamiliar codebase aja tree .aja models
About to modify a service aja servicemap <service>
About to delete or rename a file aja rrelated <file>
Reviewing a PR aja related <file> --depth 2
Want to understand a model's impact aja modeltree <model>
Preparing context for AI tools aja context <file> or aja copy <file>
Tracing an import to its source aja resolve <import>

What AJA Is NOT

❌ Not this ✅ It's this instead
A debugger A static structure analyzer
A build tool A read-only intelligence layer
A language server A fast, offline graph query tool
Cloud-dependent Fully local, no telemetry
An IDE replacement A complement to your IDE

Design Principles

  • Zero configuration — point it at any project and it works
  • Read-only always — AJA never writes to or modifies your project
  • Human-readable output — designed for terminals and humans, not just machines
  • Deterministic — same input always produces the same output
  • Fast — sub-second responses on most commands

Requirements

  • Python 3.8+
  • Java or Python project (or both)


If IDEs help you write code, AJA helps you understand it.

Project details


Download files

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

Source Distribution

aja_codeintel-0.1.9.tar.gz (122.0 kB view details)

Uploaded Source

Built Distribution

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

aja_codeintel-0.1.9-py3-none-any.whl (152.9 kB view details)

Uploaded Python 3

File details

Details for the file aja_codeintel-0.1.9.tar.gz.

File metadata

  • Download URL: aja_codeintel-0.1.9.tar.gz
  • Upload date:
  • Size: 122.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for aja_codeintel-0.1.9.tar.gz
Algorithm Hash digest
SHA256 1936f8afeadbb3d1041bd48b90c5705115fbea8ed6b1060754423145e51e9c9a
MD5 64d4ed2e1550a9aab9022efc328a0bbb
BLAKE2b-256 44fd3e78729c6afaa2fe6e47298e8f994d1a9c92f59e77a5a481745a6a33c99f

See more details on using hashes here.

File details

Details for the file aja_codeintel-0.1.9-py3-none-any.whl.

File metadata

  • Download URL: aja_codeintel-0.1.9-py3-none-any.whl
  • Upload date:
  • Size: 152.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for aja_codeintel-0.1.9-py3-none-any.whl
Algorithm Hash digest
SHA256 00f264a7c1d61bbbbd3e5adaa935226c61e1c468b0fec50ff027cd4f89417697
MD5 fc09833fcb9557ac8f380d3d71ba188b
BLAKE2b-256 73a5adecfdb00023032741d552eb81661078f7fcd4b488540ded22365be896ce

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page