ghir
Search your GitHub repos, cloned or not, across every organization you belong to. Fetch once, then search offline; each hit says where it is cloned on this machine, if anywhere.
pip install ghir
ghir refresh # you + your orgs, through the gh CLI
ghir search "flashcards spaced repetition" # offline, ranked by ir
0.032 thorwhalen/tetrachord /home/me/proj/tt/tetrachord
Music education with a learner model and scheduler at the architectural centre.
0.015 thorwhalen/rbxloop (not cloned)
Requires the GitHub CLI (gh auth login) for refresh only; searching never touches the network.
The four seams
ghir is corpus -> extraction -> ranking, with a cache beside it. Each is one keyword argument with a working default.
| Seam | Argument | Default | Alternatives |
|---|---|---|---|
| Locations: which repos | refresh(locations) |
"@me": you and every org you belong to |
owner logins, "search:<github search query>" |
| Extraction: what text a repo contributes | extract= |
"description_and_readme" (name, description, topics, README head) |
"description", or any record -> str callable |
| Ranking | rank= |
"ir": hybrid dense + BM25 through ir, indexed incrementally |
"grep" (query terms as word prefixes, no index, no model), or any callable |
| Cache | store= |
one JSON file per repo under ~/.local/share/ghir/repos/ |
any MutableMapping (a dol store: S3, a database) |
refresh merges: fetched repos overwrite their own entries, and cached repos it did not see this time are kept. A location that fails to fetch is reported in "failed" and its cached repos stay.
import ghir
ghir.refresh(["i2mint", "search:user:thorwhalen topic:education"])
for hit in ghir.search("audio tagging", rank="grep", include_forks=False):
print(hit.id, hit.local_path or hit.url)
Settings
Machine-specific choices go in ~/.config/ghir/config.json (or $GHIR_CONFIG):
{"locations": ["@me", "otosense"],
"exclude": ["SomeClientOrg/*", "myorg/private-thing"]}
An owner excluded with owner/* is never queried. local_exclude takes patterns over local clone paths ("q/private-repo"); by default it is ir's own per-machine list, ~/.config/ir/exclude, so a repo ir must not index is not fetched, cached or shown through GitHub either. A refresh purges cached repos that have become excluded. Other keys: extract, local_roots (where clones are looked for; default $PP or your home), cache_dir, corpus_name.
Using it from ir
ghir refresh also registers the cache as the ir corpus gh_repos (a records corpus whose fetcher is ghir:records), so ir's own tools see it:
ir discover gh_repos "spaced repetition"
ir discover gh_repos packages "audio tagging" # federated with the local packages corpus
Why this is a separate package and not part of ir: docs/adr/0001-where-ghir-lives.md.
Metadata
Release files for ghir 0.0.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| ghir-0.0.3.tar.gz | 18.1 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ghir-0.0.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 35.7 kB
Release files / ghir-0.0.3.tar.gz
| Download URL | ghir-0.0.3.tar.gz |
|---|---|
| Size | 18.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cf63a5ae7b4932d527541279b9bda21ccfdf912d41a6828c39d58e76ce98a8bf
|
|
BLAKE2b-256 checksum How to use checksums |
21ff37a23d6de92bf74f01f3a87f9dcdfaa7eb92ac819be1742425b0d84f8066
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","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}
|
Release files / ghir-0.0.3-py3-none-any.whl
| Download URL | ghir-0.0.3-py3-none-any.whl |
|---|---|
| Size | 17.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d85a8d490c944ffe13cf05499d29edbffb63fe3ed19f0d1f63aa3d08d7bc253e
|
|
BLAKE2b-256 checksum How to use checksums |
9bcaf85d46c430a4f022229c2ab7eee81fb24bf9b2264c38515ed79573801fba
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","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}
|
Security for ghir 0.0.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.