Repository navigation
Releases
v0.4.0 — rate-limit resilient
Maintained fork of awesome-dsh-plugin/dsh-find-plugin 0.3.7, fixing the anonymous-search-quota failures (GitHub search HTTP 403).
Install
dsh plugin --profile web add github:vclike/dsh-find-pluginThen restart dsh web. Set a GITHUB_TOKEN credential to get 30 req/min instead of the anonymous 10 req/min (per public IP, shared).
Why
Upstream calls api.github.com/search/repositories anonymously. That endpoint allows only 10 requests/minute per public IP, shared by everyone behind the same egress IP, so the tool failed constantly. Measured on 2026-09-11 through a carrier CGNAT shared egress:
- 13 rapid calls -> 7x403 / 6x200 alternating
- 403 body:
API rate limit exceeded for <shared egress IP>. (But here's the good news: Authenticated requests get a higher rate limit...) - headers:
x-ratelimit-limit: 10,x-ratelimit-remaining: 0 - a session's first call could already 403
Upstream's only mitigation is a 5-minute per-query cache (the agent changes keywords every call, so it misses), and the ~3400-entry curated list was consulted only after a successful search - never as a fallback.
Fixes & additions
- Token auth via the DSH
GITHUB_TOKENcredential (10 -> 30 req/min, not IP-shared). The credentials service is optional, read withctx.get()rather thaninject(a missing required service would stop the plugin from loading at all). - Retry once on 403/429 (honouring
retry-after) and once on network errors, then throw a typedGitHubSearchRateLimitedcarryinglimit/remaining/resetAt. - Failure caching (60s) so a retry loop cannot keep burning the quota.
- Dual-source results: live GitHub + curated keyword matches, deduped by URL; GitHub first (star-ranked, as upstream), curated-only entries fill the remaining slots and render with a
[curated]marker. - Curated registry cache: disk cache at
$DSH_HOME/cache/dsh-find-plugin/registry.json+If-None-Match/If-Modified-Sinceconditional requests (304 = zero body). Fallback chain: memory -> disk (~3400 entries) -> bundled snapshot (~176). - Curated matching: rank by matched-token count first (AND-ish semantics for multi-word queries), then weighted score, then stars; descriptions truncated to 240 chars.
- Forward
exec.signal;timeoutMs10s -> 25s. - Tests: 33 offline cases (mock
fetch) + 3 opt-in live network cases +tsc --noEmitoversrc/*.ts. - Dropped the broken
prepackscript (it referenced atsconfig.jsonandscripts/strip-client-export.mjsthat are not shipped, sopnpm buildalways failed - and it would have reverted fixes applied tolib/).
Compatibility
DSH 0.1.5-rc.2 verified. Tool name, inject and parameters are unchanged, so this is a drop-in replacement.
Credits
Upstream plugin and the curated list by awesome-dsh-plugin; the same problem is tracked upstream as issue #5.