navcode 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. navcode-0.1.0/LICENSE +21 -0
  2. navcode-0.1.0/MANIFEST.in +3 -0
  3. navcode-0.1.0/PKG-INFO +81 -0
  4. navcode-0.1.0/README.md +25 -0
  5. navcode-0.1.0/navcode/__init__.py +22 -0
  6. navcode-0.1.0/navcode/_bootstrap.py +122 -0
  7. navcode-0.1.0/navcode/adapters/__init__.py +36 -0
  8. navcode-0.1.0/navcode/adapters/antigravity.py +31 -0
  9. navcode-0.1.0/navcode/adapters/base.py +100 -0
  10. navcode-0.1.0/navcode/adapters/bob.py +33 -0
  11. navcode-0.1.0/navcode/adapters/claude.py +33 -0
  12. navcode-0.1.0/navcode/adapters/codex.py +33 -0
  13. navcode-0.1.0/navcode/adapters/continue_.py +31 -0
  14. navcode-0.1.0/navcode/adapters/copilot.py +24 -0
  15. navcode-0.1.0/navcode/adapters/cursor.py +33 -0
  16. navcode-0.1.0/navcode/adapters/kimi.py +31 -0
  17. navcode-0.1.0/navcode/adapters/windsurf.py +29 -0
  18. navcode-0.1.0/navcode/classifier.py +320 -0
  19. navcode-0.1.0/navcode/cli.py +359 -0
  20. navcode-0.1.0/navcode/embeddings.py +184 -0
  21. navcode-0.1.0/navcode/graph.py +394 -0
  22. navcode-0.1.0/navcode/indexer.py +646 -0
  23. navcode-0.1.0/navcode/mcp_server.py +271 -0
  24. navcode-0.1.0/navcode/parser.py +755 -0
  25. navcode-0.1.0/navcode/retriever.py +471 -0
  26. navcode-0.1.0/navcode/watcher.py +242 -0
  27. navcode-0.1.0/navcode.egg-info/PKG-INFO +81 -0
  28. navcode-0.1.0/navcode.egg-info/SOURCES.txt +32 -0
  29. navcode-0.1.0/navcode.egg-info/dependency_links.txt +1 -0
  30. navcode-0.1.0/navcode.egg-info/entry_points.txt +2 -0
  31. navcode-0.1.0/navcode.egg-info/requires.txt +39 -0
  32. navcode-0.1.0/navcode.egg-info/top_level.txt +1 -0
  33. navcode-0.1.0/pyproject.toml +66 -0
  34. navcode-0.1.0/setup.cfg +4 -0
navcode-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Noman Rafique
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,3 @@
1
+ include LICENSE
2
+ include README.md
3
+ recursive-include navcode *.py
navcode-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,81 @@
1
+ Metadata-Version: 2.4
2
+ Name: navcode
3
+ Version: 0.1.0
4
+ Summary: Codebase intelligence layer for AI coding agents — 80-90% token reduction
5
+ Author-email: Noman Rafique <nomanrafique01@gmail.com>
6
+ License-Expression: MIT
7
+ Keywords: ai,agents,context,codebase,tokens,mcp,claude,cursor
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Requires-Python: >=3.10
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Requires-Dist: typer>=0.12.0
17
+ Requires-Dist: rich>=13.7.0
18
+ Requires-Dist: loguru>=0.7.2
19
+ Requires-Dist: watchdog>=4.0.0
20
+ Requires-Dist: httpx>=0.27.0
21
+ Requires-Dist: numpy>=1.26.0
22
+ Requires-Dist: onnxruntime>=1.18.0
23
+ Requires-Dist: tokenizers>=0.19.0
24
+ Requires-Dist: networkx>=3.3.0
25
+ Requires-Dist: tree-sitter>=0.22.0
26
+ Requires-Dist: fastmcp>=0.4.0
27
+ Requires-Dist: SQLAlchemy>=2.0.0
28
+ Requires-Dist: tree-sitter-python>=0.21.0
29
+ Requires-Dist: tree-sitter-javascript>=0.21.0
30
+ Requires-Dist: tree-sitter-typescript>=0.21.0
31
+ Requires-Dist: tree-sitter-java>=0.21.0
32
+ Requires-Dist: tree-sitter-cpp>=0.22.0
33
+ Requires-Dist: tree-sitter-c>=0.21.0
34
+ Requires-Dist: tree-sitter-go>=0.21.0
35
+ Requires-Dist: tree-sitter-rust>=0.21.0
36
+ Requires-Dist: tree-sitter-ruby>=0.21.0
37
+ Requires-Dist: tree-sitter-c-sharp>=0.21.0
38
+ Requires-Dist: tree-sitter-php>=0.22.0
39
+ Requires-Dist: tree-sitter-swift>=0.6.0
40
+ Requires-Dist: tree-sitter-kotlin>=0.3.0
41
+ Requires-Dist: tree-sitter-scala>=0.21.0
42
+ Requires-Dist: tree-sitter-haskell>=0.21.0
43
+ Requires-Dist: tree-sitter-lua>=0.1.0
44
+ Requires-Dist: tree-sitter-r>=0.1.0
45
+ Requires-Dist: tree-sitter-bash>=0.21.0
46
+ Requires-Dist: tree-sitter-html>=0.20.0
47
+ Requires-Dist: tree-sitter-css>=0.21.0
48
+ Requires-Dist: tree-sitter-json>=0.21.0
49
+ Requires-Dist: tree-sitter-yaml>=0.6.0
50
+ Requires-Dist: tree-sitter-toml>=0.6.0
51
+ Requires-Dist: tree-sitter-markdown>=0.3.0
52
+ Requires-Dist: tree-sitter-sql>=0.2.0
53
+ Requires-Dist: tree-sitter-dockerfile>=0.2.0
54
+ Requires-Dist: tree-sitter-regex>=0.21.0
55
+ Dynamic: license-file
56
+
57
+ # navcode
58
+ > Codebase intelligence layer for AI coding agents
59
+
60
+ ## Install
61
+ ```bash
62
+ pip install navcode
63
+ ```
64
+
65
+ ## Usage
66
+ ```bash
67
+ navcode init --claude
68
+ navcode init --cursor
69
+ navcode init --bob
70
+ navcode init --auto
71
+ ```
72
+
73
+ ## Supported Agents
74
+ Claude Code, Cursor, IBM Bob, Codex, Copilot,
75
+ Kimi, Antigravity, Windsurf, Continue
76
+
77
+ ## How it works
78
+ navcode indexes your codebase locally and feeds only
79
+ relevant context to AI agents — reducing token usage by 80-90%.
80
+
81
+ Built by Nythris Studio
@@ -0,0 +1,25 @@
1
+ # navcode
2
+ > Codebase intelligence layer for AI coding agents
3
+
4
+ ## Install
5
+ ```bash
6
+ pip install navcode
7
+ ```
8
+
9
+ ## Usage
10
+ ```bash
11
+ navcode init --claude
12
+ navcode init --cursor
13
+ navcode init --bob
14
+ navcode init --auto
15
+ ```
16
+
17
+ ## Supported Agents
18
+ Claude Code, Cursor, IBM Bob, Codex, Copilot,
19
+ Kimi, Antigravity, Windsurf, Continue
20
+
21
+ ## How it works
22
+ navcode indexes your codebase locally and feeds only
23
+ relevant context to AI agents — reducing token usage by 80-90%.
24
+
25
+ Built by Nythris Studio
@@ -0,0 +1,22 @@
1
+ from navcode._bootstrap import ensure_model
2
+ from loguru import logger
3
+ from pathlib import Path
4
+
5
+ __version__ = "0.1.0"
6
+
7
+ ensure_model()
8
+
9
+
10
+ def _setup_logging() -> None:
11
+ log_dir = Path.cwd() / ".codenav"
12
+ if log_dir.exists():
13
+ logger.add(
14
+ log_dir / "navcode.log",
15
+ rotation="5 MB",
16
+ retention="7 days",
17
+ level="INFO",
18
+ format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {message}",
19
+ )
20
+
21
+
22
+ _setup_logging()
@@ -0,0 +1,122 @@
1
+ """Bootstrap utilities — ensures the ONNX embedding model is present on disk."""
2
+
3
+ from pathlib import Path
4
+
5
+ import httpx
6
+ from loguru import logger
7
+ from rich.console import Console
8
+ from rich.panel import Panel
9
+ from rich.progress import (
10
+ BarColumn,
11
+ DownloadColumn,
12
+ Progress,
13
+ TextColumn,
14
+ TimeRemainingColumn,
15
+ TransferSpeedColumn,
16
+ )
17
+
18
+ _HF_BASE: str = (
19
+ "https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2/resolve/main"
20
+ )
21
+ MODEL_URL: str = f"{_HF_BASE}/onnx/model_quantized.onnx"
22
+ MODEL_PATH: Path = Path.home() / ".navcode" / "models" / "model_quantized.onnx"
23
+
24
+ # Tokenizer files required by EmbeddingsEngine
25
+ _TOKENIZER_FILES: list[str] = [
26
+ "tokenizer.json",
27
+ "tokenizer_config.json",
28
+ "vocab.txt",
29
+ "special_tokens_map.json",
30
+ ]
31
+
32
+ _console = Console()
33
+
34
+
35
+ def _download_file(url: str, dest: Path, label: str) -> None:
36
+ """Stream *url* to *dest* with a Rich progress bar.
37
+
38
+ Raises:
39
+ httpx.HTTPError: on any HTTP-level failure.
40
+ """
41
+ with httpx.stream("GET", url, follow_redirects=True, timeout=60) as response:
42
+ response.raise_for_status()
43
+ total = int(response.headers.get("content-length", 0)) or None
44
+
45
+ with Progress(
46
+ TextColumn(f"[bold blue]{label}[/bold blue]"),
47
+ BarColumn(),
48
+ DownloadColumn(),
49
+ TransferSpeedColumn(),
50
+ TimeRemainingColumn(),
51
+ console=_console,
52
+ transient=True,
53
+ ) as progress:
54
+ task = progress.add_task("download", total=total)
55
+ with dest.open("wb") as fh:
56
+ for chunk in response.iter_bytes(chunk_size=8192):
57
+ fh.write(chunk)
58
+ progress.update(task, advance=len(chunk))
59
+
60
+
61
+ def ensure_model() -> None:
62
+ """Ensure the quantised ONNX embedding model exists locally.
63
+
64
+ If the model file is already present at ``~/.navcode/models/model_quantized.onnx``
65
+ this function returns immediately. On first run it streams the file from
66
+ HuggingFace, displaying a Rich progress bar. Network failures are caught,
67
+ shown as a Rich warning panel, and silently swallowed so the rest of navcode
68
+ can still load (the model will be re-attempted on ``navcode init``).
69
+ """
70
+ if MODEL_PATH.exists():
71
+ logger.debug("ONNX model already present at {}", MODEL_PATH)
72
+ else:
73
+ MODEL_PATH.parent.mkdir(parents=True, exist_ok=True)
74
+ logger.info("ONNX model not found — downloading from HuggingFace…")
75
+
76
+ try:
77
+ _download_file(MODEL_URL, MODEL_PATH, "Downloading model")
78
+ logger.info("Model saved to {}", MODEL_PATH)
79
+ except httpx.HTTPError as exc:
80
+ _console.print(
81
+ Panel(
82
+ f"[yellow]navcode[/yellow] could not download the embedding model.\n"
83
+ f"[dim]{exc}[/dim]\n\n"
84
+ "navcode will still load — the model will be downloaded on first "
85
+ "[cyan]navcode init[/cyan].",
86
+ title="[bold yellow]⚠ Model download skipped[/bold yellow]",
87
+ border_style="yellow",
88
+ )
89
+ )
90
+ logger.warning("Model download failed: {}", exc)
91
+
92
+ # Ensure tokenizer files are present alongside the model
93
+ _ensure_tokenizer_files()
94
+
95
+
96
+ def _ensure_tokenizer_files() -> None:
97
+ """Download any missing tokenizer files from HuggingFace."""
98
+ models_dir = MODEL_PATH.parent
99
+ models_dir.mkdir(parents=True, exist_ok=True)
100
+
101
+ for filename in _TOKENIZER_FILES:
102
+ dest = models_dir / filename
103
+ if dest.exists():
104
+ logger.debug("Tokenizer file already present: {}", filename)
105
+ continue
106
+
107
+ url = f"{_HF_BASE}/{filename}"
108
+ logger.info("Tokenizer file not found — downloading: {}", filename)
109
+ try:
110
+ _download_file(url, dest, f"Downloading {filename}")
111
+ logger.info("Saved {}", dest)
112
+ except httpx.HTTPError as exc:
113
+ _console.print(
114
+ Panel(
115
+ f"[yellow]navcode[/yellow] could not download [cyan]{filename}[/cyan].\n"
116
+ f"[dim]{exc}[/dim]\n\n"
117
+ "Semantic search may be unavailable until this file is present.",
118
+ title="[bold yellow]⚠ Tokenizer file download skipped[/bold yellow]",
119
+ border_style="yellow",
120
+ )
121
+ )
122
+ logger.warning("Tokenizer file download failed ({}): {}", filename, exc)
@@ -0,0 +1,36 @@
1
+ """navcode agent adapters — one per supported AI coding agent."""
2
+
3
+ from navcode.adapters.claude import ClaudeAdapter
4
+ from navcode.adapters.cursor import CursorAdapter
5
+ from navcode.adapters.codex import CodexAdapter
6
+ from navcode.adapters.copilot import CopilotAdapter
7
+ from navcode.adapters.bob import BobAdapter
8
+ from navcode.adapters.kimi import KimiAdapter
9
+ from navcode.adapters.antigravity import AntigravityAdapter
10
+ from navcode.adapters.windsurf import WindsurfAdapter
11
+ from navcode.adapters.continue_ import ContinueAdapter
12
+
13
+ ALL_ADAPTERS = {
14
+ "claude": ClaudeAdapter,
15
+ "cursor": CursorAdapter,
16
+ "codex": CodexAdapter,
17
+ "copilot": CopilotAdapter,
18
+ "bob": BobAdapter,
19
+ "kimi": KimiAdapter,
20
+ "antigravity": AntigravityAdapter,
21
+ "windsurf": WindsurfAdapter,
22
+ "continue": ContinueAdapter,
23
+ }
24
+
25
+ __all__ = [
26
+ "ClaudeAdapter",
27
+ "CursorAdapter",
28
+ "CodexAdapter",
29
+ "CopilotAdapter",
30
+ "BobAdapter",
31
+ "KimiAdapter",
32
+ "AntigravityAdapter",
33
+ "WindsurfAdapter",
34
+ "ContinueAdapter",
35
+ "ALL_ADAPTERS",
36
+ ]
@@ -0,0 +1,31 @@
1
+ """Antigravity adapter."""
2
+
3
+ from pathlib import Path
4
+
5
+ from navcode.adapters.base import BaseAdapter
6
+
7
+
8
+ class AntigravityAdapter(BaseAdapter):
9
+
10
+ NAME = "Antigravity"
11
+ BINARY = "antigravity"
12
+ CONFIG_DIR = "~/.antigravity"
13
+ PROJECT_DIR = ".antigravity"
14
+ PROCESS_NAME = "antigravity"
15
+ INSTRUCTION_FILE = ".antigravity/instructions.md"
16
+
17
+ def install(self) -> None:
18
+ self._write_instruction_file(
19
+ self.project_root / ".antigravity" / "instructions.md",
20
+ self._instruction_content(),
21
+ )
22
+ self._inject_mcp_config(
23
+ Path.home() / ".antigravity" / "mcp.json"
24
+ )
25
+
26
+ def is_detected(self) -> bool:
27
+ return (
28
+ self._detect_binary()
29
+ or self._detect_config_dir()
30
+ or self._detect_project_dir()
31
+ )
@@ -0,0 +1,100 @@
1
+ """Abstract base class for all navcode agent adapters."""
2
+
3
+ from abc import ABC, abstractmethod
4
+ from pathlib import Path
5
+
6
+
7
+ class BaseAdapter(ABC):
8
+
9
+ # Override these in every adapter
10
+ NAME: str = ""
11
+ BINARY: str = ""
12
+ CONFIG_DIR: str = ""
13
+ PROJECT_DIR: str = ""
14
+ PROCESS_NAME: str | None = None
15
+ INSTRUCTION_FILE: str = ""
16
+
17
+ def __init__(self, project_root: Path):
18
+ self.project_root = project_root
19
+ self.codenav_dir = project_root / ".codenav"
20
+
21
+ @abstractmethod
22
+ def install(self) -> None:
23
+ """Create all required files for this agent."""
24
+ pass
25
+
26
+ @abstractmethod
27
+ def is_detected(self) -> bool:
28
+ """Return True if this agent is installed on the system."""
29
+ pass
30
+
31
+ def _write_instruction_file(self, path: Path, content: str) -> None:
32
+ """Write instruction file, create parent dirs if needed."""
33
+ path.parent.mkdir(parents=True, exist_ok=True)
34
+ path.write_text(content, encoding="utf-8")
35
+
36
+ def _inject_mcp_config(self, config_path: Path) -> None:
37
+ """Inject navcode MCP entry into agent JSON config."""
38
+ import json
39
+
40
+ config_path.parent.mkdir(parents=True, exist_ok=True)
41
+
42
+ existing = {}
43
+ if config_path.exists():
44
+ try:
45
+ existing = json.loads(config_path.read_text())
46
+ except json.JSONDecodeError:
47
+ pass
48
+
49
+ existing.setdefault("mcpServers", {})
50
+ existing["mcpServers"]["navcode"] = {
51
+ "command": "navcode",
52
+ "args": ["mcp-serve"],
53
+ "cwd": str(self.project_root),
54
+ }
55
+ config_path.write_text(
56
+ json.dumps(existing, indent=2),
57
+ encoding="utf-8",
58
+ )
59
+
60
+ def _detect_binary(self) -> bool:
61
+ import shutil
62
+
63
+ return shutil.which(self.BINARY) is not None
64
+
65
+ def _detect_config_dir(self) -> bool:
66
+ return Path.home().joinpath(
67
+ self.CONFIG_DIR.lstrip("~/")
68
+ ).exists()
69
+
70
+ def _detect_project_dir(self) -> bool:
71
+ return (self.project_root / self.PROJECT_DIR).exists()
72
+
73
+ def _instruction_content(self) -> str:
74
+ return f"""# navcode — Active
75
+
76
+ ## Rules for {self.NAME}
77
+
78
+ NEVER use read_file or list_directory to explore the codebase.
79
+ ALWAYS start every task with navcode_get_context(task=<your task>).
80
+ Work ONLY within files and symbols navcode returns.
81
+ If you need more: call navcode_expand_context(file_path, reason).
82
+
83
+ ## Available MCP Tools
84
+
85
+ | Tool | When to use |
86
+ |---|---|
87
+ | navcode_get_context(task) | FIRST call — always |
88
+ | navcode_expand_context(file, reason) | Need more from one file |
89
+ | navcode_get_callers(function) | Understand blast radius |
90
+ | navcode_get_deps(file) | See what a file imports |
91
+ | navcode_search(query) | Find where something is defined |
92
+ | navcode_get_structure() | Architectural overview |
93
+ | navcode_stats() | Index health check |
94
+
95
+ ## Why
96
+ navcode has pre-indexed this codebase.
97
+ Using it saves 80-90% tokens vs raw file reads.
98
+
99
+ Built by Nythris Studio
100
+ """
@@ -0,0 +1,33 @@
1
+ """IBM Bob adapter."""
2
+
3
+ from pathlib import Path
4
+
5
+ from navcode.adapters.base import BaseAdapter
6
+
7
+
8
+ class BobAdapter(BaseAdapter):
9
+
10
+ NAME = "IBM Bob"
11
+ BINARY = "bob"
12
+ CONFIG_DIR = "~/.bob"
13
+ PROJECT_DIR = ".bob"
14
+ PROCESS_NAME = "bob-agent"
15
+ INSTRUCTION_FILE = ".bob/instructions.md"
16
+
17
+ def install(self) -> None:
18
+ # 1. Write .bob/instructions.md
19
+ self._write_instruction_file(
20
+ self.project_root / ".bob" / "instructions.md",
21
+ self._instruction_content(),
22
+ )
23
+ # 2. Inject MCP into ~/.bob/mcp.json
24
+ self._inject_mcp_config(
25
+ Path.home() / ".bob" / "mcp.json"
26
+ )
27
+
28
+ def is_detected(self) -> bool:
29
+ return (
30
+ self._detect_binary()
31
+ or self._detect_config_dir()
32
+ or self._detect_project_dir()
33
+ )
@@ -0,0 +1,33 @@
1
+ """Claude Code adapter."""
2
+
3
+ from pathlib import Path
4
+
5
+ from navcode.adapters.base import BaseAdapter
6
+
7
+
8
+ class ClaudeAdapter(BaseAdapter):
9
+
10
+ NAME = "Claude Code"
11
+ BINARY = "claude"
12
+ CONFIG_DIR = "~/.claude"
13
+ PROJECT_DIR = "CLAUDE.md"
14
+ PROCESS_NAME = None
15
+ INSTRUCTION_FILE = "CLAUDE.md"
16
+
17
+ def install(self) -> None:
18
+ # 1. Write CLAUDE.md to project root
19
+ self._write_instruction_file(
20
+ self.project_root / "CLAUDE.md",
21
+ self._instruction_content(),
22
+ )
23
+ # 2. Inject MCP into ~/.claude/mcp.json
24
+ self._inject_mcp_config(
25
+ Path.home() / ".claude" / "mcp.json"
26
+ )
27
+
28
+ def is_detected(self) -> bool:
29
+ return (
30
+ self._detect_binary()
31
+ or self._detect_config_dir()
32
+ or self._detect_project_dir()
33
+ )
@@ -0,0 +1,33 @@
1
+ """Codex CLI adapter."""
2
+
3
+ from pathlib import Path
4
+
5
+ from navcode.adapters.base import BaseAdapter
6
+
7
+
8
+ class CodexAdapter(BaseAdapter):
9
+
10
+ NAME = "Codex CLI"
11
+ BINARY = "codex"
12
+ CONFIG_DIR = "~/.codex"
13
+ PROJECT_DIR = "AGENTS.md"
14
+ PROCESS_NAME = None
15
+ INSTRUCTION_FILE = "AGENTS.md"
16
+
17
+ def install(self) -> None:
18
+ # 1. Write AGENTS.md
19
+ self._write_instruction_file(
20
+ self.project_root / "AGENTS.md",
21
+ self._instruction_content(),
22
+ )
23
+ # 2. Inject MCP into ~/.codex/config.json
24
+ self._inject_mcp_config(
25
+ Path.home() / ".codex" / "config.json"
26
+ )
27
+
28
+ def is_detected(self) -> bool:
29
+ return (
30
+ self._detect_binary()
31
+ or self._detect_config_dir()
32
+ or self._detect_project_dir()
33
+ )
@@ -0,0 +1,31 @@
1
+ """Continue adapter."""
2
+
3
+ from pathlib import Path
4
+
5
+ from navcode.adapters.base import BaseAdapter
6
+
7
+
8
+ class ContinueAdapter(BaseAdapter):
9
+
10
+ NAME = "Continue"
11
+ BINARY = "continue"
12
+ CONFIG_DIR = "~/.continue"
13
+ PROJECT_DIR = ".continue"
14
+ PROCESS_NAME = None
15
+ INSTRUCTION_FILE = ".continue/navcode.md"
16
+
17
+ def install(self) -> None:
18
+ self._write_instruction_file(
19
+ self.project_root / ".continue" / "navcode.md",
20
+ self._instruction_content(),
21
+ )
22
+ self._inject_mcp_config(
23
+ Path.home() / ".continue" / "config.json"
24
+ )
25
+
26
+ def is_detected(self) -> bool:
27
+ return (
28
+ self._detect_binary()
29
+ or self._detect_config_dir()
30
+ or self._detect_project_dir()
31
+ )
@@ -0,0 +1,24 @@
1
+ """GitHub Copilot adapter."""
2
+
3
+ from navcode.adapters.base import BaseAdapter
4
+
5
+
6
+ class CopilotAdapter(BaseAdapter):
7
+
8
+ NAME = "GitHub Copilot"
9
+ BINARY = "gh"
10
+ CONFIG_DIR = "~/.config/gh"
11
+ PROJECT_DIR = ".github"
12
+ PROCESS_NAME = None
13
+ INSTRUCTION_FILE = ".github/copilot-instructions.md"
14
+
15
+ def install(self) -> None:
16
+ # Write .github/copilot-instructions.md
17
+ self._write_instruction_file(
18
+ self.project_root / ".github" / "copilot-instructions.md",
19
+ self._instruction_content(),
20
+ )
21
+ # No MCP config for Copilot yet
22
+
23
+ def is_detected(self) -> bool:
24
+ return self._detect_binary() or self._detect_project_dir()
@@ -0,0 +1,33 @@
1
+ """Cursor adapter."""
2
+
3
+ from pathlib import Path
4
+
5
+ from navcode.adapters.base import BaseAdapter
6
+
7
+
8
+ class CursorAdapter(BaseAdapter):
9
+
10
+ NAME = "Cursor"
11
+ BINARY = "cursor"
12
+ CONFIG_DIR = "~/.cursor"
13
+ PROJECT_DIR = ".cursor"
14
+ PROCESS_NAME = "cursor"
15
+ INSTRUCTION_FILE = ".cursor/rules/navcode.md"
16
+
17
+ def install(self) -> None:
18
+ # 1. Write .cursor/rules/navcode.md
19
+ self._write_instruction_file(
20
+ self.project_root / ".cursor" / "rules" / "navcode.md",
21
+ self._instruction_content(),
22
+ )
23
+ # 2. Inject MCP into .cursor/mcp.json
24
+ self._inject_mcp_config(
25
+ self.project_root / ".cursor" / "mcp.json"
26
+ )
27
+
28
+ def is_detected(self) -> bool:
29
+ return (
30
+ self._detect_binary()
31
+ or self._detect_config_dir()
32
+ or self._detect_project_dir()
33
+ )
@@ -0,0 +1,31 @@
1
+ """Kimi Code adapter."""
2
+
3
+ from pathlib import Path
4
+
5
+ from navcode.adapters.base import BaseAdapter
6
+
7
+
8
+ class KimiAdapter(BaseAdapter):
9
+
10
+ NAME = "Kimi Code"
11
+ BINARY = "kimi"
12
+ CONFIG_DIR = "~/.kimi"
13
+ PROJECT_DIR = "KIMI.md"
14
+ PROCESS_NAME = None
15
+ INSTRUCTION_FILE = "KIMI.md"
16
+
17
+ def install(self) -> None:
18
+ self._write_instruction_file(
19
+ self.project_root / "KIMI.md",
20
+ self._instruction_content(),
21
+ )
22
+ self._inject_mcp_config(
23
+ Path.home() / ".kimi" / "mcp.json"
24
+ )
25
+
26
+ def is_detected(self) -> bool:
27
+ return (
28
+ self._detect_binary()
29
+ or self._detect_config_dir()
30
+ or self._detect_project_dir()
31
+ )