Skip to main content

climble

A thin Typer CLI wrapper around semble — instant code search for any local or git repo, from your shell.

climble mirrors the two operations exposed by semble's MCP server (search and find_related) so its output is interchangeable with what an MCP-connected agent would see.

Some of the helpers in src/climble/cli.py are adapted from semble's src/semble/mcp.py under the MIT license — see THIRD_PARTY_LICENSES.md.

Install

# from PyPI (once published)
uv add climble
# or, in this repo:
uv sync

Usage

# Search the current directory
uv run climble search "save model to disk"

# Search a remote repo (cloned to a temp dir; no cache between invocations)
uv run climble search "tokenizer chunking" --repo https://github.com/MinishLab/semble -k 10

# Pick a search mode (hybrid|semantic|bm25)
uv run climble search "BM25" --mode bm25

# Find chunks semantically similar to a specific location, using
# file_path:line from a prior `search` result
uv run climble find-related src/climble/cli.py 67

Options

Both commands accept:

  • --repo, -r — git URL or local path. Default: .
  • --top-k, -k — number of results. Default: 5
  • --ref — branch/tag (git URLs only)

search additionally accepts:

  • --mode, -mhybrid (default), semantic, or bm25

Notes

Each invocation re-indexes from scratch — there is no persistent on-disk cache. For repeated queries against the same repo, run semble's MCP server directly, which caches indexes in-process for the lifetime of the session.

Development

make install   # uv sync --group dev + pre-commit install
make test      # uv run pytest
make lint      # ruff check + format check + ty
make check     # lint + test
make format    # ruff --fix + format in place

Releasing

Releases are cut through GitHub Releases — not a manual publish command. Publishing a release fires .github/workflows/publish.yml, which runs uv build && uv publish --trusted-publishing always inside the pypi environment via OIDC. There are no stored PyPI tokens to rotate.

The flow:

  1. Land changes on main. Ensure CI is green (style + test workflows).
  2. Bump version in pyproject.toml and __version__ in src/climble/__init__.py. Keep them in sync. Pre-1.0: minor bump for new features, patch bump for fixes.
  3. Promote the ## Unreleased section in CHANGELOG.md to ## X.Y.Z — YYYY-MM-DD. Add a fresh empty ## Unreleased above it.
  4. Commit as chore(release): vX.Y.Z. Duplicate the CHANGELOG section into the commit body so the commit stands alone.
  5. Push: git push origin main.
  6. Tag with the full release notes in the annotation. Write the new CHANGELOG entry's body to a temp file, then: git tag -a vX.Y.Z --cleanup=verbatim -F notes.md && git push origin vX.Y.Z.
  7. Create the GitHub Release from the tag: gh release create vX.Y.Z --notes-from-tag --title vX.Y.Z (or use the web UI). Publication triggers the publish workflow.

Why steps 6 and 7 look like this. gh release create --notes-from-tag copies the tag annotation verbatim into the release body, so the annotation is the release notes — -m vX.Y.Z produces an effectively empty release body. -F notes.md fills the annotation from a real file. --cleanup=verbatim is required to keep ## markdown headers — without it, git strips every line starting with # as a comment, so your section structure disappears before it ever reaches GitHub.

The make pypi target is a manual fallback only, not the canonical path. It runs uv build && uv publish locally and requires a PyPI token in the environment; it bypasses CI's clean build and the version/tag/changelog discipline above. Avoid it unless Trusted Publishing is down.

One-time setup before the first release

  • PyPI Trusted Publisher: register this repo as a Trusted Publisher on PyPI for the climble project. Workflow filename: publish.yml. Environment: pypi. (Until this is configured, the publish workflow will fail with an OIDC error.)
  • GitHub Environment: create an environment named pypi in the repo settings. No secrets needed (OIDC).
  • PyPI name availability: climble is currently un-claimed on PyPI as of writing; if it gets taken, fall back to climble-cli for the distribution name (the import name and CLI command stay climble) — see how croc handles this in croc-cli.

License

MIT — see LICENSE and THIRD_PARTY_LICENSES.md.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

climble-0.1.0.tar.gz (68.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

climble-0.1.0-py3-none-any.whl (6.7 kB view details)

Uploaded Python 3

File details

Details for the file climble-0.1.0.tar.gz.

File metadata

  • Download URL: climble-0.1.0.tar.gz
  • Upload date:
  • Size: 68.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for climble-0.1.0.tar.gz
Algorithm Hash digest
SHA256 56c33db9cb65490a85634c4ef65f3c0a0ca0218d75eaabc83c851f56a2392146
MD5 309afa374de4817803f729fc27c556ef
BLAKE2b-256 34f79e3b1cf3d0fc0f66ac638856b6ec7f441cc1ee6767d27a58672e4e9a81ed

See more details on using hashes here.

File details

Details for the file climble-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: climble-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 6.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for climble-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 137cb3cf60d87d0eed7bfab1bb5a2910ee36a2a34ebbb197b448793ddc4ac5ad
MD5 2a1ed5c3b4e2a130e84618d6dda51277
BLAKE2b-256 0a7b0108ab024df4e974260a179c7b4a9d4d9e1d0e74abf63d0419b82d0b5ec1

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page