cocoindex-code 0.2.41__tar.gz → 0.2.43__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 (27) hide show
  1. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/PKG-INFO +73 -26
  2. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/README.md +71 -24
  3. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/src/cocoindex_code/_daemon_paths.py +40 -0
  4. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/src/cocoindex_code/_version.py +2 -2
  5. cocoindex_code-0.2.43/src/cocoindex_code/chunking.py +54 -0
  6. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/src/cocoindex_code/cli.py +28 -8
  7. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/src/cocoindex_code/client.py +15 -9
  8. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/src/cocoindex_code/daemon.py +123 -30
  9. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/src/cocoindex_code/indexer.py +15 -7
  10. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/src/cocoindex_code/project.py +42 -5
  11. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/src/cocoindex_code/server.py +26 -5
  12. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/src/cocoindex_code/settings.py +50 -0
  13. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/src/cocoindex_code/shared.py +2 -1
  14. cocoindex_code-0.2.41/src/cocoindex_code/chunking.py +0 -29
  15. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/.gitignore +0 -0
  16. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/LICENSE +0 -0
  17. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/pyproject.toml +0 -0
  18. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/src/cocoindex_code/__init__.py +0 -0
  19. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/src/cocoindex_code/__main__.py +0 -0
  20. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/src/cocoindex_code/embedder_defaults.py +0 -0
  21. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/src/cocoindex_code/embedder_params.py +0 -0
  22. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/src/cocoindex_code/file_walk.py +0 -0
  23. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/src/cocoindex_code/grep.py +0 -0
  24. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/src/cocoindex_code/litellm_embedder.py +0 -0
  25. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/src/cocoindex_code/protocol.py +0 -0
  26. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/src/cocoindex_code/query.py +0 -0
  27. {cocoindex_code-0.2.41 → cocoindex_code-0.2.43}/src/cocoindex_code/schema.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: cocoindex-code
3
- Version: 0.2.41
3
+ Version: 0.2.43
4
4
  Summary: MCP server for indexing and querying codebases using CocoIndex
5
5
  Project-URL: Homepage, https://github.com/cocoindex-io/cocoindex-code
6
6
  Project-URL: Repository, https://github.com/cocoindex-io/cocoindex-code
@@ -47,15 +47,15 @@ Description-Content-Type: text/markdown
47
47
  </p>
48
48
 
49
49
 
50
- <h1 align="center">AST-based semantic code search that just works</h1>
50
+ <h1 align="center">AST-based semantic code search</h1>
51
51
 
52
52
  ![effect](https://github.com/user-attachments/assets/cb3a4cae-0e1f-49c4-890b-7bb93317ab60)
53
53
 
54
54
 
55
- A lightweight, effective **(AST-based)** semantic code search tool for your codebase. Built on [CocoIndex](https://github.com/cocoindex-io/cocoindex) — a Rust-based ultra performant data transformation engine. Use it from the CLI, or integrate with Claude, Codex, Cursor — any coding agent — via [Skill](#skill-recommended) or [MCP](#mcp-server).
55
+ CocoIndex Code provides AST-based semantic search for your codebase, built on the [CocoIndex](https://github.com/cocoindex-io/cocoindex) Rust data transformation engine. Use it from the CLI or connect Claude, Codex, Cursor, and other coding agents through a [Skill](#skill-recommended) or [MCP](#mcp-server).
56
56
 
57
- - Instant token saving by 70%.
58
- - **1 min setup** — install and go, zero config needed!
57
+ - 70% token savings.
58
+ - 1 min setup with default settings.
59
59
 
60
60
  <div align="center">
61
61
 
@@ -69,7 +69,7 @@ A lightweight, effective **(AST-based)** semantic code search tool for your code
69
69
  [![release](https://github.com/cocoindex-io/cocoindex/actions/workflows/release.yml/badge.svg?event=push&color=5B5BD6)](https://github.com/cocoindex-io/cocoindex/actions/workflows/release.yml)
70
70
 
71
71
 
72
- 🌟 Please help star [CocoIndex](https://github.com/cocoindex-io/cocoindex) if you like this project!
72
+ Star [CocoIndex](https://github.com/cocoindex-io/cocoindex) if you find it useful.
73
73
 
74
74
  [Deutsch](https://readme-i18n.com/cocoindex-io/cocoindex-code?lang=de) |
75
75
  [English](https://readme-i18n.com/cocoindex-io/cocoindex-code?lang=en) |
@@ -84,7 +84,9 @@ A lightweight, effective **(AST-based)** semantic code search tool for your code
84
84
  </div>
85
85
 
86
86
 
87
- ## Get Started — zero config, let's go!
87
+ <a id="get-started--zero-config-lets-go"></a>
88
+
89
+ ## Get Started
88
90
 
89
91
  ### Install
90
92
 
@@ -117,7 +119,7 @@ Install the `ccc` skill so your coding agent automatically uses semantic search
117
119
  npx skills add cocoindex-io/cocoindex-code
118
120
  ```
119
121
 
120
- That's it — no `ccc init` or `ccc index` needed. The skill teaches the agent to handle initialization, indexing, and searching on its own. It will automatically keep the index up to date as you work.
122
+ The skill teaches the agent to handle initialization, indexing, and searching, so you don't need to run `ccc init` or `ccc index` yourself. The agent keeps the index up to date as you work.
121
123
 
122
124
  The agent uses semantic search automatically when it would be helpful. You can also nudge it explicitly — just ask it to search the codebase, e.g. *"find how user sessions are managed"*, or type `/ccc` to invoke the skill directly.
123
125
 
@@ -141,7 +143,7 @@ For [Grok](https://github.com/xai-org/grok) users, install via Grok's plugin sys
141
143
  | Component | Purpose |
142
144
  |-----------|---------|
143
145
  | **Skill** (`skills/ccc/`) | Agent runs `ccc search` / `ccc index` via the CLI (same as Claude Code above) |
144
- | **Hook** (`hooks/hooks.json`) | `SessionStart` → incremental `ccc index` when `.cocoindex_code/` exists |
146
+ | **Hook** (`hooks/hooks.json`) | `SessionStart` + `PostToolUse` (Edit/Write/…) → incremental `ccc index` when `.cocoindex_code/settings.yml` exists (never in the directory holding ccc's user settings, `~` by default) |
145
147
  | **MCP** (`.mcp.json`) | `ccc mcp` stdio server — `search` tool with `refresh_index=true` by default |
146
148
 
147
149
  Grok does **not** import Claude's `enabledPlugins` or plugin cache; install separately even if you already use cocoindex in Claude Code.
@@ -162,7 +164,7 @@ Prefer the GitHub shorthand (`cocoindex-io/cocoindex-code`) for install — `gro
162
164
 
163
165
  Install and enable as above, then disable the optional components:
164
166
 
165
- 1. **Hooks** — open `/hooks`, select the `SessionStart` hook from `cocoindex-code`, press `Space` to disable.
167
+ 1. **Hooks** — open `/hooks`, select the `SessionStart` / `PostToolUse` hooks from `cocoindex-code`, press `Space` to disable.
166
168
  2. **MCP** — open `/mcps`, select `cocoindex-code`, press `Space` to disable; or persist in `~/.grok/config.toml`:
167
169
 
168
170
  ```toml
@@ -182,8 +184,32 @@ mcps = false
182
184
  mcps = false
183
185
  ```
184
186
 
187
+ #### Oh My Pi plugin
188
+
189
+ [Oh My Pi](https://github.com/can1357/oh-my-pi) reads `.omp-plugin/marketplace.json` (preferred) and falls back to `.claude-plugin/marketplace.json`.
190
+
191
+ ```bash
192
+ omp plugin marketplace add cocoindex-io/cocoindex-code
193
+ omp plugin install cocoindex-code@cocoindex-code --scope project
194
+ ```
195
+
196
+ Then restart the session (`/reload-plugins` does not reload extensions). Requires `ccc` on `PATH` (`uv tool install --upgrade 'cocoindex-code[full]'`).
197
+
198
+ | Component | Purpose |
199
+ |-----------|---------|
200
+ | **Skill** (`skills/ccc/`) | Agent runs `ccc search` / `ccc index` via the CLI |
201
+ | **Hook** (`extensions/ccc-index.ts` via `package.json#omp.extensions`) | `session_start` + post-edit `tool_result` → incremental `ccc index` when `.cocoindex_code/settings.yml` exists (never in the directory holding ccc's user settings, `~` by default) |
202
+ | **MCP** (`.mcp.json`) | `ccc mcp` stdio server |
203
+
204
+ OMP does **not** execute Claude `hooks/hooks.json` command hooks. The TypeScript extension is the OMP equivalent of the Claude/Grok SessionStart + PostToolUse pair.
205
+
206
+ Skill-only (no MCP, no auto-index): install the skill via `npx skills add cocoindex-io/cocoindex-code`, or run `ccc search` / `ccc index` from the shell.
207
+
185
208
  ### MCP Server
186
209
 
210
+ <!-- Ownership marker for the official MCP registry. It must match "name" in server.json. Keep the next line. -->
211
+ <!-- mcp-name: io.github.cocoindex-io/cocoindex-code -->
212
+
187
213
  Alternatively, use `ccc mcp` to run as an MCP server:
188
214
 
189
215
  <details>
@@ -246,7 +272,24 @@ Add a local MCP server in `~/.config/kilo/kilo.jsonc`, `kilo.jsonc`, or `.kilo/k
246
272
  ```
247
273
  </details>
248
274
 
249
- Once configured, the agent automatically decides when semantic code search is helpful — finding code by description, exploring unfamiliar codebases, fuzzy/conceptual matches, or locating implementations without knowing exact names.
275
+ <details>
276
+ <summary>Oh My Pi</summary>
277
+
278
+ Prefer the marketplace install above. Manual project MCP (`.omp/mcp.json`):
279
+
280
+ ```json
281
+ {
282
+ "mcpServers": {
283
+ "cocoindex-code": {
284
+ "command": "ccc",
285
+ "args": ["mcp"]
286
+ }
287
+ }
288
+ }
289
+ ```
290
+ </details>
291
+
292
+ Once configured, the agent can use semantic search to find code by description, explore unfamiliar codebases, and locate implementations without exact names.
250
293
 
251
294
  > **Note:** The `cocoindex-code` command (without subcommand) still works as an MCP server for backward compatibility. It auto-creates settings from environment variables on first run.
252
295
 
@@ -285,6 +328,8 @@ The background daemon starts automatically on first use.
285
328
 
286
329
  > **Tip:** You can skip `ccc init` and go straight to `ccc index` — it auto-initializes new projects with default settings. If global settings are missing too (first use on the machine), it walks you through the same model setup as `ccc init` when run interactively; non-interactive runs (scripts, hooks) still require a one-time `ccc init` first.
287
330
 
331
+ > **Note:** `ccc index` never auto-initializes the directory that holds ccc's user settings directory: your home directory by default (`~/.cocoindex_code` holds the global settings and daemon files), or the parent of `$COCOINDEX_CODE_DIR` when that directory is named `.cocoindex_code`. A project there would cover every repo below it. The editor hooks skip that directory even if it is already a project. If an older ccc made your home directory a project (`~/.cocoindex_code/settings.yml` exists), run `ccc reset --all` in your home directory: it removes that project's settings and indexes and keeps your global settings. To index your whole home directory on purpose, run `ccc init` there.
332
+
288
333
  ### CLI Reference
289
334
 
290
335
  | Command | Description |
@@ -437,8 +482,8 @@ ccc() {
437
482
  }
438
483
  ```
439
484
 
440
- Now `cd` into any project under your workspace and run `ccc init`, `ccc index`,
441
- `ccc search ...`, `ccc status`, etc. — it just works.
485
+ Now `cd` into a project under your workspace and run `ccc init`, `ccc index`,
486
+ `ccc search ...`, or `ccc status`.
442
487
 
443
488
  ### Connect your coding agent
444
489
 
@@ -527,11 +572,11 @@ docker build -t cocoindex-code:local -f docker/Dockerfile .
527
572
  ```
528
573
 
529
574
  ## Features
530
- - **Semantic Code Search**: Find relevant code using natural language queries when grep doesn't work well, and save tokens immediately.
531
- - **Ultra Performant**: ⚡ Built on top of ultra performant [Rust indexing engine](https://github.com/cocoindex-io/cocoindex). Only re-indexes changed files for fast updates.
575
+ - **Semantic Code Search**: Find relevant code using natural language queries when grep doesn't work well.
576
+ - **Incremental indexing**: The [Rust indexing engine](https://github.com/cocoindex-io/cocoindex) re-indexes only changed files.
532
577
  - **Multi-Language Support**: Python, JavaScript/TypeScript, Rust, Go, Java, C/C++, C#, SQL, Shell, and more.
533
- - **Embedded**: Portable and just works, no database setup required!
534
- - **Flexible Embeddings**: Local SentenceTransformers via the `[full]` extra (free, no API key!) or 100+ cloud providers via LiteLLM.
578
+ - **Embedded storage**: No database setup required.
579
+ - **Embedding providers**: Local SentenceTransformers via the `[full]` extra, with no API key, or 100+ cloud providers via LiteLLM.
535
580
 
536
581
  ## Configuration
537
582
 
@@ -647,8 +692,9 @@ After editing `include_patterns`, `exclude_patterns`, `max_file_size`, or `langu
647
692
  - Run `ccc doctor` to preview which files match.
648
693
  - Run `ccc index` or `ccc search --refresh ...` to update the existing index.
649
694
  - You do not need to delete the index or restart the daemon for these file-matching changes.
695
+ - After any `language_overrides` change, the next run re-chunks all files, including files whose content did not change; the run reports them as reprocessed. Chunks whose text did not change keep their cached embeddings.
650
696
 
651
- If you add or change custom `chunkers`, restart the daemon first so the chunker registry is reloaded, then run `ccc index`.
697
+ If you add or change custom `chunkers`, or edit a chunker module, restart the daemon (`ccc daemon restart`), then run `ccc index`. The daemon imports chunkers once at startup, so until it restarts it keeps running the old chunker code. The first run after the restart re-chunks all files, not only the ones the changed entry applies to; chunks whose text did not change keep their cached embeddings. A chunker counts as changed when its `module:` value changes or when the file of the module it names changes. Edits to other modules that file imports are not detected: after such an edit, also change the chunker's own module file (for example, bump a version comment in it).
652
698
 
653
699
  Use `chunkers` when you want to control how a file type is split into chunks before indexing.
654
700
 
@@ -850,6 +896,7 @@ embedding:
850
896
  | css | | `.css`, `.scss` |
851
897
  | dart | | `.dart` |
852
898
  | dtd | | `.dtd` |
899
+ | elixir | | `.ex`, `.exs` |
853
900
  | fortran | f, f90, f95, f03 | `.f`, `.f90`, `.f95`, `.f03` |
854
901
  | go | golang | `.go` |
855
902
  | html | | `.html`, `.htm` |
@@ -899,7 +946,7 @@ Both source and target must be absolute paths. If no mapping matches, the defaul
899
946
 
900
947
  ## Troubleshooting
901
948
 
902
- Run `ccc doctor` to diagnose common issues. It checks your settings, daemon health, embedding model, file matching, and index status — all in one command.
949
+ Run `ccc doctor` to check your settings, daemon health, embedding model, file matching, and index status.
903
950
 
904
951
  ### `sqlite3.Connection object has no attribute enable_load_extension`
905
952
 
@@ -911,7 +958,7 @@ Some Python installations (e.g. the one pre-installed on macOS) ship with a SQLi
911
958
  brew install python3
912
959
  ```
913
960
 
914
- Then re-install cocoindex-code (see [Get Started](#get-started--zero-config-lets-go) for install options):
961
+ Then re-install cocoindex-code (see [Get Started](#get-started) for install options):
915
962
 
916
963
  Using pipx:
917
964
  ```bash
@@ -926,7 +973,7 @@ uv tool install --upgrade cocoindex-code
926
973
 
927
974
  ### `MDB_MAP_FULL: Environment mapsize limit reached`
928
975
 
929
- The index is stored in an LMDB database whose maximum size is fixed when the daemon starts. The default ceiling is **4 GiB**, which is plenty for most projects but can be exhausted by very large codebases (tens of thousands of files), especially with high-dimensional embedding models like `nomic-ai/CodeRankEmbed`.
976
+ The index is stored in an LMDB database whose maximum size is fixed when the daemon starts. The default ceiling is **4 GiB**, which codebases with tens of thousands of files can exhaust, especially with high-dimensional embedding models like `nomic-ai/CodeRankEmbed`.
930
977
 
931
978
  Raise the ceiling with the `COCOINDEX_LMDB_MAP_SIZE` environment variable (value in **bytes**). LMDB only grows the file as data is written, so a high limit doesn't pre-allocate disk — it's safe to set it generously:
932
979
 
@@ -976,15 +1023,15 @@ export COCOINDEX_DISABLE_USAGE_TRACKING=1
976
1023
  ```
977
1024
 
978
1025
  ## Large codebase / Enterprise
979
- [CocoIndex](https://github.com/cocoindex-io/cocoindex) is an ultra efficient indexing engine that also works on large codebases at scale for enterprises. In enterprise scenarios it is a lot more efficient to share indexes with teammates when there are large or many repos. We also have advanced features like branch dedupe etc designed for enterprise users.
1026
+ Teams indexing large or multiple repositories can share [CocoIndex](https://github.com/cocoindex-io/cocoindex) indexes across developers. Enterprise features include deduplication across branches.
980
1027
 
981
- > Indexing a very large codebase and hitting `MDB_MAP_FULL`? Raise the LMDB map size — see [`MDB_MAP_FULL: Environment mapsize limit reached`](#mdb_map_full-environment-mapsize-limit-reached) under Troubleshooting.
1028
+ > If indexing fails with `MDB_MAP_FULL`, raise the LMDB map size. See [`MDB_MAP_FULL: Environment mapsize limit reached`](#mdb_map_full-environment-mapsize-limit-reached) under Troubleshooting.
982
1029
 
983
- If you need help with remote setup, please email our maintainer linghua@cocoindex.io, happy to help!
1030
+ For help with remote setup, email linghua@cocoindex.io.
984
1031
 
985
1032
  ## Contributing
986
1033
 
987
- We welcome contributions! This project uses [uv](https://docs.astral.sh/uv/getting-started/installation/) for development, and every PR is gated on the same lint, format, type-check, and test suite in CI. **Please run these checks locally before opening a PR** — failing pre-commit checks are the most common cause of red CI on incoming PRs.
1034
+ We welcome contributions. This project uses [uv](https://docs.astral.sh/uv/getting-started/installation/) for development. CI checks lint, formatting, types, and tests for every PR. Run the same checks locally before opening a PR; failed pre-commit checks are the most common cause of red CI on incoming PRs.
988
1035
 
989
1036
  ### 1. Install the dev dependencies
990
1037
 
@@ -3,15 +3,15 @@
3
3
  </p>
4
4
 
5
5
 
6
- <h1 align="center">AST-based semantic code search that just works</h1>
6
+ <h1 align="center">AST-based semantic code search</h1>
7
7
 
8
8
  ![effect](https://github.com/user-attachments/assets/cb3a4cae-0e1f-49c4-890b-7bb93317ab60)
9
9
 
10
10
 
11
- A lightweight, effective **(AST-based)** semantic code search tool for your codebase. Built on [CocoIndex](https://github.com/cocoindex-io/cocoindex) — a Rust-based ultra performant data transformation engine. Use it from the CLI, or integrate with Claude, Codex, Cursor — any coding agent — via [Skill](#skill-recommended) or [MCP](#mcp-server).
11
+ CocoIndex Code provides AST-based semantic search for your codebase, built on the [CocoIndex](https://github.com/cocoindex-io/cocoindex) Rust data transformation engine. Use it from the CLI or connect Claude, Codex, Cursor, and other coding agents through a [Skill](#skill-recommended) or [MCP](#mcp-server).
12
12
 
13
- - Instant token saving by 70%.
14
- - **1 min setup** — install and go, zero config needed!
13
+ - 70% token savings.
14
+ - 1 min setup with default settings.
15
15
 
16
16
  <div align="center">
17
17
 
@@ -25,7 +25,7 @@ A lightweight, effective **(AST-based)** semantic code search tool for your code
25
25
  [![release](https://github.com/cocoindex-io/cocoindex/actions/workflows/release.yml/badge.svg?event=push&color=5B5BD6)](https://github.com/cocoindex-io/cocoindex/actions/workflows/release.yml)
26
26
 
27
27
 
28
- 🌟 Please help star [CocoIndex](https://github.com/cocoindex-io/cocoindex) if you like this project!
28
+ Star [CocoIndex](https://github.com/cocoindex-io/cocoindex) if you find it useful.
29
29
 
30
30
  [Deutsch](https://readme-i18n.com/cocoindex-io/cocoindex-code?lang=de) |
31
31
  [English](https://readme-i18n.com/cocoindex-io/cocoindex-code?lang=en) |
@@ -40,7 +40,9 @@ A lightweight, effective **(AST-based)** semantic code search tool for your code
40
40
  </div>
41
41
 
42
42
 
43
- ## Get Started — zero config, let's go!
43
+ <a id="get-started--zero-config-lets-go"></a>
44
+
45
+ ## Get Started
44
46
 
45
47
  ### Install
46
48
 
@@ -73,7 +75,7 @@ Install the `ccc` skill so your coding agent automatically uses semantic search
73
75
  npx skills add cocoindex-io/cocoindex-code
74
76
  ```
75
77
 
76
- That's it — no `ccc init` or `ccc index` needed. The skill teaches the agent to handle initialization, indexing, and searching on its own. It will automatically keep the index up to date as you work.
78
+ The skill teaches the agent to handle initialization, indexing, and searching, so you don't need to run `ccc init` or `ccc index` yourself. The agent keeps the index up to date as you work.
77
79
 
78
80
  The agent uses semantic search automatically when it would be helpful. You can also nudge it explicitly — just ask it to search the codebase, e.g. *"find how user sessions are managed"*, or type `/ccc` to invoke the skill directly.
79
81
 
@@ -97,7 +99,7 @@ For [Grok](https://github.com/xai-org/grok) users, install via Grok's plugin sys
97
99
  | Component | Purpose |
98
100
  |-----------|---------|
99
101
  | **Skill** (`skills/ccc/`) | Agent runs `ccc search` / `ccc index` via the CLI (same as Claude Code above) |
100
- | **Hook** (`hooks/hooks.json`) | `SessionStart` → incremental `ccc index` when `.cocoindex_code/` exists |
102
+ | **Hook** (`hooks/hooks.json`) | `SessionStart` + `PostToolUse` (Edit/Write/…) → incremental `ccc index` when `.cocoindex_code/settings.yml` exists (never in the directory holding ccc's user settings, `~` by default) |
101
103
  | **MCP** (`.mcp.json`) | `ccc mcp` stdio server — `search` tool with `refresh_index=true` by default |
102
104
 
103
105
  Grok does **not** import Claude's `enabledPlugins` or plugin cache; install separately even if you already use cocoindex in Claude Code.
@@ -118,7 +120,7 @@ Prefer the GitHub shorthand (`cocoindex-io/cocoindex-code`) for install — `gro
118
120
 
119
121
  Install and enable as above, then disable the optional components:
120
122
 
121
- 1. **Hooks** — open `/hooks`, select the `SessionStart` hook from `cocoindex-code`, press `Space` to disable.
123
+ 1. **Hooks** — open `/hooks`, select the `SessionStart` / `PostToolUse` hooks from `cocoindex-code`, press `Space` to disable.
122
124
  2. **MCP** — open `/mcps`, select `cocoindex-code`, press `Space` to disable; or persist in `~/.grok/config.toml`:
123
125
 
124
126
  ```toml
@@ -138,8 +140,32 @@ mcps = false
138
140
  mcps = false
139
141
  ```
140
142
 
143
+ #### Oh My Pi plugin
144
+
145
+ [Oh My Pi](https://github.com/can1357/oh-my-pi) reads `.omp-plugin/marketplace.json` (preferred) and falls back to `.claude-plugin/marketplace.json`.
146
+
147
+ ```bash
148
+ omp plugin marketplace add cocoindex-io/cocoindex-code
149
+ omp plugin install cocoindex-code@cocoindex-code --scope project
150
+ ```
151
+
152
+ Then restart the session (`/reload-plugins` does not reload extensions). Requires `ccc` on `PATH` (`uv tool install --upgrade 'cocoindex-code[full]'`).
153
+
154
+ | Component | Purpose |
155
+ |-----------|---------|
156
+ | **Skill** (`skills/ccc/`) | Agent runs `ccc search` / `ccc index` via the CLI |
157
+ | **Hook** (`extensions/ccc-index.ts` via `package.json#omp.extensions`) | `session_start` + post-edit `tool_result` → incremental `ccc index` when `.cocoindex_code/settings.yml` exists (never in the directory holding ccc's user settings, `~` by default) |
158
+ | **MCP** (`.mcp.json`) | `ccc mcp` stdio server |
159
+
160
+ OMP does **not** execute Claude `hooks/hooks.json` command hooks. The TypeScript extension is the OMP equivalent of the Claude/Grok SessionStart + PostToolUse pair.
161
+
162
+ Skill-only (no MCP, no auto-index): install the skill via `npx skills add cocoindex-io/cocoindex-code`, or run `ccc search` / `ccc index` from the shell.
163
+
141
164
  ### MCP Server
142
165
 
166
+ <!-- Ownership marker for the official MCP registry. It must match "name" in server.json. Keep the next line. -->
167
+ <!-- mcp-name: io.github.cocoindex-io/cocoindex-code -->
168
+
143
169
  Alternatively, use `ccc mcp` to run as an MCP server:
144
170
 
145
171
  <details>
@@ -202,7 +228,24 @@ Add a local MCP server in `~/.config/kilo/kilo.jsonc`, `kilo.jsonc`, or `.kilo/k
202
228
  ```
203
229
  </details>
204
230
 
205
- Once configured, the agent automatically decides when semantic code search is helpful — finding code by description, exploring unfamiliar codebases, fuzzy/conceptual matches, or locating implementations without knowing exact names.
231
+ <details>
232
+ <summary>Oh My Pi</summary>
233
+
234
+ Prefer the marketplace install above. Manual project MCP (`.omp/mcp.json`):
235
+
236
+ ```json
237
+ {
238
+ "mcpServers": {
239
+ "cocoindex-code": {
240
+ "command": "ccc",
241
+ "args": ["mcp"]
242
+ }
243
+ }
244
+ }
245
+ ```
246
+ </details>
247
+
248
+ Once configured, the agent can use semantic search to find code by description, explore unfamiliar codebases, and locate implementations without exact names.
206
249
 
207
250
  > **Note:** The `cocoindex-code` command (without subcommand) still works as an MCP server for backward compatibility. It auto-creates settings from environment variables on first run.
208
251
 
@@ -241,6 +284,8 @@ The background daemon starts automatically on first use.
241
284
 
242
285
  > **Tip:** You can skip `ccc init` and go straight to `ccc index` — it auto-initializes new projects with default settings. If global settings are missing too (first use on the machine), it walks you through the same model setup as `ccc init` when run interactively; non-interactive runs (scripts, hooks) still require a one-time `ccc init` first.
243
286
 
287
+ > **Note:** `ccc index` never auto-initializes the directory that holds ccc's user settings directory: your home directory by default (`~/.cocoindex_code` holds the global settings and daemon files), or the parent of `$COCOINDEX_CODE_DIR` when that directory is named `.cocoindex_code`. A project there would cover every repo below it. The editor hooks skip that directory even if it is already a project. If an older ccc made your home directory a project (`~/.cocoindex_code/settings.yml` exists), run `ccc reset --all` in your home directory: it removes that project's settings and indexes and keeps your global settings. To index your whole home directory on purpose, run `ccc init` there.
288
+
244
289
  ### CLI Reference
245
290
 
246
291
  | Command | Description |
@@ -393,8 +438,8 @@ ccc() {
393
438
  }
394
439
  ```
395
440
 
396
- Now `cd` into any project under your workspace and run `ccc init`, `ccc index`,
397
- `ccc search ...`, `ccc status`, etc. — it just works.
441
+ Now `cd` into a project under your workspace and run `ccc init`, `ccc index`,
442
+ `ccc search ...`, or `ccc status`.
398
443
 
399
444
  ### Connect your coding agent
400
445
 
@@ -483,11 +528,11 @@ docker build -t cocoindex-code:local -f docker/Dockerfile .
483
528
  ```
484
529
 
485
530
  ## Features
486
- - **Semantic Code Search**: Find relevant code using natural language queries when grep doesn't work well, and save tokens immediately.
487
- - **Ultra Performant**: ⚡ Built on top of ultra performant [Rust indexing engine](https://github.com/cocoindex-io/cocoindex). Only re-indexes changed files for fast updates.
531
+ - **Semantic Code Search**: Find relevant code using natural language queries when grep doesn't work well.
532
+ - **Incremental indexing**: The [Rust indexing engine](https://github.com/cocoindex-io/cocoindex) re-indexes only changed files.
488
533
  - **Multi-Language Support**: Python, JavaScript/TypeScript, Rust, Go, Java, C/C++, C#, SQL, Shell, and more.
489
- - **Embedded**: Portable and just works, no database setup required!
490
- - **Flexible Embeddings**: Local SentenceTransformers via the `[full]` extra (free, no API key!) or 100+ cloud providers via LiteLLM.
534
+ - **Embedded storage**: No database setup required.
535
+ - **Embedding providers**: Local SentenceTransformers via the `[full]` extra, with no API key, or 100+ cloud providers via LiteLLM.
491
536
 
492
537
  ## Configuration
493
538
 
@@ -603,8 +648,9 @@ After editing `include_patterns`, `exclude_patterns`, `max_file_size`, or `langu
603
648
  - Run `ccc doctor` to preview which files match.
604
649
  - Run `ccc index` or `ccc search --refresh ...` to update the existing index.
605
650
  - You do not need to delete the index or restart the daemon for these file-matching changes.
651
+ - After any `language_overrides` change, the next run re-chunks all files, including files whose content did not change; the run reports them as reprocessed. Chunks whose text did not change keep their cached embeddings.
606
652
 
607
- If you add or change custom `chunkers`, restart the daemon first so the chunker registry is reloaded, then run `ccc index`.
653
+ If you add or change custom `chunkers`, or edit a chunker module, restart the daemon (`ccc daemon restart`), then run `ccc index`. The daemon imports chunkers once at startup, so until it restarts it keeps running the old chunker code. The first run after the restart re-chunks all files, not only the ones the changed entry applies to; chunks whose text did not change keep their cached embeddings. A chunker counts as changed when its `module:` value changes or when the file of the module it names changes. Edits to other modules that file imports are not detected: after such an edit, also change the chunker's own module file (for example, bump a version comment in it).
608
654
 
609
655
  Use `chunkers` when you want to control how a file type is split into chunks before indexing.
610
656
 
@@ -806,6 +852,7 @@ embedding:
806
852
  | css | | `.css`, `.scss` |
807
853
  | dart | | `.dart` |
808
854
  | dtd | | `.dtd` |
855
+ | elixir | | `.ex`, `.exs` |
809
856
  | fortran | f, f90, f95, f03 | `.f`, `.f90`, `.f95`, `.f03` |
810
857
  | go | golang | `.go` |
811
858
  | html | | `.html`, `.htm` |
@@ -855,7 +902,7 @@ Both source and target must be absolute paths. If no mapping matches, the defaul
855
902
 
856
903
  ## Troubleshooting
857
904
 
858
- Run `ccc doctor` to diagnose common issues. It checks your settings, daemon health, embedding model, file matching, and index status — all in one command.
905
+ Run `ccc doctor` to check your settings, daemon health, embedding model, file matching, and index status.
859
906
 
860
907
  ### `sqlite3.Connection object has no attribute enable_load_extension`
861
908
 
@@ -867,7 +914,7 @@ Some Python installations (e.g. the one pre-installed on macOS) ship with a SQLi
867
914
  brew install python3
868
915
  ```
869
916
 
870
- Then re-install cocoindex-code (see [Get Started](#get-started--zero-config-lets-go) for install options):
917
+ Then re-install cocoindex-code (see [Get Started](#get-started) for install options):
871
918
 
872
919
  Using pipx:
873
920
  ```bash
@@ -882,7 +929,7 @@ uv tool install --upgrade cocoindex-code
882
929
 
883
930
  ### `MDB_MAP_FULL: Environment mapsize limit reached`
884
931
 
885
- The index is stored in an LMDB database whose maximum size is fixed when the daemon starts. The default ceiling is **4 GiB**, which is plenty for most projects but can be exhausted by very large codebases (tens of thousands of files), especially with high-dimensional embedding models like `nomic-ai/CodeRankEmbed`.
932
+ The index is stored in an LMDB database whose maximum size is fixed when the daemon starts. The default ceiling is **4 GiB**, which codebases with tens of thousands of files can exhaust, especially with high-dimensional embedding models like `nomic-ai/CodeRankEmbed`.
886
933
 
887
934
  Raise the ceiling with the `COCOINDEX_LMDB_MAP_SIZE` environment variable (value in **bytes**). LMDB only grows the file as data is written, so a high limit doesn't pre-allocate disk — it's safe to set it generously:
888
935
 
@@ -932,15 +979,15 @@ export COCOINDEX_DISABLE_USAGE_TRACKING=1
932
979
  ```
933
980
 
934
981
  ## Large codebase / Enterprise
935
- [CocoIndex](https://github.com/cocoindex-io/cocoindex) is an ultra efficient indexing engine that also works on large codebases at scale for enterprises. In enterprise scenarios it is a lot more efficient to share indexes with teammates when there are large or many repos. We also have advanced features like branch dedupe etc designed for enterprise users.
982
+ Teams indexing large or multiple repositories can share [CocoIndex](https://github.com/cocoindex-io/cocoindex) indexes across developers. Enterprise features include deduplication across branches.
936
983
 
937
- > Indexing a very large codebase and hitting `MDB_MAP_FULL`? Raise the LMDB map size — see [`MDB_MAP_FULL: Environment mapsize limit reached`](#mdb_map_full-environment-mapsize-limit-reached) under Troubleshooting.
984
+ > If indexing fails with `MDB_MAP_FULL`, raise the LMDB map size. See [`MDB_MAP_FULL: Environment mapsize limit reached`](#mdb_map_full-environment-mapsize-limit-reached) under Troubleshooting.
938
985
 
939
- If you need help with remote setup, please email our maintainer linghua@cocoindex.io, happy to help!
986
+ For help with remote setup, email linghua@cocoindex.io.
940
987
 
941
988
  ## Contributing
942
989
 
943
- We welcome contributions! This project uses [uv](https://docs.astral.sh/uv/getting-started/installation/) for development, and every PR is gated on the same lint, format, type-check, and test suite in CI. **Please run these checks locally before opening a PR** — failing pre-commit checks are the most common cause of red CI on incoming PRs.
990
+ We welcome contributions. This project uses [uv](https://docs.astral.sh/uv/getting-started/installation/) for development. CI checks lint, formatting, types, and tests for every PR. Run the same checks locally before opening a PR; failed pre-commit checks are the most common cause of red CI on incoming PRs.
944
991
 
945
992
  ### 1. Install the dev dependencies
946
993
 
@@ -14,6 +14,7 @@ import tempfile
14
14
  import time
15
15
  from dataclasses import dataclass
16
16
  from pathlib import Path
17
+ from typing import NamedTuple
17
18
 
18
19
  from .settings import user_settings_dir
19
20
 
@@ -79,6 +80,45 @@ def daemon_socket_path() -> str:
79
80
  return str(short)
80
81
 
81
82
 
83
+ class SocketIdentity(NamedTuple):
84
+ """Identifies one socket file, telling a daemon's own apart from one a
85
+ replacement daemon has since bound at the same path (issue #288).
86
+
87
+ ``ctime_ns`` is part of it because ext4/overlayfs hand a freed inode
88
+ number straight to the next file: once the original socket is closed and
89
+ unlinked, a replacement's can have the same ``(dev, ino)``.
90
+ """
91
+
92
+ dev: int
93
+ ino: int
94
+ ctime_ns: int
95
+
96
+
97
+ def socket_identity(path: str) -> SocketIdentity | None:
98
+ """Return the identity of the socket file at *path*, or None if absent. POSIX only."""
99
+ try:
100
+ st = os.stat(path)
101
+ except OSError:
102
+ return None
103
+ return SocketIdentity(st.st_dev, st.st_ino, st.st_ctime_ns)
104
+
105
+
106
+ def unlink_socket_if_owned(path: str, identity: SocketIdentity | None) -> None:
107
+ """Remove the socket file at *path* only if it is still *identity*.
108
+
109
+ Leaves alone a socket a replacement daemon has bound there since. Not
110
+ atomic — POSIX has no unlink-if-inode — so a replacement binding between
111
+ the stat and the unlink is still lost, but that window is microseconds.
112
+ Best-effort — never raises.
113
+ """
114
+ if identity is None or socket_identity(path) != identity:
115
+ return
116
+ try:
117
+ os.unlink(path)
118
+ except OSError:
119
+ pass
120
+
121
+
82
122
  def daemon_pid_path() -> Path:
83
123
  """Return the path for the daemon's PID file."""
84
124
  return daemon_runtime_dir() / "daemon.pid"
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.2.41'
22
- __version_tuple__ = version_tuple = (0, 2, 41)
21
+ __version__ = version = '0.2.43'
22
+ __version_tuple__ = version_tuple = (0, 2, 43)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -0,0 +1,54 @@
1
+ """Public API for writing custom chunkers.
2
+
3
+ Example usage::
4
+
5
+ from pathlib import Path
6
+ from cocoindex_code.chunking import Chunk, ChunkerFn, TextPosition
7
+
8
+ def my_chunker(path: Path, content: str) -> tuple[str | None, list[Chunk]]:
9
+ pos = TextPosition(byte_offset=0, char_offset=0, line=1, column=0)
10
+ return "mylang", [Chunk(text=content, start=pos, end=pos)]
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import dataclasses as _dataclasses
16
+ import pathlib as _pathlib
17
+ from collections.abc import Callable as _Callable
18
+
19
+ import cocoindex as _coco
20
+ from cocoindex.resources.chunk import Chunk, TextPosition
21
+
22
+ # Callable alias (not Protocol) — consistent with codebase style.
23
+ # language_override=None keeps the language detected by detect_code_language.
24
+ # path is not resolved (no syscall); call path.resolve() inside the chunker if needed.
25
+ ChunkerFn = _Callable[[_pathlib.Path, str], tuple[str | None, list[Chunk]]]
26
+
27
+
28
+ @_dataclasses.dataclass(frozen=True)
29
+ class LoadedChunker:
30
+ """A chunker the daemon imported from a ``settings.yml`` entry.
31
+
32
+ Its memo key is ``(spec, module_sha256)``, never ``fn`` itself: cocoindex
33
+ fingerprints a function by its module and name only, so an edit to its body
34
+ would go unnoticed, and it cannot fingerprint lambdas or closures at all.
35
+ """
36
+
37
+ fn: ChunkerFn
38
+ #: The ``"module.path:callable"`` string from ``settings.yml``.
39
+ spec: str
40
+ #: sha256 of the module file named in ``spec``, as it was when imported. Helper
41
+ #: modules that file imports are not covered.
42
+ module_sha256: str
43
+
44
+ def __coco_memo_key__(self) -> tuple[str, str]:
45
+ return (self.spec, self.module_sha256)
46
+
47
+
48
+ # Keyed by file suffix (e.g. ".toml"). Adding, removing or changing an entry
49
+ # re-processes all files.
50
+ CHUNKER_REGISTRY = _coco.ContextKey[dict[str, LoadedChunker]](
51
+ "chunker_registry", detect_change=True
52
+ )
53
+
54
+ __all__ = ["Chunk", "ChunkerFn", "CHUNKER_REGISTRY", "LoadedChunker", "TextPosition"]