indexkit 0.6.1__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.
@@ -0,0 +1,37 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
+ "name": "indexkit",
4
+ "displayName": "Local RAG",
5
+ "version": "0.6.1",
6
+ "description": "Local-first semantic and opt-in hybrid search: a bin/indexkit CLI that embeds through a configurable Ollama endpoint (default localhost), indexes with turbovec, and can fuse FTS5/BM25 candidates. Notes-first, corpus-agnostic via pluggable loaders.",
7
+ "author": {
8
+ "name": "Mark Beacom"
9
+ },
10
+ "homepage": "https://github.com/mbeacom/context-kit",
11
+ "repository": "https://github.com/mbeacom/context-kit",
12
+ "license": "MIT",
13
+ "keywords": [
14
+ "rag",
15
+ "vector-search",
16
+ "turbovec",
17
+ "ollama",
18
+ "embeddings",
19
+ "semantic",
20
+ "bm25",
21
+ "hybrid"
22
+ ],
23
+ "userConfig": {
24
+ "embed_model": {
25
+ "type": "string",
26
+ "title": "Embedding model",
27
+ "description": "ollama model used to embed chunks and queries",
28
+ "default": "nomic-embed-text"
29
+ },
30
+ "ollama_host": {
31
+ "type": "string",
32
+ "title": "Ollama host",
33
+ "description": "Base URL of the ollama server",
34
+ "default": "http://localhost:11434"
35
+ }
36
+ }
37
+ }
@@ -0,0 +1,233 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ # Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ # poetry.lock
109
+ # poetry.toml
110
+
111
+ # pdm
112
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
114
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
115
+ # pdm.lock
116
+ # pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # pixi
121
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
122
+ # pixi.lock
123
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
124
+ # in the .venv directory. It is recommended not to include this directory in version control.
125
+ .pixi
126
+
127
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
128
+ __pypackages__/
129
+
130
+ # Celery stuff
131
+ celerybeat-schedule
132
+ celerybeat.pid
133
+
134
+ # Redis
135
+ *.rdb
136
+ *.aof
137
+ *.pid
138
+
139
+ # RabbitMQ
140
+ mnesia/
141
+ rabbitmq/
142
+ rabbitmq-data/
143
+
144
+ # ActiveMQ
145
+ activemq-data/
146
+
147
+ # SageMath parsed files
148
+ *.sage.py
149
+
150
+ # Environments
151
+ .env
152
+ .envrc
153
+ .venv
154
+ env/
155
+ venv/
156
+ ENV/
157
+ env.bak/
158
+ venv.bak/
159
+
160
+ # Spyder project settings
161
+ .spyderproject
162
+ .spyproject
163
+
164
+ # Rope project settings
165
+ .ropeproject
166
+
167
+ # mkdocs documentation
168
+ /site
169
+
170
+ # mypy
171
+ .mypy_cache/
172
+ .dmypy.json
173
+ dmypy.json
174
+
175
+ # Pyre type checker
176
+ .pyre/
177
+
178
+ # pytype static type analyzer
179
+ .pytype/
180
+
181
+ # Cython debug symbols
182
+ cython_debug/
183
+
184
+ # PyCharm
185
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
186
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
187
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
188
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
189
+ # .idea/
190
+
191
+ # Abstra
192
+ # Abstra is an AI-powered process automation framework.
193
+ # Ignore directories containing user credentials, local state, and settings.
194
+ # Learn more at https://abstra.io/docs
195
+ .abstra/
196
+
197
+ # Visual Studio Code
198
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
199
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
200
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
201
+ # you could uncomment the following to ignore the entire vscode folder
202
+ # .vscode/
203
+ # Temporary file for partial code execution
204
+ tempCodeRunnerFile.py
205
+
206
+ # Ruff stuff:
207
+ .ruff_cache/
208
+
209
+ # PyPI configuration file
210
+ .pypirc
211
+
212
+ # Marimo
213
+ marimo/_static/
214
+ marimo/_lsp/
215
+ __marimo__/
216
+
217
+ # Streamlit
218
+ .streamlit/secrets.toml
219
+
220
+ # Claude Code plugin cache / local validation
221
+ .claude/
222
+ *.tq
223
+ *.tvim
224
+
225
+ # rtk (Rust Token Killer) local config — machine-specific, not published
226
+ .rtk/
227
+
228
+ # Internal dev process artifacts (brainstorm specs / implementation plans) — kept local, not published
229
+ docs/superpowers/
230
+
231
+ # MemPalace per-project files (issue #185)
232
+ mempalace.yaml
233
+ entities.json
@@ -0,0 +1,157 @@
1
+ # Changelog
2
+
3
+ ## 0.6.1 — 2026-08-08
4
+
5
+ - Correct host guidance and stale command names in the skill and README.
6
+ GitHub Copilot CLI loads `hooks/hooks.json`, so it auto-bootstraps like
7
+ Claude Code; only APM needs a manual step. The CLI is `indexkit`, not `rag`.
8
+ - Mark the PyPI install as forthcoming and document the working source install,
9
+ since the package name is not claimed yet.
10
+ - Restore pre-rename CHANGELOG entries to their original wording. Rewriting
11
+ them made an old release's notes describe variables that release never had.
12
+
13
+ ## 0.6.0 — 2026-08-08
14
+
15
+ - **Installable and usable without a plugin host** (ADR-0006). `pip install
16
+ indexkit` now works standalone: the default index location is
17
+ `${XDG_DATA_HOME:-~/.local/share}/indexkit` instead of
18
+ `~/.claude/plugins/data/indexkit`, so a user with no Claude install no longer
19
+ gets a `.claude` directory created for an unrelated tool.
20
+ - An existing `~/.claude/plugins/data/indexkit` still wins while the new default
21
+ has not been created, so upgrading a plugin install does not orphan indexes.
22
+ - `bin/indexkit` degrades instead of refusing: bootstrapped venv, then an
23
+ `indexkit` on `PATH`, then any importable `indexkit` module. A guard prevents
24
+ the launcher re-executing itself when the plugin `bin/` is on `PATH`.
25
+ - Add publish metadata (readme, license, authors, classifiers, project URLs);
26
+ `twine check` passes on both sdist and wheel.
27
+ - Rewrite the README to lead with standalone install, since it is now the
28
+ package's PyPI landing page.
29
+
30
+ ## 0.5.0 — 2026-08-08
31
+
32
+ - **Renamed from `local-rag` to `indexkit`** (ADR-0007). The name encoded a
33
+ deployment property that a supported setting falsifies: pointing
34
+ `CONTEXT_KIT_OLLAMA_HOST` at a remote ollama made "local" untrue. "RAG" also
35
+ understated an engine that does lexical BM25 alongside semantic search.
36
+ - Unify all four naming surfaces on `indexkit`: the package, the console script,
37
+ the CLI `prog`, and the launcher (`bin/rag` is now `bin/indexkit`).
38
+ - Honor `CONTEXT_KIT_LOCAL_RAG_HOME` as a fallback for
39
+ `CONTEXT_KIT_INDEXKIT_HOME`, so existing environments keep resolving.
40
+ - Add package keywords (`rag`, `local-rag`, `offline`, `hybrid-retrieval`) so the
41
+ pre-rename search terms still find the project.
42
+
43
+ ## 0.4.1 — 2026-08-05
44
+
45
+ - Correct the host guidance in the skill and README. GitHub Copilot CLI loads a
46
+ plugin's `hooks/hooks.json` (verified on 1.0.79), so it auto-bootstraps the
47
+ `rag` venv exactly as Claude Code does; only APM needs a manual bootstrap.
48
+ The docs previously grouped Copilot with APM and sent Copilot users through
49
+ an unnecessary manual step.
50
+
51
+ ## 0.4.0 — 2026-08-04
52
+
53
+ - Separate venv resolution from index-data location. `CONTEXT_KIT_LOCAL_RAG_HOME`
54
+ now locates the bootstrapped venv (and its `pyproject.sha` stamp), while
55
+ `CONTEXT_KIT_DATA` continues to locate index data. Previously both were derived
56
+ from `CONTEXT_KIT_DATA`, so a caller redirecting index data to an isolated
57
+ store also relocated the venv and `bin/rag` failed with "venv missing". The new
58
+ variable is optional and falls back to the existing `CONTEXT_KIT_DATA` chain,
59
+ so default single-user behavior is unchanged.
60
+ - Add `rag --version`, so an integrating adapter can report and pin a provider
61
+ version the same way it does for other retrieval backends.
62
+ - Add `scripts/bootstrap.sh --check`, a side-effect-free readiness probe that
63
+ prints `KEY=VALUE` status lines and exits 0 when ready or 3 when a bootstrap
64
+ is required. This gives hosts that do not run the Claude `SessionStart` hook
65
+ — GitHub Copilot and APM — a deterministic way to detect an unusable runtime.
66
+ - `--check` reports a **stale** venv (one built from different `pyproject.toml`
67
+ metadata) as loudly as a missing one. Previously a stale venv ran outdated
68
+ code silently, because the launcher never consulted the stamp.
69
+ - `--check` decides venv state before considering `uv`, and reports
70
+ `venv_status` and `uv` as separate fields. `uv` is only needed to *build* the
71
+ venv, so an already-usable runtime now reports `ready` on a machine without
72
+ `uv` instead of sending the user after an irrelevant install; `uv-missing` is
73
+ returned only when the venv genuinely needs rebuilding.
74
+
75
+ ## 0.3.3 — 2026-08-03
76
+
77
+ - Shorten the discovery description(s) to free aggregate budget for the new
78
+ `deep-review` components. Triggers and scope are unchanged; the catalog
79
+ budget stays at 4096 characters rather than being raised.
80
+
81
+ ## 0.3.2 — 2026-07-27
82
+
83
+ - Shorten the discovery description(s) to free aggregate budget for the new
84
+ `corpus-review` components. Triggers and scope are unchanged; the catalog
85
+ budget is fixed, so every addition competes for the same remainder.
86
+
87
+ ## 0.3.1 — 2026-07-19
88
+
89
+ - Clarify the configurable Ollama trust boundary: storage and embedding are
90
+ local by default, while a remote `CONTEXT_KIT_OLLAMA_HOST` receives submitted
91
+ corpus chunks and queries.
92
+
93
+ ## 0.3.0 — 2026-07-19
94
+
95
+ - Add automation-safe `rag remove --name NAME --yes` for permanent deletion of
96
+ obsolete or corrupt named indexes. Removal atomically leaves the active
97
+ namespace, unlinks only flat per-index artifacts without recursive deletion,
98
+ preserves sibling indexes, and reports partial cleanup locations.
99
+ - Apply one containment-safe, backward-compatible index-name contract across
100
+ `index`, `query`, `status`, and `remove`; reject traversal while preserving
101
+ legacy names with spaces or more than 80 characters.
102
+ - Serialize operations with a per-index process lock, reject owned-artifact
103
+ symlinks before opening or writing, close partially initialized resources,
104
+ and keep removal quarantine entries out of `rag list`.
105
+
106
+ ## 0.2.0 — 2026-07-19
107
+
108
+ - Add opt-in `rag query --hybrid`, which fuses turbovec semantic and SQLite
109
+ FTS5/BM25 lexical candidates with deterministic, equal-weight reciprocal-rank
110
+ fusion (RRF constant 60 and `3 × k` candidate depth).
111
+ - Keep FTS5 synchronized for incremental indexing, changed files, and deletions;
112
+ automatically migrate/backfill existing indexes. Status now reports FTS5
113
+ capability, and hybrid requests clearly fail when it is unavailable.
114
+ - Add source offsets and semantic, lexical, and fused retrieval metadata to JSON
115
+ results while preserving semantic-only as the default.
116
+
117
+ ## 0.1.6 — 2026-07-18
118
+
119
+ - Lead host guidance with GitHub Copilot, APM, then Claude Code in the plugin
120
+ README (the manual `rag` bootstrap now comes first; the Claude auto-bootstrap
121
+ note follows).
122
+
123
+ ## 0.1.5 — 2026-07-18
124
+
125
+ - Rebrand: the marketplace was renamed `productivity-skills` → `context-kit`.
126
+ Environment variables are now `CONTEXT_KIT_*` (`CONTEXT_KIT_DATA`,
127
+ `CONTEXT_KIT_EMBED_MODEL`, `CONTEXT_KIT_OLLAMA_HOST`); the former
128
+ `PRODUCTIVITY_SKILLS_*` names still resolve as a deprecated alias, so resolution
129
+ order is `CONTEXT_KIT_*` → `PRODUCTIVITY_SKILLS_*` → Claude fallback. Updated URLs
130
+ and install commands (`… install local-rag@context-kit`).
131
+
132
+ ## 0.1.4 — 2026-07-13
133
+
134
+ - Add an `apm.yml` manifest so Agent Package Manager (`microsoft/apm`) users can
135
+ install this plugin (`apm install local-rag@context-kit`) alongside the
136
+ Claude Code and GitHub Copilot flows. As with Copilot, APM does not run the
137
+ Claude `SessionStart` bootstrap hook — bootstrap `bin/rag` manually and use the
138
+ `PRODUCTIVITY_SKILLS_*` env vars (see docs/APM.md).
139
+
140
+ ## 0.1.3 — 2026-05-29
141
+
142
+ - Add GitHub Copilot/manual setup docs and portable `PRODUCTIVITY_SKILLS_*`
143
+ environment variables while preserving `CLAUDE_PLUGIN_*` fallbacks.
144
+
145
+ ## 0.1.2 — 2026-05-28
146
+
147
+ - Docs: clarify that `rag` is not rtk-wrapped (prefixing is a no-op); prefer
148
+ `rtk` on the surrounding `rg` step, where `rtk rg -l` keeps paths raw. Permit
149
+ `Bash(rg:*)`/`Bash(rtk rg:*)` so the hybrid `rg -l | rag query` example runs.
150
+
151
+ ## 0.1.1 — 2026-05-24
152
+
153
+ Docs: correct the `rag status` skill example (reports counts/model/dim, not staleness).
154
+
155
+ ## 0.1.0 — 2026-05-24
156
+
157
+ Initial engine: bin/rag CLI, uv venv bootstrap, plugin manifest (loader/store/embed/index/engine/cli land in subsequent commits).
indexkit-0.6.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mark Beacom
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,222 @@
1
+ Metadata-Version: 2.4
2
+ Name: indexkit
3
+ Version: 0.6.1
4
+ Summary: Offline hybrid retrieval: build a local semantic + BM25 index over your files and query it. Local RAG with ollama, turbovec, and SQLite FTS5.
5
+ Project-URL: Homepage, https://github.com/mbeacom/context-kit
6
+ Project-URL: Repository, https://github.com/mbeacom/context-kit
7
+ Project-URL: Changelog, https://github.com/mbeacom/context-kit/blob/main/plugins/indexkit/CHANGELOG.md
8
+ Project-URL: Issues, https://github.com/mbeacom/context-kit/issues
9
+ Author: Mark Beacom
10
+ License: MIT License
11
+
12
+ Copyright (c) 2026 Mark Beacom
13
+
14
+ Permission is hereby granted, free of charge, to any person obtaining a copy
15
+ of this software and associated documentation files (the "Software"), to deal
16
+ in the Software without restriction, including without limitation the rights
17
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
+ copies of the Software, and to permit persons to whom the Software is
19
+ furnished to do so, subject to the following conditions:
20
+
21
+ The above copyright notice and this permission notice shall be included in all
22
+ copies or substantial portions of the Software.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
+ SOFTWARE.
31
+ License-File: LICENSE
32
+ Keywords: bm25,embeddings,hybrid-retrieval,local-rag,offline,ollama,rag,semantic-search,vector-search
33
+ Classifier: Development Status :: 4 - Beta
34
+ Classifier: Environment :: Console
35
+ Classifier: Intended Audience :: Developers
36
+ Classifier: License :: OSI Approved :: MIT License
37
+ Classifier: Programming Language :: Python :: 3
38
+ Classifier: Programming Language :: Python :: 3 :: Only
39
+ Classifier: Topic :: Software Development :: Libraries
40
+ Classifier: Topic :: Text Processing :: Indexing
41
+ Requires-Python: >=3.10
42
+ Requires-Dist: httpx>=0.27
43
+ Requires-Dist: turbovec>=0.5
44
+ Description-Content-Type: text/markdown
45
+
46
+ # indexkit
47
+
48
+ Offline hybrid retrieval: build a local semantic + lexical index over your files
49
+ and query it. Chunks and embeds a corpus through [`ollama`](https://ollama.com),
50
+ indexes it with [`turbovec`](https://github.com/RyanCodrai/turbovec) (a quantized
51
+ vector index), and fuses that with SQLite FTS5/BM25 for opt-in hybrid search.
52
+
53
+ No API key and no network egress by default — the embedding endpoint is
54
+ localhost. A configured remote `CONTEXT_KIT_OLLAMA_HOST` receives corpus chunks
55
+ and queries, so that is the one setting that sends data off the machine.
56
+
57
+ Notes-first but corpus-agnostic: loaders are pluggable, so the same engine can
58
+ index Markdown notes, code, or any text corpus.
59
+
60
+ > Formerly `local-rag`. The old name claimed a deployment property that a
61
+ > supported setting falsifies, and understated an engine that also does lexical
62
+ > retrieval. Pre-rename environment variables are still honored.
63
+
64
+ ## Install
65
+
66
+ > **Not on PyPI yet.** The package is publish-ready but the name has not been
67
+ > claimed. Until the release workflow runs, install from source; the `pip
68
+ > install` line below is what will work once it ships.
69
+
70
+ ```bash
71
+ # From a clone of https://github.com/mbeacom/context-kit
72
+ pip install ./plugins/indexkit # or: uv tool install ./plugins/indexkit
73
+ ollama pull nomic-embed-text # once
74
+ ```
75
+
76
+ Once published:
77
+
78
+ ```bash
79
+ pip install indexkit # or: uv tool install indexkit
80
+ ```
81
+
82
+ Either way that is the whole setup — no plugin host, no bootstrap step. Indexes
83
+ default to `${XDG_DATA_HOME:-~/.local/share}/indexkit`.
84
+
85
+ ```bash
86
+ indexkit index ~/notes --name notes
87
+ indexkit query "how did we handle retry backoff" --name notes --k 8
88
+ ```
89
+
90
+ ### As a context-kit plugin
91
+
92
+ Claude Code and GitHub Copilot CLI auto-bootstrap the bundled `bin/indexkit`
93
+ launcher from the plugin's `SessionStart` hook, into `${CLAUDE_PLUGIN_DATA}/venv`
94
+ — for Copilot, `~/.copilot/plugin-data/<marketplace>/indexkit/venv`. In that
95
+ mode the host controls where indexes live.
96
+
97
+ The launcher prefers that bootstrapped venv, then falls back to an `indexkit`
98
+ already on your `PATH`, then to any importable `indexkit` module. So a
99
+ pip-installed copy satisfies the plugin too, and a missing venv is not fatal.
100
+
101
+ ## Requirements
102
+
103
+ - [`ollama`](https://ollama.com) running with an embedding model pulled:
104
+
105
+ ```bash
106
+ ollama pull nomic-embed-text
107
+ ```
108
+
109
+ - [`uv`](https://docs.astral.sh/uv/) — **only** for the plugin bootstrap path.
110
+ A `pip install` needs nothing beyond Python 3.10+.
111
+
112
+ For APM or manual plugin usage — or on any host where the venv is missing or
113
+ stale — bootstrap it yourself into a neutral data location:
114
+
115
+ ```bash
116
+ export CONTEXT_KIT_DATA="$HOME/.local/share/context-kit"
117
+ bash scripts/bootstrap.sh
118
+ export PATH="$PWD/bin:$PATH"
119
+ ```
120
+
121
+ To check readiness without installing anything:
122
+
123
+ ```bash
124
+ bash scripts/bootstrap.sh --check # exit 0 ready, 3 needs bootstrap
125
+ ```
126
+
127
+ It prints `KEY=VALUE` lines: `status` (`ready`, `missing`, `stale`,
128
+ `uv-missing`), the raw `venv_status` and `uv` availability as separate fields,
129
+ the resolved `home`/`venv` paths, and the exact `bootstrap_command`. A `stale`
130
+ venv was built from different `pyproject.toml` metadata and would run outdated
131
+ code, so it is reported as clearly as a missing one. Because `uv` is only
132
+ needed to *build* the venv, an already-usable venv reports `ready` even when
133
+ `uv` is absent. Dependent tooling uses this to detect an unusable runtime on
134
+ hosts that do not deploy plugin hooks, such as APM. (Claude Code and GitHub
135
+ Copilot CLI both run this plugin's `SessionStart` bootstrap.)
136
+
137
+ ## Usage
138
+
139
+ Index a corpus, then query it:
140
+
141
+ ```bash
142
+ indexkit index <path> --name X
143
+ indexkit query "your question" --name X
144
+ indexkit query "exact terms and intent" --name X --hybrid
145
+ indexkit status --name X
146
+ indexkit list
147
+ indexkit remove --name X --yes
148
+ ```
149
+
150
+ Each named index is persisted under `<data-dir>/indexes/<name>/`, so queries are
151
+ fast and survive across sessions. The data directory resolves in this order:
152
+
153
+ 1. `CONTEXT_KIT_DATA` (or the `PRODUCTIVITY_SKILLS_DATA` alias)
154
+ 2. `CLAUDE_PLUGIN_DATA`, set by a plugin host
155
+ 3. `${XDG_DATA_HOME:-~/.local/share}/indexkit` — the standalone default
156
+
157
+ An existing `~/.claude/plugins/data/indexkit` directory still wins over the
158
+ standalone default while that default has not been created, so upgrading a
159
+ plugin install does not orphan indexes you already built.
160
+
161
+ ### Index lifecycle
162
+
163
+ Index names remain backward-compatible with earlier releases: any non-empty
164
+ single path component except `.` or `..` is accepted, including names with
165
+ spaces or more than 80 characters. Path separators (`/` and `\`) and NUL are
166
+ rejected. These containment rules apply consistently to `index`, `query`,
167
+ `status`, and `remove`.
168
+
169
+ `indexkit remove --name X --yes` permanently removes one named index. The command is
170
+ non-interactive and refuses to run without `--yes`; missing indexes fail clearly.
171
+ Indexing, querying, status inspection, and removal share a per-index process
172
+ lock, so removal fails clearly while that index is in use. Once locked, removal
173
+ moves only the selected index out of the active namespace, then unlinks its flat
174
+ artifact files without recursive directory deletion. Other indexes are
175
+ untouched, and incomplete cleanup is reported with the quarantined artifact
176
+ location rather than silently ignored.
177
+
178
+ Portable environment variables:
179
+
180
+ | Variable | Purpose | Claude fallback |
181
+ | --- | --- | --- |
182
+ | `CONTEXT_KIT_DATA` | venv and index storage | `CLAUDE_PLUGIN_DATA` |
183
+ | `CONTEXT_KIT_INDEXKIT_HOME` | venv location only, when it must differ from index storage | — (defaults to `CONTEXT_KIT_DATA`) |
184
+ | `CONTEXT_KIT_EMBED_MODEL` | ollama embedding model | `CLAUDE_PLUGIN_OPTION_EMBED_MODEL` |
185
+ | `CONTEXT_KIT_OLLAMA_HOST` | ollama base URL | `CLAUDE_PLUGIN_OPTION_OLLAMA_HOST` |
186
+ | `XDG_DATA_HOME` | relocates the standalone default data directory | — |
187
+
188
+ None of these are required for a standalone install; all have defaults.
189
+ The pre-rename `CONTEXT_KIT_LOCAL_RAG_HOME` is still read as a fallback for
190
+ `CONTEXT_KIT_INDEXKIT_HOME`.
191
+
192
+ `CONTEXT_KIT_DATA` normally holds both the venv and the indexes. Set
193
+ `CONTEXT_KIT_INDEXKIT_HOME` only when a caller needs to redirect *index data*
194
+ to an isolated store while still using one shared bootstrapped venv — the
195
+ `memory` plugin does this to keep each project's index inside its own
196
+ project-isolated provider directory. When it is unset, behavior is unchanged.
197
+
198
+ The pre-rename `PRODUCTIVITY_SKILLS_*` names still resolve as a deprecated alias
199
+ (`CONTEXT_KIT_*` → `PRODUCTIVITY_SKILLS_*` → Claude fallback).
200
+
201
+ ## Hybrid retrieval
202
+
203
+ Semantic-only retrieval remains the default. `--hybrid` adds SQLite FTS5 lexical
204
+ BM25 candidates and fuses them with turbovec semantic candidates using deterministic
205
+ reciprocal-rank fusion: `1.0 / (60 + semantic_rank) + 1.0 / (60 + lexical_rank)`.
206
+ Each source retrieves `3 × k` candidates before fusion, so the candidate depth is
207
+ greater than the requested final result count. JSON results include source offsets
208
+ and per-source rank/score metadata; text output remains compact.
209
+
210
+ `indexkit query` also accepts an `--allowlist` of candidate documents (read from a file,
211
+ or `-` for stdin), which applies to both semantic and lexical candidates. For
212
+ example, feeding Obsidian backlinks into a hybrid query:
213
+
214
+ ```bash
215
+ obsidian backlinks file="X" | indexkit query "..." --hybrid --allowlist -
216
+ ```
217
+
218
+ FTS5 is detected and backfilled automatically for existing indexes. `indexkit status`
219
+ reports its `fts5` capability. If the SQLite build lacks FTS5, semantic retrieval
220
+ continues to work but `--hybrid` exits with a clear error.
221
+
222
+ MIT © Mark Beacom.