code-context-engine 0.4.10__tar.gz → 0.4.11__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.
- {code_context_engine-0.4.10/src/code_context_engine.egg-info → code_context_engine-0.4.11}/PKG-INFO +5 -3
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/README.md +3 -1
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/pyproject.toml +2 -2
- {code_context_engine-0.4.10 → code_context_engine-0.4.11/src/code_context_engine.egg-info}/PKG-INFO +5 -3
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/code_context_engine.egg-info/SOURCES.txt +1 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/editors.py +65 -2
- code_context_engine-0.4.11/tests/test_editors_opencode.py +74 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/LICENSE +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/setup.cfg +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/code_context_engine.egg-info/dependency_links.txt +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/code_context_engine.egg-info/entry_points.txt +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/code_context_engine.egg-info/requires.txt +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/code_context_engine.egg-info/top_level.txt +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/__init__.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/cli.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/cli_style.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/compression/__init__.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/compression/compressor.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/compression/ollama_client.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/compression/output_rules.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/compression/prompts.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/compression/quality.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/config.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/dashboard/__init__.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/dashboard/_page.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/dashboard/server.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/event_bus.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/indexer/__init__.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/indexer/chunker.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/indexer/embedder.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/indexer/embedding_cache.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/indexer/git_hooks.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/indexer/git_indexer.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/indexer/ignorefile.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/indexer/manifest.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/indexer/pipeline.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/indexer/secrets.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/indexer/watcher.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/integration/__init__.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/integration/bootstrap.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/integration/git_context.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/integration/mcp_server.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/integration/session_capture.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/memory/__init__.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/memory/compressor.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/memory/db.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/memory/extractive.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/memory/grammar.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/memory/hook_installer.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/memory/hook_server.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/memory/hooks.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/memory/migrate.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/models.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/pricing.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/project_commands.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/retrieval/__init__.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/retrieval/confidence.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/retrieval/query_parser.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/retrieval/retriever.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/serve_http.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/services.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/storage/__init__.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/storage/backend.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/storage/fts_store.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/storage/graph_store.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/storage/local_backend.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/storage/remote_backend.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/storage/vector_store.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/utils.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/tests/test_cli_init_probe.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/tests/test_cli_mcp_config.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/tests/test_cli_savings.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/tests/test_cli_savings_buckets.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/tests/test_cli_savings_e2e.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/tests/test_cli_serve.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/tests/test_cli_sessions_export.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/tests/test_cli_sessions_status.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/tests/test_cli_smoke.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/tests/test_cli_uninstall.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/tests/test_config.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/tests/test_e2e.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/tests/test_event_bus.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/tests/test_models.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/tests/test_project_commands.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/tests/test_real_life.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/tests/test_services.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/tests/test_token_efficiency.py +0 -0
- {code_context_engine-0.4.10 → code_context_engine-0.4.11}/tests/test_token_packing.py +0 -0
{code_context_engine-0.4.10/src/code_context_engine.egg-info → code_context_engine-0.4.11}/PKG-INFO
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-context-engine
|
|
3
|
-
Version: 0.4.
|
|
4
|
-
Summary: Index your codebase. AI searches instead of re-reading files. 94% token savings, benchmarked on FastAPI. Works with Claude Code, Cursor, VS Code, Gemini CLI, and
|
|
3
|
+
Version: 0.4.11
|
|
4
|
+
Summary: Index your codebase. AI searches instead of re-reading files. 94% token savings, benchmarked on FastAPI. Works with Claude Code, Cursor, VS Code, Gemini CLI, Codex, and OpenCode.
|
|
5
5
|
Author-email: Fazle Elahee <felahee@gmail.com>, Raj <rajkumar.sakti@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/elara-labs/code-context-engine
|
|
@@ -78,7 +78,8 @@ Dynamic: license-file
|
|
|
78
78
|
<a href="#install-and-see-savings-in-60-seconds"><img src="https://img.shields.io/badge/VS_Code-007ACC?style=for-the-badge&logo=visual-studio-code&logoColor=white" alt="VS Code" height="36"></a>
|
|
79
79
|
<a href="#install-and-see-savings-in-60-seconds"><img src="https://img.shields.io/badge/Cursor-000000?style=for-the-badge&logo=cursor&logoColor=white" alt="Cursor" height="36"></a>
|
|
80
80
|
<a href="#install-and-see-savings-in-60-seconds"><img src="https://img.shields.io/badge/Gemini_CLI-4285F4?style=for-the-badge&logo=google&logoColor=white" alt="Gemini CLI" height="36"></a>
|
|
81
|
-
<a href="#install-and-see-savings-in-60-seconds"><img src="https://img.shields.io/badge/Codex_CLI-412991?style=for-the-badge&logo=openai&logoColor=white" alt="Codex CLI" height="36"></a
|
|
81
|
+
<a href="#install-and-see-savings-in-60-seconds"><img src="https://img.shields.io/badge/Codex_CLI-412991?style=for-the-badge&logo=openai&logoColor=white" alt="Codex CLI" height="36"></a>
|
|
82
|
+
<a href="#install-and-see-savings-in-60-seconds"><img src="https://img.shields.io/badge/OpenCode-22C55E?style=for-the-badge&logo=terminal&logoColor=white" alt="OpenCode" height="36"></a>
|
|
82
83
|
</p>
|
|
83
84
|
|
|
84
85
|
<p align="center">
|
|
@@ -125,6 +126,7 @@ Restart your editor. Done. Every question now hits the index instead of re-readi
|
|
|
125
126
|
| Cursor | `.cursor/mcp.json` | `.cursorrules` |
|
|
126
127
|
| Gemini CLI | `.gemini/settings.json` | `GEMINI.md` |
|
|
127
128
|
| OpenAI Codex | `.codex/config.toml` | |
|
|
129
|
+
| OpenCode | `opencode.json` | |
|
|
128
130
|
|
|
129
131
|
Multiple editors in the same project? All get configured in one command.
|
|
130
132
|
|
|
@@ -29,7 +29,8 @@
|
|
|
29
29
|
<a href="#install-and-see-savings-in-60-seconds"><img src="https://img.shields.io/badge/VS_Code-007ACC?style=for-the-badge&logo=visual-studio-code&logoColor=white" alt="VS Code" height="36"></a>
|
|
30
30
|
<a href="#install-and-see-savings-in-60-seconds"><img src="https://img.shields.io/badge/Cursor-000000?style=for-the-badge&logo=cursor&logoColor=white" alt="Cursor" height="36"></a>
|
|
31
31
|
<a href="#install-and-see-savings-in-60-seconds"><img src="https://img.shields.io/badge/Gemini_CLI-4285F4?style=for-the-badge&logo=google&logoColor=white" alt="Gemini CLI" height="36"></a>
|
|
32
|
-
<a href="#install-and-see-savings-in-60-seconds"><img src="https://img.shields.io/badge/Codex_CLI-412991?style=for-the-badge&logo=openai&logoColor=white" alt="Codex CLI" height="36"></a
|
|
32
|
+
<a href="#install-and-see-savings-in-60-seconds"><img src="https://img.shields.io/badge/Codex_CLI-412991?style=for-the-badge&logo=openai&logoColor=white" alt="Codex CLI" height="36"></a>
|
|
33
|
+
<a href="#install-and-see-savings-in-60-seconds"><img src="https://img.shields.io/badge/OpenCode-22C55E?style=for-the-badge&logo=terminal&logoColor=white" alt="OpenCode" height="36"></a>
|
|
33
34
|
</p>
|
|
34
35
|
|
|
35
36
|
<p align="center">
|
|
@@ -76,6 +77,7 @@ Restart your editor. Done. Every question now hits the index instead of re-readi
|
|
|
76
77
|
| Cursor | `.cursor/mcp.json` | `.cursorrules` |
|
|
77
78
|
| Gemini CLI | `.gemini/settings.json` | `GEMINI.md` |
|
|
78
79
|
| OpenAI Codex | `.codex/config.toml` | |
|
|
80
|
+
| OpenCode | `opencode.json` | |
|
|
79
81
|
|
|
80
82
|
Multiple editors in the same project? All get configured in one command.
|
|
81
83
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "code-context-engine"
|
|
3
|
-
version = "0.4.
|
|
4
|
-
description = "Index your codebase. AI searches instead of re-reading files. 94% token savings, benchmarked on FastAPI. Works with Claude Code, Cursor, VS Code, Gemini CLI, and
|
|
3
|
+
version = "0.4.11"
|
|
4
|
+
description = "Index your codebase. AI searches instead of re-reading files. 94% token savings, benchmarked on FastAPI. Works with Claude Code, Cursor, VS Code, Gemini CLI, Codex, and OpenCode."
|
|
5
5
|
readme = {file = "README.md", content-type = "text/markdown"}
|
|
6
6
|
license = "MIT"
|
|
7
7
|
authors = [
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11/src/code_context_engine.egg-info}/PKG-INFO
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-context-engine
|
|
3
|
-
Version: 0.4.
|
|
4
|
-
Summary: Index your codebase. AI searches instead of re-reading files. 94% token savings, benchmarked on FastAPI. Works with Claude Code, Cursor, VS Code, Gemini CLI, and
|
|
3
|
+
Version: 0.4.11
|
|
4
|
+
Summary: Index your codebase. AI searches instead of re-reading files. 94% token savings, benchmarked on FastAPI. Works with Claude Code, Cursor, VS Code, Gemini CLI, Codex, and OpenCode.
|
|
5
5
|
Author-email: Fazle Elahee <felahee@gmail.com>, Raj <rajkumar.sakti@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/elara-labs/code-context-engine
|
|
@@ -78,7 +78,8 @@ Dynamic: license-file
|
|
|
78
78
|
<a href="#install-and-see-savings-in-60-seconds"><img src="https://img.shields.io/badge/VS_Code-007ACC?style=for-the-badge&logo=visual-studio-code&logoColor=white" alt="VS Code" height="36"></a>
|
|
79
79
|
<a href="#install-and-see-savings-in-60-seconds"><img src="https://img.shields.io/badge/Cursor-000000?style=for-the-badge&logo=cursor&logoColor=white" alt="Cursor" height="36"></a>
|
|
80
80
|
<a href="#install-and-see-savings-in-60-seconds"><img src="https://img.shields.io/badge/Gemini_CLI-4285F4?style=for-the-badge&logo=google&logoColor=white" alt="Gemini CLI" height="36"></a>
|
|
81
|
-
<a href="#install-and-see-savings-in-60-seconds"><img src="https://img.shields.io/badge/Codex_CLI-412991?style=for-the-badge&logo=openai&logoColor=white" alt="Codex CLI" height="36"></a
|
|
81
|
+
<a href="#install-and-see-savings-in-60-seconds"><img src="https://img.shields.io/badge/Codex_CLI-412991?style=for-the-badge&logo=openai&logoColor=white" alt="Codex CLI" height="36"></a>
|
|
82
|
+
<a href="#install-and-see-savings-in-60-seconds"><img src="https://img.shields.io/badge/OpenCode-22C55E?style=for-the-badge&logo=terminal&logoColor=white" alt="OpenCode" height="36"></a>
|
|
82
83
|
</p>
|
|
83
84
|
|
|
84
85
|
<p align="center">
|
|
@@ -125,6 +126,7 @@ Restart your editor. Done. Every question now hits the index instead of re-readi
|
|
|
125
126
|
| Cursor | `.cursor/mcp.json` | `.cursorrules` |
|
|
126
127
|
| Gemini CLI | `.gemini/settings.json` | `GEMINI.md` |
|
|
127
128
|
| OpenAI Codex | `.codex/config.toml` | |
|
|
129
|
+
| OpenCode | `opencode.json` | |
|
|
128
130
|
|
|
129
131
|
Multiple editors in the same project? All get configured in one command.
|
|
130
132
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"""Multi-editor MCP configuration.
|
|
2
2
|
|
|
3
3
|
Detects installed editors and writes MCP server config in each editor's
|
|
4
|
-
format. Supports Claude Code, VS Code/Copilot, Cursor, Gemini CLI,
|
|
5
|
-
OpenAI Codex CLI.
|
|
4
|
+
format. Supports Claude Code, VS Code/Copilot, Cursor, Gemini CLI,
|
|
5
|
+
OpenAI Codex CLI, and OpenCode.
|
|
6
6
|
"""
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
@@ -50,6 +50,13 @@ EDITORS: dict[str, dict] = {
|
|
|
50
50
|
"format": "toml",
|
|
51
51
|
"detect": [".codex"],
|
|
52
52
|
},
|
|
53
|
+
"opencode": {
|
|
54
|
+
"name": "OpenCode",
|
|
55
|
+
"config_path": "opencode.json",
|
|
56
|
+
"servers_key": "mcp",
|
|
57
|
+
"format": "opencode",
|
|
58
|
+
"detect": ["opencode.json", "opencode.jsonc"],
|
|
59
|
+
},
|
|
53
60
|
}
|
|
54
61
|
|
|
55
62
|
# ── Instruction file definitions ──────────────────────────────────────
|
|
@@ -129,6 +136,9 @@ def configure_mcp(project_dir: Path, editor_key: str) -> bool:
|
|
|
129
136
|
if editor.get("format") == "toml":
|
|
130
137
|
return _configure_toml(config_path, command, str(project_dir))
|
|
131
138
|
|
|
139
|
+
if editor.get("format") == "opencode":
|
|
140
|
+
return _configure_opencode(config_path, command, str(project_dir))
|
|
141
|
+
|
|
132
142
|
servers_key = editor["servers_key"]
|
|
133
143
|
entry = {"command": command, "args": ["serve", "--project-dir", str(project_dir)]}
|
|
134
144
|
|
|
@@ -154,6 +164,53 @@ def configure_mcp(project_dir: Path, editor_key: str) -> bool:
|
|
|
154
164
|
return True
|
|
155
165
|
|
|
156
166
|
|
|
167
|
+
def _configure_opencode(config_path: Path, command: str, project_dir: str) -> bool:
|
|
168
|
+
"""Add CCE to OpenCode's opencode.json. Returns True if changed.
|
|
169
|
+
|
|
170
|
+
OpenCode uses a different MCP entry format: type "local" with command
|
|
171
|
+
as an array (not a string + args).
|
|
172
|
+
"""
|
|
173
|
+
# OpenCode may also have opencode.jsonc; if the .jsonc exists and .json
|
|
174
|
+
# doesn't, use the .jsonc path instead.
|
|
175
|
+
jsonc_path = config_path.with_suffix(".jsonc")
|
|
176
|
+
if jsonc_path.exists() and not config_path.exists():
|
|
177
|
+
config_path = jsonc_path
|
|
178
|
+
|
|
179
|
+
entry = {
|
|
180
|
+
"type": "local",
|
|
181
|
+
"command": [command, "serve", "--project-dir", project_dir],
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if config_path.exists():
|
|
185
|
+
try:
|
|
186
|
+
content = config_path.read_text()
|
|
187
|
+
# Strip JSONC comments for parsing
|
|
188
|
+
data = json.loads(_strip_jsonc_comments(content))
|
|
189
|
+
except (json.JSONDecodeError, OSError):
|
|
190
|
+
data = {}
|
|
191
|
+
else:
|
|
192
|
+
data = {}
|
|
193
|
+
|
|
194
|
+
servers = data.setdefault("mcp", {})
|
|
195
|
+
if "context-engine" in servers:
|
|
196
|
+
existing = servers["context-engine"]
|
|
197
|
+
if existing.get("command") == entry["command"] and existing.get("type") == "local":
|
|
198
|
+
return False
|
|
199
|
+
servers["context-engine"] = entry
|
|
200
|
+
atomic_write_text(config_path, json.dumps(data, indent=2) + "\n")
|
|
201
|
+
return True
|
|
202
|
+
|
|
203
|
+
servers["context-engine"] = entry
|
|
204
|
+
atomic_write_text(config_path, json.dumps(data, indent=2) + "\n")
|
|
205
|
+
return True
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def _strip_jsonc_comments(text: str) -> str:
|
|
209
|
+
"""Strip single-line // comments from JSONC content for JSON parsing."""
|
|
210
|
+
import re
|
|
211
|
+
return re.sub(r'//.*?$', '', text, flags=re.MULTILINE)
|
|
212
|
+
|
|
213
|
+
|
|
157
214
|
def _configure_toml(config_path: Path, command: str, project_dir: str) -> bool:
|
|
158
215
|
"""Add CCE to a TOML config file (Codex). Returns True if changed."""
|
|
159
216
|
block = _codex_toml_block(command, project_dir)
|
|
@@ -174,6 +231,12 @@ def remove_mcp(project_dir: Path, editor_key: str) -> str | None:
|
|
|
174
231
|
editor = EDITORS[editor_key]
|
|
175
232
|
config_path = project_dir / editor["config_path"]
|
|
176
233
|
|
|
234
|
+
# OpenCode may use .jsonc instead of .json
|
|
235
|
+
if editor.get("format") == "opencode":
|
|
236
|
+
jsonc_path = config_path.with_suffix(".jsonc")
|
|
237
|
+
if jsonc_path.exists() and not config_path.exists():
|
|
238
|
+
config_path = jsonc_path
|
|
239
|
+
|
|
177
240
|
if not config_path.exists():
|
|
178
241
|
return None
|
|
179
242
|
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""Tests for OpenCode MCP configuration in editors.py."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
from unittest.mock import patch
|
|
6
|
+
|
|
7
|
+
from context_engine.editors import (
|
|
8
|
+
configure_mcp, detect_editors, remove_mcp,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def test_detect_opencode_json(tmp_path):
|
|
13
|
+
(tmp_path / "opencode.json").write_text("{}")
|
|
14
|
+
detected = detect_editors(tmp_path)
|
|
15
|
+
assert "opencode" in detected
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def test_detect_opencode_jsonc(tmp_path):
|
|
19
|
+
(tmp_path / "opencode.jsonc").write_text("{}")
|
|
20
|
+
detected = detect_editors(tmp_path)
|
|
21
|
+
assert "opencode" in detected
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def test_configure_opencode_creates_config(tmp_path):
|
|
25
|
+
with patch("context_engine.editors.resolve_cce_binary", return_value="/usr/bin/cce"):
|
|
26
|
+
changed = configure_mcp(tmp_path, "opencode")
|
|
27
|
+
assert changed is True
|
|
28
|
+
|
|
29
|
+
data = json.loads((tmp_path / "opencode.json").read_text())
|
|
30
|
+
entry = data["mcp"]["context-engine"]
|
|
31
|
+
assert entry["type"] == "local"
|
|
32
|
+
assert entry["command"] == ["/usr/bin/cce", "serve", "--project-dir", str(tmp_path)]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def test_configure_opencode_idempotent(tmp_path):
|
|
36
|
+
with patch("context_engine.editors.resolve_cce_binary", return_value="/usr/bin/cce"):
|
|
37
|
+
configure_mcp(tmp_path, "opencode")
|
|
38
|
+
changed = configure_mcp(tmp_path, "opencode")
|
|
39
|
+
assert changed is False
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_configure_opencode_preserves_existing(tmp_path):
|
|
43
|
+
existing = {"model": "anthropic/claude-sonnet-4-5", "mcp": {"other": {"type": "local"}}}
|
|
44
|
+
(tmp_path / "opencode.json").write_text(json.dumps(existing))
|
|
45
|
+
|
|
46
|
+
with patch("context_engine.editors.resolve_cce_binary", return_value="/usr/bin/cce"):
|
|
47
|
+
configure_mcp(tmp_path, "opencode")
|
|
48
|
+
|
|
49
|
+
data = json.loads((tmp_path / "opencode.json").read_text())
|
|
50
|
+
assert data["model"] == "anthropic/claude-sonnet-4-5"
|
|
51
|
+
assert "other" in data["mcp"]
|
|
52
|
+
assert "context-engine" in data["mcp"]
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def test_configure_opencode_uses_jsonc_if_exists(tmp_path):
|
|
56
|
+
(tmp_path / "opencode.jsonc").write_text('{\n // my config\n "model": "test"\n}')
|
|
57
|
+
|
|
58
|
+
with patch("context_engine.editors.resolve_cce_binary", return_value="/usr/bin/cce"):
|
|
59
|
+
changed = configure_mcp(tmp_path, "opencode")
|
|
60
|
+
assert changed is True
|
|
61
|
+
|
|
62
|
+
# Should write to .jsonc since that's what existed
|
|
63
|
+
data = json.loads((tmp_path / "opencode.jsonc").read_text())
|
|
64
|
+
assert "context-engine" in data["mcp"]
|
|
65
|
+
assert data["model"] == "test"
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def test_remove_opencode(tmp_path):
|
|
69
|
+
config = {"mcp": {"context-engine": {"type": "local", "command": ["/usr/bin/cce"]}}}
|
|
70
|
+
(tmp_path / "opencode.json").write_text(json.dumps(config))
|
|
71
|
+
|
|
72
|
+
result = remove_mcp(tmp_path, "opencode")
|
|
73
|
+
assert result is not None
|
|
74
|
+
assert "opencode" in result.lower()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/compression/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/compression/prompts.py
RENAMED
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/compression/quality.py
RENAMED
|
File without changes
|
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/dashboard/__init__.py
RENAMED
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/dashboard/_page.py
RENAMED
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/dashboard/server.py
RENAMED
|
File without changes
|
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/indexer/__init__.py
RENAMED
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/indexer/chunker.py
RENAMED
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/indexer/embedder.py
RENAMED
|
File without changes
|
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/indexer/git_hooks.py
RENAMED
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/indexer/git_indexer.py
RENAMED
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/indexer/ignorefile.py
RENAMED
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/indexer/manifest.py
RENAMED
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/indexer/pipeline.py
RENAMED
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/indexer/secrets.py
RENAMED
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/indexer/watcher.py
RENAMED
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/integration/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/memory/__init__.py
RENAMED
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/memory/compressor.py
RENAMED
|
File without changes
|
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/memory/extractive.py
RENAMED
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/memory/grammar.py
RENAMED
|
File without changes
|
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/memory/hook_server.py
RENAMED
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/memory/hooks.py
RENAMED
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/memory/migrate.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/project_commands.py
RENAMED
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/retrieval/__init__.py
RENAMED
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/retrieval/confidence.py
RENAMED
|
File without changes
|
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/retrieval/retriever.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/storage/__init__.py
RENAMED
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/storage/backend.py
RENAMED
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/storage/fts_store.py
RENAMED
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/storage/graph_store.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_context_engine-0.4.10 → code_context_engine-0.4.11}/src/context_engine/storage/vector_store.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|