Omahub
← All plugins
Y

Gitcrawlchy

by yamz8

Search a gitcrawl mirror from the Omarchy bar

Security review

No obvious issues detected

Deterministic scan — not a security guarantee

None
Risk level
None
Analyzed commit
dea70f6
Scanned
1 month ago

No potentially dangerous behavior detected in the analyzed commit.

Automated analysis only — not a security guarantee.

AI advisory review

No obvious issues detected

Language-model assessment · ~deepseek/deepseek-v4-flash-latest — advisory only

Low
AI risk level
Low
Recommendation
install
Model
~deepseek/deepseek-v4-flash-latest
Analyzed commit
dea70f6
Reviewed
1 month ago

The plugin is a QML bar widget that shells out to a pinned, checksum-verified gitcrawl binary and a small bash bridge. The installer is defensive (HTTPS-only, origin checks, size cap, pinned SHA-256) and the bridge only reads local data and runs search/tui commands. No obfuscation, persistence, credential exfiltration, or destructive behavior was found.

  • The bridge reads ~/.config/gitcrawl/openai.key and exports it as OPENAI_API_KEY to child processes; this is a local secret but is only used to enable the gitcrawl CLI's embedding features, not transmitted anywhere by the plugin itself.
  • The bridge borrows `gh auth token` and exports GITHUB_TOKEN to child processes; again local use only, but worth noting the plugin will make the token available to the gitcrawl binary it invokes.
  • The installer downloads and executes a binary from GitHub releases; mitigations (pinned tag, pinned SHA-256, HTTPS-only, origin allowlist, 10 MiB cap) are strong, but installing a third-party binary is inherently a supply-chain decision the user should be aware of.
  • The bridge includes a `cmd_repos` function that reads gitcrawl's SQLite database directly; it is read-only and guarded, but it does couple the plugin to gitcrawl's internal schema.
How this check works

This review combines the deterministic scan (the rule-based results above) with an independent look at the plugin's code by a language model. The model reads a trimmed sample of the repository's files, the manifest, and the README, then gives a plain-language risk level and a recommendation: install (no notable danger), review (look closer first), or avoid (clearly dangerous).

It runs on the same analyzed commit as the deterministic scan and is strictly advisory — it is not a security guarantee and never blocks a plugin by itself. A human moderator still reviews plugins before they are listed.

AI advisory only — automated analysis, not a security guarantee.

Install
$ omarchy plugin add https://github.com/yamz8/gitcrawlchy --enable
Developer Tools #bar #quickshell

Gitcrawlchy

A bar widget for one command: gitcrawl search, over gitcrawl's local SQLite mirror of a GitHub repository's issues and pull requests.

Click gitcrawl's mark in the bar, describe a problem, and read what is already in the mirror.

What it is

A UI for a single CLI command, not a front end for gitcrawl.

gitcrawl search takes five flags. The panel is those five flags and the rows they return:

Flag Control
owner/repo the repository picker — discovered from your own mirror
--query the text field
--mode keyword / semantic / hybrid
--scope threads / code / all
--limit a row count, beside the query

Nothing is filtered, re-ranked or reimplemented on this side: the rows are the command's hits in the order it ranked them, and the footer prints the invocation so the panel is checkable against the CLI.

Open gitcrawl hands the selected repository to gitcrawl tui, which is the cluster browser and where triage belongs. Everything else gitcrawl does is another command; bin/gitcrawlchy still shims the rest for scripts.

Controls are grouped by line: the repository and the handoff; the query and how many rows to ask for; then --mode and --scope as two chip groups of three pushed to opposite ends. Seven chips in one row read as a single seven-way choice — two threes with a gap read as two decisions.

The footer prints the invocation across as many lines as it needs. It used to elide, which meant a long query pushed --limit off the end and the line stopped being the checkable thing it exists to be.

What a row shows

Only what the payload carries, which varies by mode: score comes back from semantic and from the vector half of hybrid, and scope only under --scope all. Both are shown when present rather than invented when absent.

Rows open html_url — gitcrawl's own link, not a path built from a number.

Why --limit is bounded, and why there is no "all"

--limit truncates the ranking and the payload carries no total, so a full page means at least this many. The header says 25+ RESULTS · LIMIT REACHED rather than presenting the ceiling as an answer, and the picker sits beside the query because how many rows to ask for is part of the request.

There is no unlimited option, and gitcrawl has no flag for one: omitting --limit returns 20 rather than everything, and --limit 0 and --limit -1 are both refused with expected positive integer. A very large number does work — --limit 100000 on the returns all 6,085 matches — but that is 2.5 MB of JSON and about 650 ms through the bridge before QML parses it and builds six thousand rows, which is the cost profile that made the old cluster view take twenty seconds to open. 200 is the ceiling for that reason.

When it comes back empty

gitcrawl writes its failures to stderr and nothing to stdout, so a UI that discards stderr has to guess why a search returned nothing. This one reports what the command said:

  • a missing OpenAI key — semantic and hybrid embed the query at search time, so without it they return zero hits and say nothing
  • a repository that is not in the mirror
  • no vectors for the repository yet

And when the search genuinely matched nothing, the wording is about the mirror rather than about GitHub. Nothing in the search payload dates the mirror, so this panel cannot tell you it is stale — no matches means "not in the local mirror", which is not the same as "not reported".

The keyboard

The panel opens with its search field focused, so bare letters stay typeable and navigation takes Alt and the arrows. Omarchy's PanelKeyCatcher bare h/j/k/l would be swallowed by the field, which is why it is not used.

Key Does
Alt + 1 / Alt + 2 / Alt + 3 --mode keyword / semantic / hybrid
Alt + 4 / Alt + 5 / Alt + 6 --scope threads / code / all
Alt + R next repository
Alt + T open gitcrawl tui on the selected repository
Alt + Left / Alt + Right previous / next mode
Down / Up move the cursor through the rows
Enter open the row under the cursor, or run the search when no row is picked
Escape leave the row list, then close the panel

Changing any flag re-runs the search when results are showing, because a flag only means something in terms of a result — switching mode and leaving the old rows up would label the previous answer with the new mode.

Why the mode picker is not decoration

On the omacom/omarchy corpus (7,046 threads), keyword search returns nothing at all for a sentence a person would actually type. Semantic finds the real duplicate:

Query keyword semantic
lock screen wont accept password 0 #3562 cant use the password in lockscreen
audio crackling after update 0 #6037 Audio Quality Dropped Significantly…
my laptop wont wake up after closing the lid 0 #3511 Screen does not wake up after… lid closed

Repositories

search takes owner/repo as a positional argument, so the repository is part of the query rather than a setting the panel happens to remember. Switching clears the results and re-runs, so the previous repo's rows never sit under the new repo's name.

--mode and --limit persist as preferences. --scope does not: code and all are one-off detours, and a panel left on code would fail the next search you opened it to run, for a reason from a previous session.

What this does not cover

The panel runs gitcrawl search and nothing else. No clusters, no sync, no doctor, no pipeline — those are other commands, and gitcrawl tui or the CLI is where they belong.

One consequence worth stating plainly: because status and doctor are gone, the panel cannot tell you the mirror is stale. A search hit carries no sync timestamp, so this is a limit of the command, not an omission — see When it comes back empty.

bin/gitcrawlchy still dispatches the wider set for scripting. Not dispatched at all:

Area Commands
Remote / cloud archives remote status, remote archives, remote login, whoami, cloud publish
Portable stores portable export, portable prune
Setup init, configure
Control metadata metadata
gh-shaped search search issues|prs — a second usage of search, closer to gh search over the mirror than to the ranked local form
Superseded gh (prints a migration notice), cluster-explain (alias for cluster-detail)

The mark

BrandMark.qml draws gitcrawl's own logo — the three connected nodes — with the geometry lifted from docs/social-card.svg in the gitcrawl repository, so it is the real mark rather than an impression of it.

It paints monochrome in the bar, following the active theme, because Omarchy's bar icons are monochrome and a single coloured logo in that row reads as a mistake. Panel headers use gitcrawl's palette (#60a5fa, #2dd4bf, #93c5fd), where colour belongs.

Below about 28px the nodes are fattened and the links thinned. The source proportions are drawn for a 118px logo; scaled straight down to a 22px bar icon the dots vanish and the three links dominate, so the mark reads as a play triangle instead of a graph.

Requirements

  • gitcrawl on PATH — no Go toolchain needed, the project publishes release archives:

    ./scripts/install-gitcrawl.sh
    

    Installs to ~/.local/bin (override with PREFIX).

    The installer is pinned: the version and both architecture SHA-256 digests are written into the script itself, so what gets installed is fixed by the source you are reading rather than resolved from a mutable "latest" release at run time. The digest is checked against that pinned value — not against a checksums.txt published alongside the download — and is verified before the archive is opened. HTTPS is required at every hop, a redirect off the expected release origin is refused, and any mismatch exits non-zero without installing anything.

    The download is also capped at 10 MiB — a small allowance over the pinned archives, which are 7,085,432 (amd64) and 6,502,668 (arm64) bytes. curl refuses an oversized declared length up front and aborts mid-transfer once the ceiling is crossed, and the stream is piped through head so a response that declares no length at all still cannot write past it. Either way the script exits non-zero with nothing installed, so a hostile or faulty response from the release origin cannot fill the disk while the digest it was always going to fail is computed. Move the ceiling in the same commit as the pin if a future archive outgrows it.

    Currently pinned to v0.9.2. To move to a newer gitcrawl, change PINNED_TAG and both digests in the same commit; the script takes no version argument. Without gitcrawl present the plugin says so and points at the installer rather than reporting a pile of absences that are not real.

  • GITHUB_TOKEN, or gh authenticated — the bridge borrows gh auth token

  • For embeddings: an OpenAI-compatible key at ~/.config/gitcrawl/openai.key (mode 600). Embedding the whole corpus cost about $0.03.

    The key is needed at search time as well, not only when embedding: semantic and hybrid modes embed the query before comparing vectors. Without it gitcrawl returns zero hits and says nothing, which reads as "nothing has been reported".

Install

omarchy plugin add https://github.com/yamz8/gitcrawlchy.git --enable
omarchy bar put yamz8.gitcrawlchy --section right
omarchy restart shell

omarchy plugin add clones the repository, validates the manifest, and installs it as yamz8.gitcrawlchy. Update later with omarchy plugin update yamz8.gitcrawlchy.

To open the panel from the keyboard, add this to ~/.config/hypr/bindings.lua:

o.bind("SUPER + ALT + C", "Gitcrawlchy", "omarchy-shell yamz8.gitcrawlchy toggle")

Install from a local checkout

cp -R ./gitcrawlchy ~/.config/omarchy/plugins/yamz8.gitcrawlchy
omarchy plugin validate ~/.config/omarchy/plugins/yamz8.gitcrawlchy
omarchy plugin enable yamz8.gitcrawlchy
omarchy restart shell

Remove

omarchy bar remove yamz8.gitcrawlchy
omarchy plugin disable yamz8.gitcrawlchy
omarchy plugin remove yamz8.gitcrawlchy
omarchy restart shell

That takes the widget out of the bar and deletes ~/.config/omarchy/plugins/yamz8.gitcrawlchy. The plugin writes nothing outside that folder: the mirror, the GitHub token and the embedding key all belong to gitcrawl and are left alone. Remove the SUPER + ALT + C line from bindings.lua yourself if you added one — this plugin never edits it.

Settings

Per-widget, in shell.json:

Key Default Meaning
repo (empty) The owner/repo search runs against. Empty means "ask gitcrawl"
repos "" Comma-separated list for the picker; it appears once there is more than one
mode hybrid Starting --mode
limit 25 Starting --limit

The plugin ships with no repository configured. Left unset, it asks gitcrawl which repository your mirror is about — gitcrawl tui --json with no argument reports the most recently updated one, which is the only supported way to discover it. So a fresh install searches your mirror, not a repository baked into the plugin. If nothing has been synced yet, the panel says so and gives you the command.

Set repo to pin one. Set repos to switch between several — a picker appears above the query box, and Alt + R walks the list. Switching clears the results and re-runs the query against the new repository.

{ "id": "yamz8.gitcrawlchy", "repos": "omacom/omarchy,openclaw/gitcrawl" }

The list is configured because nothing in gitcrawl can produce it: no command enumerates repositories, status --json counts them without naming them, and tui --json reports only the one it is browsing. The alternative is reading gitcrawl's SQLite schema directly, which is what the previous picker did and the one place this plugin was coupled to gitcrawl's storage rather than its interface.

Bridge

bin/gitcrawlchy is usable on its own — one JSON object per command, diagnostics on stderr, NDJSON progress for long jobs:

gitcrawlchy status
gitcrawlchy clusters omacom/omarchy 6 | jq '.clusters[0]'
gitcrawlchy search omacom/omarchy "lid close" hybrid threads 25
gitcrawlchy refresh omacom/omarchy      # streams

Notes

Editing this plugin's QML requires omarchy restart shell — rescanPlugins reports success and keeps serving the old code.

License

MIT