technicalpickles / technicalpickles/cq
Explore semantic/similarity search via DuckDB vss extension
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 11
- Forks
- 1
- Avg merge
- 4h 43m
- Merged PRs (30d)
- 22
Description
Right now cq search is keyword-only: `--grep` does substring/ILIKE matching, and `cq sql` is raw SQL over the DuckDB views. That covers "I remember roughly what I typed" but not "find sessions where I was doing something like X" when the wording doesn't match.
DuckDB has a first-party answer for this: the vss extension. It adds FIXED_SIZE_ARRAY(FLOAT, N) columns, HNSW indexing, and distance functions (array_distance, array_cosine_similarity) for ANN queries. Since cq is already DuckDB under the hood, this is schema and pipeline work, not a new storage engine.
Filing this to explore, not as a committed plan. There's real work and some open questions before this is worth building.
What it would take
- Embeddings, not just storage. vss handles the vector index, but something still has to turn message/tool-result text into vectors in the first place. Nothing in cq's sync pipeline does that today. Needs a model choice (local, e.g. something on Ollama, vs. an API call) and a call on cost/latency per row.
- Fits the incremental sync model. cq's whole design is incremental caching of JSONL into DuckDB. Embedding would need to slot into that the same way: only new/changed rows get embedded, not a full rebuild every sync.
- HNSW persistence is still a little sketchy. Durable HNSW indexes to disk went through an experimental flag (
SET hnsw_enable_experimental_persistence = true) for a while. Worth checking current DuckDB's status on that before leaning on it, since cq's cache DB is expected to survive across runs. If it's not solid, that's an index rebuild on every sync, which changes the sync-time budget. - What actually gets embedded. Full message text? Chunked? Do tool results get embedded too, or just messages? Answering this affects both index size and what "similar" ends up meaning.
- Query surface. New subcommand, or a
--semanticflag on an existing one? However it lands, it needs to compose with the existing scope flags (--project,--session,--since) the same way keyword search does. - Model churn. If the embedding model changes later, old vectors are stale. Need a plan for detecting that and re-embedding, even if it's just "bump a schema version and rebuild."
Why explore this now
qmd already does semantic search well, but only over markdown docs, not session transcripts. cq is the tool that actually has the transcripts. If semantic search on sessions is worth having, this is the natural place for it.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the existing cq search, --grep, cq sql, and incremental sync pipeline, then verify DuckDB vss persistence and embedding options. Decide what text is embedded, how model version changes are handled, and how semantic queries compose with --project, --session, and --since; done means a documented implementation direction with its storage, cost, and rebuild implications.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust, sql
- Domain
- backend, databases, search
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100