diff --git a/docs/superpowers/plans/2026-10-08-qmd-local-search.md b/docs/superpowers/plans/2026-10-08-qmd-local-search.md new file mode 100644 index 0000000..9588e52 --- /dev/null +++ b/docs/superpowers/plans/2026-10-08-qmd-local-search.md @@ -0,0 +1,1985 @@ +# QMD Local Search Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Replace the Python Qwen retrieval stack with QMD (Qwen3 embedding, Qwen3 reranker, QMD query expansion) behind the existing Yes/No/Auto local-models question, with a strict `semantic-search` skill for Claude and Codex. + +**Architecture:** Node scripts in `shared/qmd/` drive QMD through its SDK: a token-protected loopback daemon keeps the three models loaded and exits after 30 idle minutes; a search wrapper talks to it and falls back to `qmd query --json`; a SessionStart hook warms the daemon and the repository collection. A Python installer library (`scripts/lib/qmd.py`, with `.sh`/`.ps1` wrappers, the same pattern as the removed `semantic-retrieval.py`) installs, benchmarks, migrates, and removes setup-owned QMD state. + +**Tech Stack:** Node.js 22+ (ESM, `node:test`), `@tobilu/qmd@2.8.3` SDK and its bundled `yaml` and `node-llama-cpp` packages, Python 3.12 stdlib (`unittest`), Bash and PowerShell 5.1/7. + +**Spec:** `docs/superpowers/specs/2026-10-08-qmd-local-search-design.md` + +## Global Constraints + +- Models (exact URIs): embed `hf:Qwen/Qwen3-Embedding-0.6B-GGUF/Qwen3-Embedding-0.6B-Q8_0.gguf`; rerank `hf:ggml-org/Qwen3-Reranker-0.6B-Q8_0-GGUF/qwen3-reranker-0.6b-q8_0.gguf`; generate `hf:tobil/qmd-query-expansion-1.7B-gguf/qmd-query-expansion-1.7B-q4_k_m.gguf`. +- QMD package: `@tobilu/qmd@2.8.3`; Node.js 22 or newer; `npm` required. +- No Python code loads or runs a model. Python is used only by the installer library, as elsewhere in `scripts/lib/`. +- Auto thresholds: median search latency at most 5 s (`QMD_BENCHMARK_MAX_QUERY_SECONDS`); embedding at least 20 chunks/s (`QMD_BENCHMARK_MIN_CHUNKS_PER_SECOND`); GPU first, then CPU; 10-minute timeout per device. +- Idle stop: `QMD_IDLE_MINUTES`, default 30. +- Platforms: Linux and Windows are both first-class (the CI runner is Ubuntu; Windows is verified locally in Task 11). Spawned processes use `windowsHide`, `npm`/`qmd` run with `shell: true` only on Windows, hooks have `.sh` and `.ps1` entry points. +- Multiple GPUs and CPUs: the setup never narrows the device set. `gpu` mode uses llama.cpp's automatic backend, which spreads layers over every GPU of that backend; `cpu` mode uses every logical core (node-llama-cpp default). The setup never sets `CUDA_VISIBLE_DEVICES`, `GGML_VK_VISIBLE_DEVICES`, or a thread limit. Mixed-vendor systems use the one backend llama.cpp picks (CUDA before Vulkan); the benchmark reports the GPU names it used. +- Repository collection: `repo-` + first 12 hex chars of SHA-256 of the resolved absolute repository path; mask `**/*.{md,py,cs,ts,tsx,js,jsx,mjs,go,rs,java,ps1,sh,json,yml,yaml,xml,sql}`; chunk strategy `auto`; `includeByDefault: false`. +- State: `~/.my-ai-configuration/qmd.json` (installer state) and `~/.my-ai-configuration/qmd/` (installed scripts, `daemon.json`, `collections.json`, `warm.log`). Selection key stays `semantic_retrieval`; parameters stay `-SemanticRetrieval` / `--semantic-retrieval`. +- The setup removes only what it created: QMD package, model files, repo collections, the `models:` block it wrote. Foreign installs and collections survive. +- Every hook has `.sh` and `.ps1` entry points; PowerShell code stays 5.1-compatible. The `.mjs` scripts are invoked as `node