Changelog
This page mirrors the canonical CHANGELOG.md in the repo root. Versions follow Semantic Versioning and match the published git tags.
v0.11.0 — 2026-07-07
Added
- Federated multi-backend search:
ketch search --multi(and the MCPsearchtool'smultiinput) queries several backends at once and fuses their rankings with Reciprocal Rank Fusion, so a page multiple engines rank highly rises to the top. Bare--multifederates every usable backend (zero-config installs still get ddg + exa + keenable);--multi=brave,exapicks an explicit set (the=is required for a list). Results are deduplicated by URL canonicalization, each backend gets a 10s timeout with graceful degradation (failed:frontmatter / additive MCPerrorsmap), and every fused result lists the engines that found it. firecrawlweb search backend via the Firecrawl v2 search API, configured withketch config set firecrawl_api_key <key>and selected with-b firecrawl. Reportsfirecrawl_api_key_setinketch configdiscovery and is covered by a liveketch doctorprobe.keenableweb search backend over the Keenable index, built for AI agents. Keyless by default (public endpoint, rate-limited); an optionalkeenable_api_keylifts the rate limit.ketch extract— pipe HTML through ketch's readability + markdown pipeline with no fetch:curl -L <url> | ketch extract. Supports--url(metadata + relative-link resolution),--select,--trim,--max-chars, and the global--json; deliberately no cache, browser, or MCP surface.- Claude Code plugin + marketplace manifest:
claude plugin marketplace add 1broseidon/ketch, thenclaude plugin install ketch@ketchwires upketch mcp serveand the bundled agent skill. Optional convenience — the stateless CLI remains the zero-infrastructure path.
v0.10.0 — 2026-07-01
Added
ketch mcp serve— ketch as an MCP server over stdio, exposingsearch,code,docs,scrape, andcrawlwith the same config-driven backends as the CLI, stable[kind]error prefixes mirroring the CLI exit codes, and concise server instructions in the initialize result.- Bundled agent skill at
skills/ketch/— a SKILL.md playbook any skill-loading agent can install: surface routing, token budgets, error-prefix control flow, a deep-research recipe, and a guided backend-setup flow. ketch doctor— deterministic live health checks for every surface (search/code/docs backends, browser, cache) withok/no_key/unreachable/misconfiguredstatuses, fix hints (including the SearXNGformat: jsontrap), aligned human output or stable--json.- Key-presence booleans in
ketch configdiscovery (brave_api_key_set,exa_api_key_set,context7_api_key_set,github_token_set) so agents can tell "unconfigured" from "ready" in one call. - Shared config-driven constructors (
search/code/docs/scrape/cache.NewFromConfig) used by both the CLI and MCP server, ending backend-switch drift. MIT LICENSE file.
Changed
ketch docs --libraryon a non-context7 backend andketch code --regexon GitHub are clear validation errors instead of silent re-routes; the unimplementedlocaldocs backend is rejected up front and no longer advertised.
Fixed
- Context7 404s classify as not-found (exit 3) instead of retryable-upstream;
docs --resolverespects--limit;ketch cache --jsonemits stable JSON; unknown-backend errors list the valid options; a data race in the scraper's browser-binary resolution.
v0.9.5 — 2026-06-29
Fixed
- Tables render as GFM pipe tables across readability, raw, and selector extraction paths (#14).
- Brave searches cap the API
countat Brave's per-request maximum of 20, preventing HTTP 422 when--limitis higher (#17). - Client-rendered SPA pages (e.g. Next.js App Router) are no longer misdetected as static; adds a
spa_markersconfig key to extend detection (#15).
v0.9.4 — 2026-06-22
Added
exaweb search backend via Exa's hosted MCP endpoint, with optionalexa_api_keyconfig for authenticated usage.ketch scrape --force-browser— always render via the configured browser, skipping JS-shell auto-detection (#12); composes with--rawand--select. Documents the previously-undocumented--rawflag (#11).
v0.9.3 — 2026-05-29
Added
grepappcode search backend (Grep MCP,mcp.grep.app) — keyless, literal/regex search across 1M+ public GitHub repos. Now the default forketch code(wassourcegraph).ketch code --regexinterprets the query as a regular expression. Supported ongrepappandsourcegraph;githubrejects it because REST code search is literal-only.
Changed
code.Searcherinterface refactored from positional params to aQuerystruct so backend options can grow without signature churn.
Fixed
- Documentation drift across README, CLAUDE.md, and the site reference: corrected the
ketch codedefault backend, scoped-b/--backendtosearch/code/docs, documented previously-missing flags and theversioncommand, and synced theketch configdiscovery JSON example with real output.
v0.9.2 — 2026-05-24
Added
- Differentiated exit codes so scripts and agents can distinguish failure classes:
2validation/bad input,3not found,4upstream/network,5precondition (missing API key/token),6interrupted.
Changed
ketch crawlno longer swallows Ctrl+C as exit 0. SIGINT during a foreground crawl exits6while still printing the summary collected before shutdown.-b/--backendis no longer a persistent root flag — it lives onsearch(matching the existingcodeanddocslocal flags).ketch -b ddg search "q"andketch search -b ddg "q"both still work.
v0.9.1 — 2026-05-22
Added
url_rewritesconfig: an ordered list of{match, replace}regex rules applied transparently before any fetch inscrape,search --scrape, andcrawl. Redirect URLs without touching the agent surface (e.g.www.reddit.com→old.reddit.com). The original URL is preserved in output asurl:; the fetched URL appears asfetched_url:when different.
Changed
crawl.Crawl()now takes a*scrape.Scraperfrom the caller (Options.BrowserBinremoved). Affects only direct importers of thecrawlpackage — the CLI is unchanged.
Fixed
- Broken example URLs in the README (#8, thanks @abhmul).
v0.9.0 — 2026-05-12
Changed
- Breaking. Reusable packages moved from
pkg/<pkg>to the module root. Import paths change fromgithub.com/1broseidon/ketch/pkg/<pkg>togithub.com/1broseidon/ketch/<pkg>. - VitePress documentation site moved from
docs/tosite/, freeingdocs/for the docs-search Go package. Site URL is unaffected.
v0.8.1 — 2026-05-12
Fixed
- Page cache no longer returns unrendered JS-shell content after a browser is configured. Entries record their fetch source (
http/http_shell/browser); JS-shell hits are bypassed once a browser is available, and pre-existing entries migrate in place. Fixes #7.
v0.8.0 — 2026-05-02
Changed
- Reusable packages moved from
internal/topkg/(cache,code,config,crawl,docs,extract,httpx,scrape,search,updatecheck). Pure rename — exposes them for import by external Go programs.
v0.7.1 — 2026-04-21
Fixed
ketch docs --resolve <name>returned HTTP 400 after an upstream Context7 API change. Query param renamed (?q=→?query=), results moved into a{"results": [...]}envelope, and field names updated.ketch docs <query>and--librarywere unaffected.
v0.7.0 — 2026-04-21
Added
ketch versioncommand and--versionflag — reports build version, commit, and date.- Passive update reminder when a newer release exists (cached 24h, throttled). Honors
KETCH_NO_UPDATE_NOTIFIER=1,CI,--json, and non-TTY stderr. - Ctrl+C (SIGINT) and SIGTERM cancel the root context, so foreground
ketch crawldrains gracefully.
Changed
- HTTP stack tuned for crawling: a shared
*http.Transportwith a 30s timeout,MaxIdleConnsPerHost=16, HTTP/2, and a keep-alive dialer, reused by every backend. context.Contextplumbed through the scraper, browser, crawler, and sitemap/llms.txt fetches — cancellation reaches into Rod andhttp.Client.Do.- All HTTP response bodies capped at 20 MiB via
io.LimitReader.
v0.6.0 — 2026-04-11
Added
ketch scrapesmart input detection: multiple args, JSON array, file (one URL per line), or stdin pipe — auto-detected, no extra flags.--concurrency Nonketch scrape(default 5) — semaphore-based worker pool.--selectand--no-llms-txtnow propagate to multi-URL scraping.
Changed
search.Searcher.Searchanddocs.Searcher.Searchnow takecontext.Contextas the first param, consistent withcode.Searcher.
v0.5.0 — 2026-04-11
Added
ketch scrape --select <css>— CSS selector extraction, bypasses readability (with browser fallback for JS-rendered pages).ketch scrape --max-chars N— truncate markdown output to N Unicode code points.ketch scrape --trim— strip markdown formatting while preserving content text (typically 30–40% token reduction).ketch search/code/docs --minimal— one result per line, tab-separated, pipe-friendly.- llms.txt auto-detection: bare domain URLs check
/llms.txtand return it directly when found. Disable with--no-llms-txt.
v0.4.0 — 2026-04-11
Added
ketch code -b github— GitHub Code Search backend. Token resolution: explicit config →$GITHUB_TOKEN→$GH_TOKEN→gh auth token.- GitHub backend populates star counts via a single batched GraphQL call.
github_token_sourcefield in theketch configdiscovery payload (the token itself is never printed).
Changed
code.Searcher.Searchtakescontext.Contextas its first arg; backends usehttp.NewRequestWithContextfor cancellation.
v0.3.0 — 2026-04-10
Added
ketch codecommand — code search via the Sourcegraph streaming SSE API. Zero config.ketch docscommand — library documentation search via Context7. Requires an API key.- Config keys:
code_backend,docs_backend,context7_api_key,sourcegraph_url.
v0.2.0
Browser rendering, crawl, and cache overhaul.
- Browser rendering: JS-rendered pages (React, Angular, Salesforce Lightning) automatically detected and re-fetched via headless Chrome using Rod.
ketch config set browser chrome— configure browserketch browser install— download Chromiumketch browser status— check browser availability- Transparent fallback — agents see the same output format
- Crawl command: BFS and sitemap-based site crawling.
ketch crawl <url>— BFS crawl with configurable depth and concurrencyketch crawl <url> --sitemap— sitemap-based crawlketch crawl <url> --background— detached process with status trackingketch crawl status/ketch crawl stop— monitor and control background crawls
- Cache backend: migrated from filesystem to an embedded bbolt database.
- Single
cache.dbfile;Storeinterface for future backends - Default TTL changed to 72h; shared cache between scrape and crawl
- Single
v0.1.0
Initial release.
- Search via Brave, DuckDuckGo, or SearXNG
- Scrape URLs to clean markdown (readability + html-to-markdown)
- Concurrent batch scraping
- YAML frontmatter + markdown output format
- JSON config at
~/.config/ketch/config.json - TTL-based page cache with platform-correct paths
ketch configdiscovery payload for agent introspection--jsonflag on all commands- GoReleaser + Homebrew tap publishing