Metadata-Version: 2.4
Name: delphi-code
Version: 0.2.10
Summary: Offline local code search for agents
Author: Mark Dorofeev
License-Expression: Apache-2.0
Project-URL: Repository, https://github.com/markdorof/delphi-code
Project-URL: Issues, https://github.com/markdorof/delphi-code/issues
Keywords: code-search,semantic-search,embeddings,offline,cli,agents
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: MacOS
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development
Classifier: Topic :: Text Processing :: Indexing
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: THIRD_PARTY_NOTICES.md
Requires-Dist: cocoindex==1.0.24
Requires-Dist: sqlite-vec==0.1.9
Requires-Dist: sentence-transformers==6.1.0
Requires-Dist: numpy==2.5.3
Requires-Dist: pathspec==0.12.1
Requires-Dist: questionary==2.1.1
Requires-Dist: certifi
Requires-Dist: torch<2.15,>=2.14
Requires-Dist: transformers<6,>=5.17
Requires-Dist: huggingface-hub<2,>=1.32
Requires-Dist: tokenizers<0.24,>=0.23.2
Dynamic: license-file

# Delphi Code

Offline semantic code search for agents. Delphi Code is a small Python CLI that indexes local source trees with a local embedding model and answers natural-language queries with JSON for agents and readable text in a terminal. No daemon, server, account, or cloud embedding provider.

## Quick start

Install with the script, which also installs [uv](https://docs.astral.sh/uv/) if it is missing and runs `setup`:

```sh
curl -LsSf https://github.com/markdorof/delphi-code/releases/latest/download/install.sh | sh
```

Or, with uv already installed:

```sh
uv tool install --managed-python delphi-code
delphi-code setup
```

Then index a project and search it:

```sh
delphi-code index -p /absolute/path/to/project
delphi-code search 'where are user passwords checked?'
```

`setup` downloads and verifies the embedding model once; after that, every command runs offline. Without `-p`, `search` looks through every indexed project.

To use it from an agent, connect the agent to the MCP server, which keeps the model loaded so repeated searches are near-instant, and give it the [skill](https://github.com/markdorof/delphi-code/blob/main/plugin/skills/delphi-code/SKILL.md), which tells it when to search by meaning instead of grep:

| Agent | Setup |
|---|---|
| Claude Code | `claude plugin marketplace add markdorof/delphi-code`, then `claude plugin install delphi-code@delphi-code` |
| Codex | `codex plugin marketplace add markdorof/delphi-code`, then install it from `/plugins` |
| Cursor | Add `{"mcpServers": {"delphi-code": {"type": "stdio", "command": "delphi-code", "args": ["mcp"]}}}` to `~/.cursor/mcp.json` |
| VS Code (Copilot) | `code --add-mcp '{"name": "delphi-code", "command": "delphi-code", "args": ["mcp"]}'` |
| Gemini CLI | `gemini mcp add delphi-code delphi-code mcp` |

The Claude Code and Codex plugins include both. For the others, also copy the skill to `~/.agents/skills/delphi-code/SKILL.md`.

## Requirements

- macOS 14+ on arm64 (tested). Linux is not yet verified; Windows is not supported.
- Python 3.12+ with SQLite loadable extensions. `--managed-python` makes uv use a Python build that supports them; `doctor` checks this.
- No GPU needed.

## Installation

The install script runs the same `uv tool install --managed-python delphi-code` and `delphi-code setup` as the uv option. Pass options after `sh -s --`: `--no-setup` skips the model download, `--version VERSION` picks a release. Running it again upgrades.

From a checkout, with uv:

```sh
uv tool install --managed-python /absolute/path/to/delphi-code
delphi-code setup
```

`setup` downloads the pinned [all-MiniLM-L6-v2](https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2) model and checks it against bundled hashes. Running it again reuses a valid model. `--model DIR` or `DELPHI_CODE_MODEL` selects a different location. For an offline machine, import a prepared model directory:

```sh
delphi-code setup --from /absolute/path/to/all-MiniLM-L6-v2
```

### Upgrading

```sh
uv tool upgrade delphi-code
```

See [GitHub Releases](https://github.com/markdorof/delphi-code/releases) for changes. The model and indexes are kept. If a release can't reuse an old index, commands fail with `index_incompatible`; delete the index directory the error names and run `index` or `sync` again.

### Uninstalling

```sh
uv tool uninstall delphi-code
rm -rf ~/Library/Application\ Support/delphi-code
```

On Linux the data directory is `$XDG_DATA_HOME/delphi-code` or `~/.local/share/delphi-code`.

## Indexing projects

```sh
delphi-code index -p ~/src/api              # one-off; run again after changes
delphi-code add ~/src/api ~/src/web         # track local projects
delphi-code add github.com/octo/tools       # track a remote repo (no clone needed)
delphi-code add                             # pick repos from your Bitbucket/GitHub account
delphi-code sync                            # update everything tracked
```

Tracked projects live in `repos.toml` in the data directory. Remote repos are shallow-cloned to a temp dir on `sync` and skipped when unchanged; `--ref` picks a branch or tag. Only `add` and `sync` use the network.

Remote credentials: `GITHUB_TOKEN`/`GH_TOKEN` (or `gh auth token`) for GitHub; `BITBUCKET_APP_PASSWORD` (an API token works) with `BITBUCKET_EMAIL` or `BITBUCKET_USERNAME` for Bitbucket. Otherwise git's stored credentials are used.

## Commands

```sh
delphi-code doctor -p /path/to/project
delphi-code index -p /path/to/project
delphi-code search -p /path/to/project 'parse configuration' --language python --path 'src/*' --limit 5
delphi-code status -p /path/to/project
delphi-code list --indexed
```

| Command | What it does | Options |
|---|---|---|
| `setup` | Downloads or imports the model and checks the installation. | `--from DIR`, `--model DIR` |
| `doctor` | Checks the model, SQLite extensions, and storage with a real embedding. | `-p`, `--model` |
| `index` | Builds or incrementally updates a project's index. | `-p`, `--model`, `--path`, `--language`, `--ignore`, `--max-bytes` |
| `search QUERY` | Runs a natural-language query. Without `-p`, searches every index. | `-p`, `--model`, `--path`, `--language`, `--limit` (default 10) |
| `status` | Reports a project's index state. | `-p` |
| `add [SOURCE ...]` | Tracks and indexes projects or remote repositories; without sources, picks repositories interactively. | `--ref`, `--no-sync`, `--model`, `--path`, `--language`, `--ignore`, `--max-bytes` |
| `sync` | Indexes every tracked project. | `--model` |
| `list` | Lists tracked projects and stored indexes. | `--indexed` |
| `remove NAME` | Stops tracking a project and deletes its index. | `--keep-index` |
| `mcp` | Serves the commands above as MCP tools over stdio, with the same names and options. | `--model` |

Every command accepts `--json` and `--help`. `--path`, `--language`, and `--ignore` can be repeated.

### Selecting a project

`-p` / `--project` takes a path, or, once a project is indexed, its key or folder name (`acme/api`, `api`). Use `./name` to force a directory. Without `-p`, `search` searches all indexes and other commands use the current directory.

## Output

In a terminal, commands print readable text (`NO_COLOR` disables colors). Otherwise, or with `--json`, each command writes one JSON object with `schema_version`, `ok`, `command`, and `data` or `error`:

```json
{
  "command": "search",
  "ok": true,
  "schema_version": 1,
  "data": {
    "query": "where is the model checksum verified?",
    "results": [
      {
        "path": "delphi_code/setup.py",
        "language": "python",
        "start_line": 17,
        "end_line": 31,
        "score": 0.39,
        "text": "def verify_assets(root):\n    …"
      }
    ]
  }
}
```

Higher `score` means a closer match.

| Exit code | Meaning |
|---|---|
| 0 | Success, including no matches |
| 2 | Invalid arguments or project |
| 3 | Missing or incompatible model |
| 4 | Missing, incomplete, or incompatible index |
| 5 | Busy index or operational failure |

## What gets indexed

- `.gitignore` and `.delphi-codeignore` files are respected, plus any `--ignore` patterns.
- `.git`, `.venv`, `venv`, `node_modules`, `__pycache__`, and the model directory are skipped, as are symlinks, binary files, and files over `--max-bytes` (default 1 MiB).
- `--path` globs and `--language` values (such as `python`, `typescript`) narrow the selection. On `index` they define the whole indexed set; on `search` they filter results.

## Models

The default model, MiniLM, is small and general-purpose. Any local SentenceTransformers model with safetensors weights and no custom code can be used through `--model` or `DELPHI_CODE_MODEL`. Searching an index with a different model fails instead of returning wrong results.

## Storage and logs

Data lives in `~/Library/Application Support/delphi-code/` on macOS and `~/.local/share/delphi-code/` on Linux: the model, indexes, `repos.toml`, and `logs/delphi-code.log`. Override locations with `DELPHI_CODE_MODEL`, `DELPHI_CODE_INDEX_ROOT`, `DELPHI_CODE_REGISTRY`, and `DELPHI_CODE_LOG_FILE`; set `DELPHI_CODE_LOG_LEVEL` to `DEBUG`, `INFO`, `WARNING`, `ERROR`, or `OFF`. Logs never leave the machine.

A Git repository with an `origin` remote shares one index across clones and moves; other directories are indexed by path.

## Offline guarantees

The CLI disables telemetry, loads models only from local files, and blocks network access from Python. Only `setup`, and `add`/`sync` for remote repositories, need the network. For an OS-level guarantee on macOS:

```sh
/usr/bin/sandbox-exec -p '(version 1)(allow default)(deny network*)' \
  delphi-code index -p /path/to/project
```

## Development

See [CONTRIBUTING.md](https://github.com/markdorof/delphi-code/blob/main/CONTRIBUTING.md).

## License

Apache-2.0. See [THIRD_PARTY_NOTICES.md](https://github.com/markdorof/delphi-code/blob/main/THIRD_PARTY_NOTICES.md) for dependency and model notices.
