Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
494 changes: 408 additions & 86 deletions Cargo.lock

Large diffs are not rendered by default.

9 changes: 7 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "naviscope"
version = "0.1.0"
version = "0.2.0"
edition = "2024"

[dependencies]
Expand All @@ -20,7 +20,6 @@ regex = "1.11.1"
tokio = { version = "1.49.0", features = ["rt-multi-thread", "macros", "sync", "time"] }
schemars = "1.2.0"
rmcp = { version = "0.13.0", features = ["macros", "server", "transport-io"] }
postcard = { version = "1.1.3", features = ["use-std"] }
tower-lsp = "0.20"
futures = "0.3"
dashmap = "6.1.0"
Expand All @@ -31,6 +30,12 @@ tracing = "0.1.44"
tracing-subscriber = { version = "0.3.22", features = ["env-filter"] }
tracing-appender = "0.2.4"
tokio-tungstenite = "0.28.0"
reedline = "0.45.0"
dirs = "6.0.0"
nu-ansi-term = "0.50.3"
shlex = "1.3.0"
tabled = "0.20.0"
rmp-serde = "1.3.1"

[build-dependencies]
cc = "1.2"
68 changes: 46 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
# Naviscope

Naviscope is a graph-based, structured code query engine specifically designed for Large Language Models (LLMs). It builds a comprehensive **Code Knowledge Graph** that bridges the gap between micro-level source code semantics (calls, inheritance) and macro-level project structures (modules, packages, dependencies).
Naviscope is a **unified Code Knowledge Graph engine** that bridges the gap between AI agents and developers. It builds a comprehensive graph representation of your codebase, connecting micro-level source code semantics (calls, inheritance) with macro-level project structures (modules, packages, dependencies).

Unlike traditional text search, Naviscope provides a deep, structured understanding of your codebase, enabling LLMs to navigate and reason about complex software systems with precision.
Unlike traditional text search or language servers, Naviscope provides a **single, unified knowledge graph** that powers both LLM agents (via MCP) and IDE features (via LSP), enabling precise code navigation and reasoning across complex software systems.

## 🌟 Key Features

- **Code Knowledge Graph**: Represents project entities and their complex relationships in a unified graph using `petgraph`.
- **LLM-Friendly DSL**: A shell-like query interface (`grep`, `ls`, `inspect`, `incoming`, `outgoing`) that returns structured JSON data optimized for LLM agents.
- **Unified Code Knowledge Graph**: A single graph representation using `petgraph` that powers both MCP (for LLMs) and LSP (for IDEs), ensuring consistency across all tools.
- **Zero JVM Overhead**: Built entirely in Rust, providing instant startup and low memory footprint—no more waiting for Java language servers to index.
- **LLM-Optimized Query Interface**: Structured JSON responses via MCP tools (`grep`, `ls`, `inspect`, `deps`) designed specifically for AI agent consumption.
- **High-Performance Indexing**: A robust 3-phase processing pipeline (Scan & Parse → Resolve → Apply) utilizing Rust's concurrency for maximum speed.
- **Real-time Synchronization**: Automatic graph updates via file system watching (`notify`), ensuring the index stays consistent with your changes.
- **Multi-Protocol Interface**: Support for both **MCP** (Model Context Protocol) for AI agents and **LSP** (Language Server Protocol) for IDEs.
- **Extensible Architecture**: Language-neutral core with a strategy-based resolver. Currently focused on **Java + Gradle**, with Maven support in progress.
- **Dual Protocol Support**: Native **MCP** (Model Context Protocol) for AI agents and **LSP** (Language Server Protocol) for IDEs, both sharing the same underlying graph.
- **Resilient & Fast**: Works effectively even with syntax errors or missing dependencies, providing immediate feedback without blocking on incomplete code.
- **Extensible Architecture**: Language-neutral core with a strategy-based resolver. Currently supports **Java + Gradle**, with Maven support in progress.

## 🏗️ Architecture

Expand Down Expand Up @@ -43,7 +45,7 @@ npm run package

### CLI Commands
- `naviscope index <PATH>`: Build a persistent index for a project (stored in `~/.naviscope/indices`).
- `naviscope query <PATH> <JSON>`: Execute a structured DSL query manually.
- `naviscope shell [PATH]`: Start an interactive shell to query the code knowledge graph.
- `naviscope watch <PATH>`: Start a background service to keep the index updated as you edit files.
- `naviscope schema`: Display the JSON schema and examples for the GraphQuery DSL.
- `naviscope clear [PATH]`: Remove specific project index or clear all cached indices.
Expand All @@ -54,11 +56,10 @@ npm run package
Naviscope implements the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/), allowing LLM agents like Cursor and Claude to directly use its code knowledge graph.

#### Available Tools
- **`grep`**: Global search for symbols by pattern and kind (Class, Method, etc.).
- **`ls`**: List package members, class fields, or project modules.
- **`grep`**: Global search for symbols by pattern and kind (Class, Method, etc.) across the entire project.
- **`ls`**: List package members, class fields, or project modules. Explore project structure hierarchically.
- **`inspect`**: Retrieve full metadata and source code for a specific Fully Qualified Name (FQN).
- **`incoming`**: Trace inbound relationships like callers, implementers, or references.
- **`outgoing`**: Trace outbound relationships like callees or class dependencies.
- **`deps`**: Analyze dependencies—outgoing (what I depend on) or incoming (who depends on me) with optional edge type filtering.

#### Configuring in Cursor
To use Naviscope in Cursor:
Expand Down Expand Up @@ -106,27 +107,50 @@ Naviscope acts as a high-performance LSP server for Java, offering a lightweight
- **Other Editors**: Simply point your LSP client to the `naviscope lsp` command.

#### Why Naviscope LSP?
- **Zero JVM Overhead**: No more "Java Language Server is indexing..." hanging your UI.
- **Resilient**: Works even if your code has syntax errors or missing dependencies.
- **Unified Knowledge**: Shares the same core graph used by MCP for LLM agents.
- **Zero JVM Overhead**: Built in Rust, providing instant startup and low memory usage—no more "Java Language Server is indexing..." blocking your workflow.
- **Resilient**: Works effectively even with syntax errors or missing dependencies, providing immediate navigation without waiting for perfect code.
- **Unified Knowledge Graph**: Shares the exact same core graph used by MCP for LLM agents, ensuring consistency between AI-assisted development and manual navigation.
- **Lightweight Alternative**: A fast, memory-efficient replacement for JDTLS that doesn't require a full Java runtime.

## 🛠️ Query API Examples

The Query DSL (used by `naviscope query` and MCP) supports several commands for structured exploration:
- `grep`: `{"command": "grep", "pattern": "UserService", "kind": ["class"]}`
- `ls`: `{"command": "ls", "fqn": "com.example.service"}`
- `inspect`: `{"command": "inspect", "fqn": "com.example.service.UserService"}`
- `incoming`: `{"command": "incoming", "fqn": "com.example.service.UserService#save", "edge_type": ["Calls"]}`
- `outgoing`: `{"command": "outgoing", "fqn": "com.example.service.UserService"}`
The Query DSL (used by `naviscope shell` and MCP) supports several commands for structured exploration:

**Shell Commands:**
```bash
grep "UserService" # Search for symbols matching pattern
ls "com.example.service" # List package contents
cat "com.example.service.UserService" # Inspect full details of a symbol
deps "com.example.service.UserService" # Show dependencies (outgoing by default)
deps --rev "com.example.service.UserService" # Show reverse dependencies (incoming)
```

**JSON DSL (for MCP/API):**
```json
{"command": "grep", "pattern": "UserService", "kind": ["class"], "limit": 20}
{"command": "ls", "fqn": "com.example.service", "kind": ["class", "interface"]}
{"command": "cat", "fqn": "com.example.service.UserService"}
{"command": "deps", "fqn": "com.example.service.UserService", "rev": false, "edge_type": ["Calls", "InheritsFrom"]}
```

## 🎯 Project Positioning

Naviscope fills a unique niche in the developer tooling ecosystem:

**For LLM Agents**: Provides structured, graph-based code understanding that goes far beyond text search, enabling AI assistants to reason about code relationships, dependencies, and architecture.

**For Developers**: Offers a lightweight, fast LSP server that doesn't require JVM overhead, with the added benefit of sharing the same knowledge graph that powers AI-assisted development.

**The Unified Advantage**: Unlike traditional tools that maintain separate indexes for different purposes, Naviscope's single knowledge graph ensures that what AI agents see is exactly what developers navigate—creating a seamless, consistent experience across all development workflows.

## 📈 Roadmap (V1)
- [x] Core Graph Storage (`petgraph`)
- [x] Java & Gradle Parser (Tree-sitter driven)
- [x] Shell-like Query DSL Engine
- [x] Parallel Indexing & Real-time Updates (`notify`)
- [x] MCP Server implementation
- [x] MCP Server implementation (grep, ls, inspect, deps)
- [x] LSP Support (Definition, References, Hierarchy, Hover, etc.)
- [x] VSCode Extension (Initial version)
- [x] VSCode Extension
- [ ] Maven Support (In Progress)
- [ ] Python/Rust Language Strategies (Planned)

Expand Down
20 changes: 12 additions & 8 deletions editors/vscode/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Naviscope for VS Code

Naviscope is a graph-based, structured code query engine that powers your coding experience with deep semantic understanding. This extension brings the power of Naviscope's Language Server Protocol (LSP) integration directly into VS Code, offering a lightweight and blazing-fast alternative for Java navigation.
Naviscope is a unified Code Knowledge Graph engine that powers both AI agents and developers. This VS Code extension brings Naviscope's Language Server Protocol (LSP) integration directly into your editor, offering a lightweight, blazing-fast alternative to JDTLS for Java navigation.

## 🚀 Features

Expand All @@ -20,9 +20,10 @@ Naviscope builds a comprehensive Code Knowledge Graph of your project, enabling
- **Document Highlights**: Highlight all occurrences of a symbol in the current file.

### Why Use Naviscope?
- **Zero JVM Overhead**: No heavy background processes or memory-hogging language servers.
- **Resilient Indexing**: Works effectively even with syntax errors or incomplete code.
- **Unified Graph**: Built on the same engine used by LLM agents via MCP.
- **Zero JVM Overhead**: Built entirely in Rust—no Java runtime required, instant startup, minimal memory footprint.
- **Resilient Indexing**: Works effectively even with syntax errors or incomplete code, providing immediate navigation without waiting for perfect builds.
- **Unified Knowledge Graph**: Shares the exact same code knowledge graph used by LLM agents via MCP, ensuring consistency between AI-assisted development and manual navigation.
- **Lightweight Alternative**: A fast, memory-efficient replacement for JDTLS that doesn't block your workflow.

## 📦 System Requirements

Expand All @@ -32,15 +33,18 @@ Naviscope builds a comprehensive Code Knowledge Graph of your project, enabling

## 📦 Installation

Just install the extension!
1. Install the extension from the VS Code marketplace or from a `.vsix` file.
2. Ensure the `naviscope` binary is available in your PATH, or configure the `naviscope.path` setting to point to the binary location.
3. Open a Java project—Naviscope will automatically start indexing your workspace.

On first launch, Naviscope will automatically detect your platform and download the necessary binary engine to `~/.naviscope/bin`. It's completely managed by the extension—no manual configuration required.
**Note**: You need to have the `naviscope` CLI installed separately. See the [main repository](https://github.com/biuld/naviscope) for installation instructions.

## 🔧 Troubleshooting

If the extension fails to start:
1. Check your internet connection if this is the first run (the binary needs to be downloaded).
2. Check the "Naviscope Client" output channel in VS Code for detailed logs.
1. Ensure the `naviscope` binary is installed and available in your PATH, or configure `naviscope.path` in VS Code settings.
2. Check the "Naviscope Client" output channel in VS Code for detailed logs.
3. Verify your project is a valid Java/Gradle project structure.

## 🗑️ Uninstallation

Expand Down
2 changes: 1 addition & 1 deletion editors/vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "naviscope",
"displayName": "Naviscope",
"description": "Graph-based structured code navigation for Java",
"version": "0.1.0",
"version": "0.2.0",
"publisher": "naviscope",
"repository": {
"type": "git",
Expand Down
30 changes: 28 additions & 2 deletions editors/vscode/src/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,35 @@ const BINARY_NAME = 'naviscope';
const REPO_OWNER = 'biuld';
const REPO_NAME = 'naviscope';
// Update this version when bundling a new version of the extension
const EXPECTED_VERSION = '0.1.0';
const EXPECTED_VERSION = '0.2.0';

/**
* Check if naviscope is available in PATH
*/
async function checkPathForNaviscope(): Promise<string | null> {
try {
// Use 'which' on Unix-like systems, 'where' on Windows
const command = process.platform === 'win32' ? 'where' : 'which';
const { stdout } = await execAsync(`${command} ${BINARY_NAME}`);
const pathInPath = stdout.trim().split('\n')[0];
if (pathInPath && fs.existsSync(pathInPath)) {
return pathInPath;
}
} catch (e) {
// Command not found in PATH
}
return null;
}

export async function bootstrap(context: vscode.ExtensionContext): Promise<string | undefined> {
// First, check if naviscope is available in PATH
const pathBinary = await checkPathForNaviscope();
if (pathBinary) {
// If found in PATH, use it directly without downloading or checking updates
return pathBinary;
}

// Only download and check updates if naviscope is not in PATH
const naviscopeHome = path.join(os.homedir(), '.naviscope');
const binDir = path.join(naviscopeHome, 'bin');

Expand Down Expand Up @@ -81,7 +107,7 @@ export async function bootstrap(context: vscode.ExtensionContext): Promise<strin
async function checkVersion(binaryPath: string): Promise<boolean> {
try {
const { stdout } = await execAsync(`"${binaryPath}" --version`);
// Expected output: "naviscope 0.1.0"
// Expected output: "naviscope 0.2.0"
return stdout.includes(EXPECTED_VERSION);
} catch (e) {
console.warn('Failed to check version:', e);
Expand Down
20 changes: 8 additions & 12 deletions src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
mod index;
mod query;
mod shell;
mod schema;
mod watch;
mod clear;
Expand Down Expand Up @@ -35,17 +35,13 @@ pub enum Commands {
#[arg(long)]
debug: bool,
},
/// Query the code knowledge graph using JSON DSL
#[command(long_about = "Executes a structured query against an existing index. \
The query should be a JSON object following the GraphQuery schema.")]
Query {
/// Path to the project root (used to locate the default index)
/// Start an interactive shell to query the code knowledge graph
#[command(long_about = "Starts an interactive shell where you can execute structured queries \
against the index using both JSON DSL and shorthand commands.")]
Shell {
/// Path to the project root (used to locate the default index). Defaults to current directory.
#[arg(value_name = "PROJECT_PATH")]
path: PathBuf,

/// Structured query in JSON format (e.g., '{"command": "grep", "pattern": "MyClass"}')
#[arg(value_name = "JSON_QUERY")]
query: String,
path: Option<PathBuf>,
},
/// Show the JSON schema/examples for GraphQuery
Schema,
Expand Down Expand Up @@ -95,7 +91,7 @@ pub fn run() -> Result<(), Box<dyn std::error::Error>> {
path,
debug,
} => index::run(path, debug),
Commands::Query { path, query } => query::run(path, query),
Commands::Shell { path } => shell::run(path),
Commands::Schema => schema::run(),
Commands::Watch { path, debug } => watch::run(path, debug),
Commands::Clear { path } => clear::run(path),
Expand Down
18 changes: 0 additions & 18 deletions src/cli/query.rs

This file was deleted.

Loading
Loading